datadog_dashboards
Advanced tools
Comparing version 2.2.0 to 2.3.0
@@ -74,5 +74,7 @@ 'use strict'; | ||
}, | ||
s3: { | ||
title: 's3', | ||
name: 's3-name' | ||
s3_buckets: { | ||
uploads: { | ||
title: 's3', | ||
name: 's3-name' | ||
} | ||
}, | ||
@@ -79,0 +81,0 @@ caches: { |
427
index.js
#!/usr/bin/env node | ||
// Command-line tool to generate datadog dashboards from a config file | ||
require("dotenv").config(); | ||
Dashboards = require("./dashboards"); | ||
const { version } = require('./package.json'); | ||
ScreenboardService = require("./services/screenboard"); | ||
CloudwatchAlbGraphFactory = require("./factories/cloudwatch/alb"); | ||
CloudwatchAsgGraphFactory = require("./factories/cloudwatch/asg"); | ||
CloudwatchDynamoPanelFactory = require("./factories/cloudwatch/dynamodb"); | ||
CloudwatchElasticacheGraphFactory = require("./factories/cloudwatch/elasticache"); | ||
CloudwatchKinesisGraphFactory = require("./factories/cloudwatch/kinesis"); | ||
CloudwatchLambdaGraphFactory = require("./factories/cloudwatch/lambda"); | ||
CloudwatchRdsGraphFactory = require("./factories/cloudwatch/rds"); | ||
CloudwatchSqsGraphFactory = require("./factories/cloudwatch/sqs"); | ||
CloudwatchS3GraphFactory = require("./factories/cloudwatch/s3"); | ||
InstStatsdRequestsGraphFactory = require("./factories/statsd/inst-statsd-requests"); | ||
DelayedJobsGraphFactory = require("./factories/statsd/delayed-jobs"); | ||
CustomGraphFactory = require("./factories/custom"); | ||
const chalk = require("chalk"); | ||
@@ -26,3 +15,2 @@ const CLI = require("clui"); | ||
const prompt = require("prompt-sync")(); | ||
const Spinner = CLI.Spinner; | ||
const path = require("path"); | ||
@@ -75,411 +63,8 @@ const ROOT_PATH = process.cwd(); | ||
function getDashboardJsonString(dashboardConfig, prettyPrint = false) { | ||
const generated = generateEnvironmentDashboard(dashboardConfig); | ||
return JSON.stringify(generated, null, prettyPrint ? 2 : null); | ||
} | ||
const dashboards = new Dashboards(dashboardsConfig.dashboardsByEnvironment) | ||
/** | ||
* Creates the dashboards based on the config. | ||
* Determines whether to do a create or an updated based on the title of the dashboard. | ||
* @param {*} dashboardsConfig | ||
*/ | ||
function createDashboards(dashboardsConfig) { | ||
const spinnerStatus = new Spinner( | ||
"Retrieving existing dashboards, please wait..." | ||
); | ||
spinnerStatus.start(); | ||
const screenboardSvc = new ScreenboardService( | ||
DATADOG_API_API_KEY, | ||
DATADOG_API_APP_KEY | ||
); | ||
screenboardSvc.getAllScreenboards().then(res => { | ||
spinnerStatus.stop(); | ||
return Promise.all( | ||
dashboardsConfig.dashboardsByEnvironment.map(dashboardConfig => { | ||
const existingBoardId = screenboardSvc.getScreenboardIdByTitle( | ||
dashboardConfig.title | ||
); | ||
const jsonString = getDashboardJsonString(dashboardConfig); | ||
if (existingBoardId) { | ||
console.log(`Updating ${dashboardConfig.title}`); | ||
return screenboardSvc.updateScreenboard( | ||
existingBoardId, | ||
dashboardConfig.title, | ||
jsonString | ||
); | ||
} else { | ||
console.log(`Creating ${dashboardConfig.title}`); | ||
return screenboardSvc.createScreenboard( | ||
dashboardConfig.title, | ||
jsonString | ||
); | ||
} | ||
}) | ||
) | ||
.then(() => { | ||
console.log(); | ||
console.log(chalk.green.bold("Done!")); | ||
}) | ||
.catch(err => { | ||
console.log(chalk.red.bold("Failed!")); | ||
console.log(err); | ||
}); | ||
}); | ||
} | ||
/** | ||
* Previews the dashboard JSON and outputs it to stdout | ||
* @param {*} dashboardsConfig | ||
*/ | ||
function previewDashboards(dashboardsConfig) { | ||
dashboardsConfig.dashboardsByEnvironment.map(dashboardConfig => { | ||
console.log(chalk.green.bold(`Dashboard - ${dashboardConfig.title}`)); | ||
const jsonString = getDashboardJsonString(dashboardConfig, true); | ||
console.log(jsonString) | ||
}) | ||
} | ||
if (program.preview) { | ||
previewDashboards(dashboardsConfig); | ||
dashboards.preview() | ||
} else { | ||
createDashboards(dashboardsConfig); | ||
dashboards.create(DATADOG_API_API_KEY, DATADOG_API_APP_KEY) | ||
} | ||
function titleWidget(title, state) { | ||
var widget = { | ||
type: 'free_text', | ||
font_size: '24', | ||
title: true, | ||
text: title, | ||
height: 3, | ||
width: 117, | ||
x: 0, | ||
y: state.position | ||
} | ||
state.position += 4; | ||
return widget; | ||
} | ||
function generateCustomWidgets(customWidgets, widgets = [], state) { | ||
if (!customWidgets) return; | ||
const factory = new CustomGraphFactory(); | ||
Object.keys(customWidgets).forEach(function(key) { | ||
widgets.push(factory.render(customWidgets[key], state)); | ||
}) | ||
} | ||
/** | ||
* Generates widgets for all load balancers. | ||
* | ||
* @param {object} load_balancers | ||
* @param {array} widgets | ||
* @param {object} state | ||
*/ | ||
function generateAlbGraphs(load_balancers, widgets = [], state) { | ||
if (!load_balancers) return; | ||
const factoryAlb = new CloudwatchAlbGraphFactory(); | ||
for (var lb of load_balancers) { | ||
const lbName = lb.targetgroup_name ? `Load Balancer: Target Group ${lb.targetgroup_name}` : 'Load Balancer' | ||
widgets.push(titleWidget(lbName, state)); | ||
widgets.push(...factoryAlb.alb_totalRequests(lb, state)); | ||
widgets.push(factoryAlb.alb_hits(lb, state)); | ||
widgets.push(factoryAlb.alb_latency(lb, state)); | ||
widgets.push(factoryAlb.alb_health(lb, state)); | ||
state.position += 30; | ||
} | ||
} | ||
/** | ||
* Generates widgets for instances in all auto scaling groups. | ||
* | ||
* @param {object} vars | ||
* @param {array} widgets | ||
* @param {object} state | ||
*/ | ||
function generateAsgGraphs(vars, widgets = [], state) { | ||
if (!vars.asgs) return; | ||
const factoryAsg = new CloudwatchAsgGraphFactory(); | ||
widgets.push(titleWidget('Auto Scaling Groups', state)); | ||
widgets.push(factoryAsg.asg_cpu(vars.asgs, state)); | ||
widgets.push(factoryAsg.asg_instancesInService(vars.asgs, state)); | ||
widgets.push(...factoryAsg.asg_network(vars.asgs, state)); | ||
widgets.push(...factoryAsg.asg_hosts(vars, state)); | ||
state.position += 38; | ||
} | ||
function generateInstStatsdRequestsGraphs(requests, project, environment, region, widgets = [], state) { | ||
if (!requests) return; | ||
const factoryRequests = new InstStatsdRequestsGraphFactory(requests, project, environment, region); | ||
widgets.push(titleWidget('Requests', state)); | ||
widgets.push(factoryRequests.totalTimeGraph(state)); | ||
widgets.push(factoryRequests.countGraph(state)); | ||
state.position += 30; | ||
widgets.push(...factoryRequests.toplists(state)); | ||
state.position += 16; | ||
} | ||
function generateDelayedJobsGraphs(delayed_jobs, project, environment, region, widgets = [], state) { | ||
if (!delayed_jobs) return; | ||
const factoryJobs = new DelayedJobsGraphFactory(delayed_jobs, project, environment, region); | ||
widgets.push(titleWidget('Jobs', state)); | ||
widgets.push(...factoryJobs.executedFailedCounts(state, 0)); | ||
widgets.push(...factoryJobs.executedFailedTimeseries(state, 21)); | ||
widgets.push(...factoryJobs.runtimeAndOldestJob(state, 66)); | ||
state.position += 48; | ||
} | ||
function generateLambdasGraphs(lambdas, region, widgets = [], state) { | ||
if (!lambdas) return; | ||
const factory = new CloudwatchLambdaGraphFactory(region); | ||
Object.keys(lambdas).forEach(key => { | ||
widgets.push(titleWidget(`Lambda: ${lambdas[key].title}`, state)); | ||
widgets.push(factory.render('invocations', lambdas[key], state)); | ||
widgets.push(factory.render('duration', lambdas[key], state)); | ||
state.position += 22; | ||
}); | ||
} | ||
function generateKinesisStreamsGraphs(streams, widgets = [], state) { | ||
if (!streams) return; | ||
const factory = new CloudwatchKinesisGraphFactory(); | ||
Object.keys(streams).forEach(key => { | ||
widgets.push(titleWidget(`Kinesis: ${streams[key].title}`, state)); | ||
widgets.push(factory.render('iteratorAge', streams[key], state)); | ||
widgets.push(factory.render('records', streams[key], state)); | ||
widgets.push(factory.render('throughput', streams[key], state)); | ||
state.position += 21; | ||
}); | ||
return widgets; | ||
} | ||
function generateDynamoTablesGraphs(tables, region, widgets = [], state) { | ||
if (!tables || !region) return; | ||
const factory = new CloudwatchDynamoPanelFactory(region); | ||
Object.keys(tables).forEach(function(key) { | ||
widgets.push(titleWidget(`DynamoDB: ${tables[key].title}`, state)); | ||
widgets.push(...factory.units(tables[key], state)); | ||
widgets.push(factory.throttled(tables[key], state)); | ||
state.position += 16; | ||
}); | ||
} | ||
function generateCachesGraphs(caches, widgets = [], state) { | ||
if (!caches) return; | ||
const factory = new CloudwatchElasticacheGraphFactory(); | ||
Object.keys(caches).forEach(function(key) { | ||
widgets.push(titleWidget(`ElastiCache: ${caches[key].title}`, state)); | ||
widgets.push(factory.render('hits', caches[key], state)); | ||
widgets.push(factory.render('items', caches[key], state)); | ||
widgets.push(factory.render('memory', caches[key], state)); | ||
state.position += 16; | ||
widgets.push(factory.render('bytesUsed', caches[key], state)); | ||
widgets.push(factory.render('evictions', caches[key], state)); | ||
if (caches[key].type === 'redis') { | ||
widgets.push(factory.render('redis_commands', caches[key], state)); | ||
} | ||
state.position += 16; | ||
}); | ||
} | ||
function generateSqsGraphs(queues, region, widgets = [], state) { | ||
if (!queues || !region) return; | ||
const factory = new CloudwatchSqsGraphFactory(region); | ||
Object.keys(queues).forEach(function(key) { | ||
widgets.push(titleWidget(`SQS: ${queues[key].title}`, state)); | ||
widgets.push(factory.render('visibilityCount', queues[key], state)); | ||
widgets.push(factory.render('deletedCount', queues[key], state)); | ||
widgets.push(factory.render('visibility', queues[key], state)); | ||
widgets.push(factory.render('deleted', queues[key], state)); | ||
state.position += 20; | ||
}); | ||
} | ||
function generateRdsGraphs(rdsIds, widgets = [], state) { | ||
if (!rdsIds) return; | ||
const rds = new CloudwatchRdsGraphFactory(); | ||
rdsIds.forEach(function(rdsInstance) { | ||
let rdsId; | ||
let rdsName = null; | ||
if (typeof rdsInstance === 'string' || rdsInstance instanceof String) { | ||
rdsId = rdsInstance; | ||
} else { | ||
rdsId = rdsInstance.id; | ||
rdsName = rdsInstance.name; | ||
} | ||
widgets.push(titleWidget(`RDS: ${rdsName ? `${rdsName} (${rdsId})` : rdsId}`, state)); | ||
widgets.push(rds.render('rds_cpu', rdsId, state)); | ||
widgets.push(rds.render('rds_memory', rdsId, state)); | ||
widgets.push(rds.render('rds_connections', rdsId, state)); | ||
state.position += 16; | ||
widgets.push(rds.render('rds_throughput', rdsId, state)); | ||
widgets.push(rds.render('rds_storage', rdsId, state)); | ||
widgets.push(rds.render('rds_iops', rdsId, state)); | ||
widgets.push(rds.render('rds_burstBalance', rdsId, state)); | ||
state.position += 16; | ||
}) | ||
} | ||
function generateS3BucketGraphs(buckets, widgets = [], state) { | ||
if (!buckets) return; | ||
const factory = new CloudwatchS3GraphFactory(); | ||
Object.keys(buckets).forEach(function(key) { | ||
widgets.push(titleWidget(`S3: ${buckets[key].title}`, state)); | ||
widgets.push(factory.render('totalCount', buckets[key], state)); | ||
widgets.push(factory.render('totalSize', buckets[key], state)); | ||
widgets.push(factory.render('count', buckets[key], state)); | ||
widgets.push(factory.render('size', buckets[key], state)); | ||
state.position += 20; | ||
}); | ||
} | ||
function generateEnvironmentDashboard(vars) { | ||
var dashboard = { | ||
board_title: vars.title, | ||
description: vars.description || "A great dashboard!", | ||
template_variables: vars.template_variables, | ||
widgets: [] | ||
}; | ||
var state = { | ||
position: 0 | ||
}; | ||
// Custom widgets | ||
if (vars.custom) { | ||
if (!vars.custom_height) { | ||
console.log(chalk.red('You must define the height you want reserved for custom graphs in "custom_height" setting.')); | ||
process.exit(1); | ||
} | ||
dashboard.widgets.push(titleWidget(vars.custom_title || 'Custom Graphs', state)); | ||
generateCustomWidgets(vars.custom, dashboard.widgets, state); | ||
state.position += vars.custom_height; | ||
} | ||
// ALB | ||
if (vars.alb) { | ||
generateAlbGraphs(vars.alb, dashboard.widgets, state); | ||
} | ||
// ASGS | ||
if (vars.asgs) { | ||
generateAsgGraphs(vars, dashboard.widgets, state); | ||
} | ||
// Requests | ||
if (vars.inst_statsd_requests) { | ||
// Use the specific project for statsd or use the default one | ||
var projectStatsd = vars.inst_statsd_requests.project || vars.project | ||
generateInstStatsdRequestsGraphs(vars.inst_statsd_requests, projectStatsd, vars.environment, | ||
vars.region, dashboard.widgets, state); | ||
} | ||
// Jobs | ||
if (vars.delayed_jobs) { | ||
// Use the specific project for statsd or use the default one | ||
var projectStatsd = vars.delayed_jobs.project || vars.project | ||
generateDelayedJobsGraphs(vars.delayed_jobs, projectStatsd, vars.environment, | ||
vars.region, dashboard.widgets, state); | ||
} | ||
// RDS | ||
// Support multiple RDS instances in an backwards compatible fashion | ||
if (vars.rds_id) { | ||
generateRdsGraphs([vars.rds_id], dashboard.widgets, state); | ||
} | ||
if (vars.rds_ids) { | ||
generateRdsGraphs(vars.rds_ids, dashboard.widgets, state); | ||
} | ||
// Caches | ||
if (vars.caches) { | ||
generateCachesGraphs(vars.caches, dashboard.widgets, state); | ||
} | ||
// Lambdas | ||
if (vars.lambdas) { | ||
generateLambdasGraphs(vars.lambdas, vars.region, dashboard.widgets, state); | ||
} | ||
// Kinesis | ||
if (vars.kinesis_streams) { | ||
generateKinesisStreamsGraphs(vars.kinesis_streams, dashboard.widgets, state); | ||
} | ||
// Dynamo tables | ||
if (vars.dynamo_tables) { | ||
generateDynamoTablesGraphs(vars.dynamo_tables, vars.region, dashboard.widgets, state); | ||
} | ||
// SQS Queues | ||
if (vars.sqs_queues) { | ||
generateSqsGraphs(vars.sqs_queues, vars.region, dashboard.widgets, state); | ||
} | ||
// S3 | ||
if (vars.s3_buckets) { | ||
generateS3BucketGraphs(vars.s3_buckets, dashboard.widgets, state); | ||
} | ||
return dashboard; | ||
} |
{ | ||
"name": "datadog_dashboards", | ||
"version": "2.2.0", | ||
"version": "2.3.0", | ||
"description": "A quick way to generate helpful, pre-canned datadog dashboards for Cloudwatch.", | ||
"main": "index.js", | ||
"dependencies": { | ||
"aws-sdk": "^2.543.0", | ||
"btoa": "^1.1.2", | ||
@@ -14,5 +15,7 @@ "callsites": "^3.0.0", | ||
"figlet": "^1.2.1", | ||
"handlebars": "^4.0.12", | ||
"handlebars": "^4.4.3", | ||
"merge-deep": "^3.0.2", | ||
"node-fetch": "^2.3.0", | ||
"prompt-sync": "^4.1.5" | ||
"prompt-sync": "^4.1.5", | ||
"title-case": "^2.1.1" | ||
}, | ||
@@ -19,0 +22,0 @@ "bin": { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
100742
70
1935
13
8
+ Addedaws-sdk@^2.543.0
+ Addedmerge-deep@^3.0.2
+ Addedtitle-case@^2.1.1
+ Addedarr-union@3.1.0(transitive)
+ Addedavailable-typed-arrays@1.0.7(transitive)
+ Addedaws-sdk@2.1692.0(transitive)
+ Addedbase64-js@1.5.1(transitive)
+ Addedbuffer@4.9.2(transitive)
+ Addedcall-bind@1.0.7(transitive)
+ Addedclone-deep@0.2.4(transitive)
+ Addeddefine-data-property@1.1.4(transitive)
+ Addedes-define-property@1.0.0(transitive)
+ Addedes-errors@1.3.0(transitive)
+ Addedevents@1.1.1(transitive)
+ Addedfor-each@0.3.3(transitive)
+ Addedfor-in@0.1.81.0.2(transitive)
+ Addedfor-own@0.1.5(transitive)
+ Addedfunction-bind@1.1.2(transitive)
+ Addedget-intrinsic@1.2.4(transitive)
+ Addedgopd@1.0.1(transitive)
+ Addedhas-property-descriptors@1.0.2(transitive)
+ Addedhas-proto@1.0.3(transitive)
+ Addedhas-symbols@1.0.3(transitive)
+ Addedhas-tostringtag@1.0.2(transitive)
+ Addedhasown@2.0.2(transitive)
+ Addedieee754@1.1.13(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedis-arguments@1.1.1(transitive)
+ Addedis-buffer@1.1.6(transitive)
+ Addedis-callable@1.2.7(transitive)
+ Addedis-extendable@0.1.1(transitive)
+ Addedis-generator-function@1.0.10(transitive)
+ Addedis-plain-object@2.0.4(transitive)
+ Addedis-typed-array@1.1.13(transitive)
+ Addedisarray@1.0.0(transitive)
+ Addedisobject@3.0.1(transitive)
+ Addedjmespath@0.16.0(transitive)
+ Addedkind-of@2.0.13.2.2(transitive)
+ Addedlazy-cache@0.2.71.0.4(transitive)
+ Addedlower-case@1.1.4(transitive)
+ Addedmerge-deep@3.0.3(transitive)
+ Addedmixin-object@2.0.1(transitive)
+ Addedno-case@2.3.2(transitive)
+ Addedpossible-typed-array-names@1.0.0(transitive)
+ Addedpunycode@1.3.2(transitive)
+ Addedquerystring@0.2.0(transitive)
+ Addedsax@1.2.1(transitive)
+ Addedset-function-length@1.2.2(transitive)
+ Addedshallow-clone@0.1.2(transitive)
+ Addedtitle-case@2.1.1(transitive)
+ Addedupper-case@1.1.3(transitive)
+ Addedurl@0.10.3(transitive)
+ Addedutil@0.12.5(transitive)
+ Addeduuid@8.0.0(transitive)
+ Addedwhich-typed-array@1.1.15(transitive)
+ Addedxml2js@0.6.2(transitive)
+ Addedxmlbuilder@11.0.1(transitive)
Updatedhandlebars@^4.4.3