-
-
Save anatolijd/73b1360c9780c0d161b1 to your computer and use it in GitHub Desktop.
/* global _ */ | |
/* | |
* Complex scripted dashboard | |
* This script generates a dashboard object that Grafana can load. It also takes a number of user | |
* supplied URL parameters (int ARGS variable) | |
* | |
* Global accessable variables | |
* window, document, $, jQuery, ARGS, moment | |
* | |
* Return a dashboard object, or a function | |
* | |
* For async scripts, return a function, this function must take a single callback function, | |
* call this function with the dasboard object | |
* | |
* Author: Anatoliy Dobrosynets, Recorded Future, Inc. | |
*/ | |
// accessable variables in this scope | |
var window, document, ARGS, $, jQuery, moment, kbn; | |
// use defaults for URL arguments | |
var arg_env = 'prod'; | |
var arg_i = 'default'; | |
var arg_span = 4; | |
var arg_from = '2h'; | |
if(!_.isUndefined(ARGS.span)) { | |
arg_span = ARGS.span; | |
} | |
if(!_.isUndefined(ARGS.from)) { | |
arg_from = ARGS.from; | |
} | |
if(!_.isUndefined(ARGS.env)) { | |
arg_env = ARGS.env; | |
} | |
if(!_.isUndefined(ARGS.i)) { | |
arg_i = ARGS.i; // instance name | |
} | |
// return dashboard filter_list | |
// optionally include 'All' | |
function get_filter_object(name,query,show_all){ | |
show_all = (typeof show_all === "undefined") ? true : show_all; | |
var arr = find_filter_values(query); | |
var opts = []; | |
for (var i in arr) { | |
opts.push({"text":arr[i], "value":arr[i]}); | |
}; | |
if (show_all == true) { | |
opts.unshift({"text":"All", "value": '{'+arr.join()+'}'}); | |
}; | |
return { | |
type: "filter", | |
name: name, | |
query: query, | |
options: opts, | |
current: opts[0], | |
includeAll: show_all | |
} | |
}; | |
// execute graphite-api /metrics/find query | |
// return array of metric last names ( func('test.cpu-*') returns ['cpu-0','cpu-1',..] ) | |
function find_filter_values(query){ | |
var search_url = window.location.protocol + '//' + window.location.host + '/_graphite/metrics/find/?query=' + query; | |
var res = []; | |
var req = new XMLHttpRequest(); | |
req.open('GET', search_url, false); | |
req.send(null); | |
var obj = JSON.parse(req.responseText); | |
for(var key in obj) { | |
if (obj[key].hasOwnProperty("text")) { | |
res.push(obj[key]["text"]); | |
} | |
} | |
return res; | |
}; | |
// execute graphite-api /metrics/expand query | |
// return array of metric full names (func('*.cpu-*') returns ['test.cpu-0','test.cpu-1',..] ) | |
function expand_filter_values(query){ | |
var search_url = window.location.protocol + '//' + window.location.host + '/_graphite/metrics/expand/?query=' + query; | |
var req = new XMLHttpRequest(); | |
req.open('GET', search_url, false); | |
req.send(null); | |
var obj = JSON.parse(req.responseText); | |
if (obj.hasOwnProperty('results')) { | |
return obj['results']; | |
} else { | |
return []; | |
}; | |
}; | |
// used to calculate aliasByNode index in panel template | |
function len(prefix){ | |
return prefix.split('.').length - 2; | |
}; | |
/* | |
panel templates | |
*/ | |
// collectd | |
function panel_collectd_cpu(title,prefix){ | |
var idx = len(prefix); | |
return { | |
title: title, | |
type: 'graphite', | |
span: arg_span, | |
renderer: "flot", | |
y_formats: ["none"], | |
grid: {max: null, min: 0}, | |
lines: true, | |
fill: 1, | |
linewidth: 1, | |
stack: true, | |
legend: {show: true}, | |
percentage: true, | |
nullPointMode: "null", | |
tooltip: { | |
value_type: "individual", | |
query_as_alias: true | |
}, | |
targets: [ | |
{ "target": "alias(sumSeries(nonNegativeDerivative(" + prefix + "[[instance]].cpu-*.cpu-user,0)),'user')" }, | |
{ "target": "alias(sumSeries(nonNegativeDerivative(" + prefix + "[[instance]].cpu-*.cpu-system,0)),'system')" }, | |
{ "target": "alias(sumSeries(nonNegativeDerivative(" + prefix + "[[instance]].cpu-*.cpu-idle,0)),'idle')" }, | |
{ "target": "alias(sumSeries(nonNegativeDerivative(" + prefix + "[[instance]].cpu-*.cpu-wait,0)),'wait')" }, | |
{ "target": "alias(sumSeries(nonNegativeDerivative(" + prefix + "[[instance]].cpu-*.cpu-steal,0)),'steal')" }, | |
{ "target": "alias(sumSeries(nonNegativeDerivative(" + prefix + "[[instance]].cpu-*.cpu-nice,0)),'nice')" }, | |
{ "target": "alias(sumSeries(nonNegativeDerivative(" + prefix + "[[instance]].cpu-*.cpu-softirq,0)),'irq')" }, | |
{ "target": "alias(sumSeries(nonNegativeDerivative(" + prefix + "[[instance]].cpu-*.cpu-interrupt,0)),'intrpt')" }, | |
], | |
aliasColors: { | |
"user": "#508642", | |
"system": "#EAB839", | |
"wait": "#890F02", | |
"steal": "#E24D42", | |
"idle": "#6ED0E0" | |
} | |
} | |
}; | |
function panel_collectd_memory(title,prefix){ | |
var idx = len(prefix); | |
return { | |
title: title, | |
type: 'graphite', | |
span: arg_span, | |
y_formats: ["bytes"], | |
grid: {max: null, min: 0}, | |
lines: true, | |
fill: 1, | |
linewidth: 1, | |
stack: true, | |
nullPointMode: "null", | |
targets: [ | |
{ "target": "aliasByNode(movingMedian(" + prefix + "[[instance]].memory.memory-{used,free,cached,buffered},'15min')," +(idx+3)+ ")" }, | |
], | |
aliasColors: { | |
"memory-free": "#629E51", | |
"memory-used": "#1F78C1", | |
"memory-cached": "#EF843C", | |
"memory-buffered": "#CCA300" | |
} | |
} | |
}; | |
function panel_collectd_loadavg(title,prefix){ | |
var idx = len(prefix); | |
return { | |
title: title, | |
type: 'graphite', | |
span: arg_span, | |
y_formats: ["none"], | |
grid: {max: null, min: 0}, | |
lines: true, | |
fill: 0, | |
linewidth: 2, | |
nullPointMode: "null", | |
targets: [ | |
{ "target": "aliasByNode(movingMedian(" + prefix + "[[instance]].load.load.midterm,'10min')," +(idx+4)+ ")" }, | |
] | |
} | |
}; | |
function panel_collectd_swap_size(title,prefix){ | |
var idx = len(prefix); | |
return { | |
title: title, | |
type: 'graphite', | |
span: arg_span, | |
y_formats: ["bytes"], | |
grid: {max: null, min: 0, leftMin: 0}, | |
lines: true, | |
fill: 1, | |
linewidth: 1, | |
stack: true, | |
nullPointMode: "null", | |
targets: [ | |
{ "target": "aliasByNode(" + prefix + "[[instance]].swap.swap-{free,used,cached}," +(idx+3)+ ")" }, | |
], | |
aliasColors: { | |
"swap-used": "#1F78C1", | |
"swap-cached": "#EAB839", | |
"swap-free": "#508642" | |
} | |
} | |
}; | |
function panel_collectd_swap_io(title,prefix){ | |
var idx = len(prefix); | |
return { | |
title: title, | |
type: 'graphite', | |
span: arg_span, | |
y_formats: ["bytes"], | |
grid: {max: null, min: 0}, | |
lines: true, | |
fill: 1, | |
linewidth: 2, | |
nullPointMode: "null", | |
targets: [ | |
{ "target": "aliasByNode(movingMedian(nonNegativeDerivative(keepLastValue(" + prefix + "[[instance]].swap.swap_io-in,10),0),'5min')," +(idx+3)+ ")" }, | |
{ "target": "aliasByNode(movingMedian(scale(nonNegativeDerivative(keepLastValue(" + prefix + "[[instance]].swap.swap_io-out,10),0),-1),'5min')," +(idx+3)+ ")" }, | |
] | |
} | |
}; | |
function panel_collectd_network_octets(title,prefix,intrf){ | |
intrf = (typeof intrf === "undefined") ? 'interface-eth0' : intrf; | |
var idx = len(prefix); | |
return { | |
title: title + ', ' + intrf, | |
type: 'graphite', | |
span: arg_span, | |
y_formats: ["bytes"], | |
grid: {max: null, min: null}, | |
lines: true, | |
fill: 1, | |
linewidth: 2, | |
nullPointMode: "null", | |
targets: [ | |
{ "target": "aliasByNode(movingMedian(nonNegativeDerivative(keepLastValue(" + prefix + "[[instance]]." + intrf + ".if_octets.rx,10),0),'5min')," +(idx+4)+ ")" }, | |
{ "target": "aliasByNode(movingMedian(scale(nonNegativeDerivative(keepLastValue(" + prefix + "[[instance]]." + intrf + ".if_octets.tx,10),0),-1),'5min')," +(idx+4)+ ")" } | |
] | |
} | |
}; | |
function panel_collectd_network_packets(title,prefix,intrf){ | |
intrf = (typeof intrf === "undefined") ? 'interface-eth0' : intrf; | |
var idx = len(prefix); | |
return { | |
title: title + ', ' + intrf, | |
type: 'graphite', | |
span: arg_span, | |
y_formats: ["bytes"], | |
grid: {max: null, min: null}, | |
lines: true, | |
fill: 1, | |
linewidth: 2, | |
nullPointMode: "null", | |
targets: [ | |
{ "target": "aliasByNode(movingMedian(nonNegativeDerivative(keepLastValue(" + prefix + "[[instance]]." + intrf + ".if_packets.rx,10),0),'5min')," +(idx+4)+ ")" }, | |
{ "target": "aliasByNode(movingMedian(scale(nonNegativeDerivative(keepLastValue(" + prefix + "[[instance]]." + intrf + ".if_packets.tx,10),0),-1),'5min')," +(idx+4)+ ")" } | |
] | |
} | |
}; | |
function panel_collectd_df(title,prefix,vol){ | |
vol = (typeof vol === "undefined") ? 'df-root' : vol; | |
var idx = len(prefix); | |
return { | |
title: title + ', ' + vol, | |
type: 'graphite', | |
span: arg_span, | |
y_formats: ["bytes"], | |
grid: {max: null, min: 0, leftMin: 0}, | |
lines: true, | |
fill: 1, | |
linewidth: 2, | |
stack: true, | |
nullPointMode: "null", | |
targets: [ | |
{ "target": "aliasByNode(" + prefix + "[[instance]]." + vol + ".df_complex-{free,used,reserved}," +(idx+3)+ ")" }, | |
], | |
aliasColors: { | |
"df_complex-used": "#447EBC", | |
"df_complex-free": "#508642", | |
"df_complex-reserved": "#EAB839" | |
} | |
} | |
}; | |
function panel_collectd_disk(title,prefix,vol){ | |
vol = (typeof vol === "undefined") ? 'df-root' : vol; | |
var idx = len(prefix); | |
return { | |
title: title + ', ' + vol, | |
type: 'graphite', | |
span: arg_span, | |
y_formats: ["none"], | |
grid: {max: null, min: null}, | |
lines: true, | |
fill: 1, | |
linewidth: 2, | |
nullPointMode: "null", | |
targets: [ | |
{ "target": "aliasByNode(nonNegativeDerivative(" + prefix + "[[instance]]." + vol + ".disk_ops.write,10)," +(idx+2)+ "," +(idx+4)+ ")" }, | |
{ "target": "aliasByNode(scale(nonNegativeDerivative(" + prefix + "[[instance]]." + vol + ".disk_ops.read,10),-1)," +(idx+2)+ "," +(idx+4)+ ")" } | |
], | |
aliasColors: { | |
"df_complex-used": "#447EBC", | |
"df_complex-free": "#508642", | |
"df_complex-reserved": "#EAB839" | |
} | |
} | |
}; | |
// jmxtrans | |
function panel_jvm_heap(title,prefix){ | |
var idx = len(prefix); | |
return { | |
title: title, | |
type: 'graphite', | |
span: arg_span, | |
y_formats: ["bytes"], | |
grid: {max: null, min: 0}, | |
lines: true, | |
fill: 1, | |
linewidth: 2, | |
nullPointMode: "null", | |
targets: [ | |
{ "target": "aliasByNode(" + prefix + "memory.HeapMemoryUsage_{used,max}," +(idx+2)+ ")" }, | |
], | |
aliasColors: { | |
"HeapMemoryUsage_used": "#508642", | |
"HeapMemoryUsage_max": "#890F02" | |
} | |
} | |
}; | |
function panel_jvm_old_gen_size(title,prefix){ | |
var idx = len(prefix); | |
return { | |
title: title, | |
type: 'graphite', | |
span: arg_span, | |
y_formats: ["bytes"], | |
grid: {max: null, min: 0, leftMin: 0}, | |
lines: true, | |
fill: 1, | |
linewidth: 2, | |
stack: true, | |
nullPointMode: "null", | |
tooltip: { | |
value_type: "individual", | |
query_as_alias: true | |
}, | |
targets: [ | |
{ "target": "aliasByNode(movingMedian(" + prefix + "memorypool.*OldGen.Usage_used,'15min')," +(idx+2)+ "," +(idx+3)+ ")" }, | |
{ "target": "aliasByNode(movingMedian(" + prefix + "memorypool.*EdenSpace.Usage_used,'15min')," +(idx+2)+ "," +(idx+3)+ ")"}, | |
] | |
} | |
}; | |
function panel_jvm_perm_gen_size(title,prefix){ | |
var idx = len(prefix); | |
return { | |
title: title, | |
type: 'graphite', | |
span: arg_span, | |
y_formats: ["bytes"], | |
grid: {max: null, min: 0, leftMin: 0}, | |
lines: true, | |
fill: 1, | |
linewidth: 2, | |
nullPointMode: "null", | |
targets: [ | |
{ "target": "aliasByNode(movingMedian(" + prefix + "memorypool.*PermGen.Usage_{used,max},'15min')," +(idx+2)+ "," +(idx+3)+ ")"}, | |
], | |
aliasColors: { | |
"PermGen.Usage_max": "#890F02", | |
"PSPermGen.Usage_max": "#890F02" | |
} | |
} | |
}; | |
function panel_jvm_gc_time(title,prefix){ | |
var idx = len(prefix); | |
return { | |
title: title, | |
type: 'graphite', | |
span: arg_span, | |
y_formats: ["ms"], | |
grid: {max: null, min: 0, leftMin: 0}, | |
lines: true, | |
fill: 0, | |
linewidth: 1, | |
nullPointMode: "null", | |
targets: [ | |
{ "target": "aliasByNode(nonNegativeDerivative(" + prefix + "gc.*.CollectionTime,10)," +(idx+2)+ ")"}, | |
] | |
} | |
}; | |
function panel_jvm_gc_invoked(title,prefix){ | |
var idx = len(prefix); | |
return { | |
title: title, | |
type: 'graphite', | |
span: arg_span, | |
y_formats: ["none"], | |
grid: {max: null, min: 0, leftMin: 0}, | |
lines: false, | |
bars: true, | |
fill: 0, | |
linewidth: 1, | |
nullPointMode: "null", | |
targets: [ | |
{ "target": "aliasByNode(nonNegativeDerivative(" + prefix + "gc.*.CollectionCount,10)," +(idx+2)+ ")"}, | |
] | |
} | |
}; | |
function panel_jetty_threads(title,prefix){ | |
var idx = len(prefix); | |
return { | |
title: title, | |
type: 'graphite', | |
span: arg_span, | |
y_formats: ["none"], | |
grid: {max: null, min: 0, leftMin: 0}, | |
fill: 0, | |
line: true, | |
linewidth: 1, | |
nullPointMode: "null", | |
targets: [ | |
{ "target": "alias(" + prefix + "jetty_threads.threads,'total')" }, | |
{ "target": "alias(" + prefix + "jetty_threads.idleThreads,'idle')" }, | |
{ "target": "alias(" + prefix + "jetty_threads.minThreads,'min')" }, | |
{ "target": "alias(" + prefix + "jetty_threads.maxThreads,'max')" }, | |
{ "target": "alias(diffSeries(" + prefix + "jetty_threads.threads," + prefix + "jetty_threads.idleThreads),\"busy\")"} | |
] | |
} | |
}; | |
function panel_jetty_threads_ratio(title,prefix){ | |
var idx = len(prefix); | |
return { | |
title: title, | |
type: 'graphite', | |
span: arg_span, | |
y_formats: ["short","short"], | |
grid: {max: null, min: 0, leftMin: 0, rightMin:0}, | |
fill: 0, | |
line: true, | |
linewidth: 2, | |
nullPointMode: "null", | |
targets: [ | |
{ "target": "alias(diffSeries(" + prefix + "jetty_threads.threads," + prefix + "jetty_threads.idleThreads),\"busy\")" }, | |
{ "target": "alias(scale(divideSeries(diffSeries(" + prefix + "jetty_threads.threads," + prefix + "jetty_threads.idleThreads)," + prefix + "jetty_threads.maxThreads),100),\"ratio busy/max %\")" } | |
], | |
aliasYAxis: { | |
"busy": 2 | |
} | |
} | |
}; | |
/* | |
row templates | |
*/ | |
function row_delimiter(title){ | |
return { | |
title: "_____ " + title, | |
height: "20px", | |
collapse: false, | |
editable: false, | |
collapsable: false, | |
panels: [{ | |
title: title, | |
editable: false, | |
span: 12, | |
type: "text", | |
mode: "text" | |
}] | |
} | |
}; | |
function row_jvm(title,prefix){ | |
return { | |
title: title, | |
height: "250px", | |
collapse: true, | |
panels: [ | |
panel_jvm_heap('JVM Heap',prefix), | |
panel_jvm_old_gen_size('Old/New Gen usage',prefix), | |
panel_jvm_perm_gen_size('Perm Gen usage',prefix), | |
panel_jvm_gc_time('GC time, sec',prefix), | |
panel_jvm_gc_invoked('GC invocations',prefix), | |
] | |
} | |
}; | |
function row_jetty(title,prefix){ | |
return { | |
title: title, | |
height: "250px", | |
collapse: true, | |
panels: [ | |
panel_jetty_threads('jetty threads',prefix), | |
panel_jetty_threads_ratio('busy/max threads ratio, %',prefix), | |
] | |
} | |
}; | |
function row_cpu_memory(title,prefix){ | |
return { | |
title: title, | |
height: '250px', | |
collapse: false, | |
panels: [ | |
panel_collectd_cpu('CPU, %',prefix), | |
panel_collectd_memory('Memory',prefix), | |
panel_collectd_loadavg('Load avg, 10min',prefix) | |
] | |
} | |
}; | |
function row_swap(title,prefix){ | |
return { | |
title: title, | |
height: '250px', | |
collapse: true, | |
panels: [ | |
panel_collectd_swap_size('Swap size',prefix), | |
panel_collectd_swap_io('Swap IO',prefix), | |
] | |
} | |
}; | |
function row_network(title,prefix,filter){ | |
var interfaces = find_filter_values(filter + '.interface-*'); | |
var panels_network = []; | |
for (var i in interfaces) { | |
panels_network.push( | |
panel_collectd_network_octets('network octets',prefix,interfaces[i]), | |
panel_collectd_network_packets('network packets',prefix,interfaces[i]) | |
); | |
}; | |
return { | |
title: title, | |
height: '250px', | |
collapse: true, | |
panels: panels_network | |
} | |
}; | |
function row_disk_space(title,prefix,filter){ | |
var volumes = find_filter_values(filter + '.df-*'); | |
panels_disk_space = []; | |
for (var i in volumes) { | |
panels_disk_space.push(panel_collectd_df('disk space',prefix,volumes[i])); | |
}; | |
return { | |
title: title, | |
height: '250px', | |
collapse: true, | |
panels: panels_disk_space | |
} | |
}; | |
function row_disk_usage(title,prefix,filter){ | |
var volumes = find_filter_values(filter + '.disk-*'); | |
var panels_disk_usage = []; | |
for (var i in volumes) { | |
panels_disk_usage.push(panel_collectd_disk('disk ops read/write',prefix,volumes[i])); | |
}; | |
return { | |
title: title, | |
height: '250px', | |
collapse: true, | |
panels: panels_disk_usage | |
} | |
}; | |
return function(callback) { | |
// Setup some variables | |
var dashboard; | |
/* prefix - depends on actual Graphite tree. | |
In my case it depends on environment which can be passed as argument too. | |
.collectd.hosts. | |
.statsd.hosts. | |
.jmxtrans.hosts. | |
*/ | |
var prefix = arg_env + '.collectd.hosts.'; | |
var arg_filter = prefix + arg_i; | |
// set filter | |
var dashboard_filter = { | |
time: { | |
from: "now-" + arg_from, | |
to: "now" | |
}, | |
list: [ | |
get_filter_object("instance",arg_filter,false) | |
] | |
}; | |
// define pulldowns | |
pulldowns = [ | |
{ | |
type: "filtering", | |
collapse: false, | |
notice: false, | |
enable: true | |
}, | |
{ | |
type: "annotations", | |
enable: false | |
} | |
]; | |
// Intialize a skeleton with nothing but a rows array and service object | |
dashboard = { | |
rows : [], | |
services : {} | |
}; | |
dashboard.title = arg_i + ' (' + arg_env + ')'; | |
dashboard.editable = true; | |
dashboard.pulldowns = pulldowns; | |
dashboard.services.filter = dashboard_filter; | |
// custom dashboard rows (appended to the default dashboard rows) | |
var optional_rows = []; | |
// If there are any JMX metrics available for this host - append them to dashboard | |
var proc_metrics = expand_filter_values(arg_env + '.jmxtrans.hosts.' + arg_i + '.proc.*.jmx'); | |
for (var m in proc_metrics) { | |
proc_name = proc_metrics[m].split('.')[5]; | |
var jmx_prefix = arg_env + '.jmxtrans.hosts.[[instance]].proc.' + proc_name + '.jmx.'; | |
optional_rows.push( | |
row_delimiter(proc_name), | |
row_jvm('JVM Heap',jmx_prefix) | |
); | |
var jetty_metric = find_filter_values(arg_env + '.jmxtrans.hosts.' + arg_i + '.proc.' + proc_name + '.jmx.jetty_threads'); | |
if (jetty_metric.length > 0) { | |
optional_rows.push(row_jetty('Jetty',jmx_prefix)); | |
}; | |
}; | |
$.ajax({ | |
method: 'GET', | |
url: '/' | |
}) | |
.done(function(result) { | |
// costruct dashboard rows | |
dashboard.rows.push( | |
row_cpu_memory('cpu, memory',prefix), | |
row_swap('swap',prefix), | |
row_network('network',prefix,arg_filter), | |
row_disk_space('disk space',prefix,arg_filter), | |
row_disk_usage('disk ops',prefix,arg_filter) | |
); | |
// custom rows | |
for (var i in optional_rows){ | |
dashboard.rows.push(optional_rows[i]); | |
}; | |
// when dashboard is composed call the callback | |
// function and pass the dashboard | |
callback(dashboard); | |
}); | |
} |
This might give you some ideas. This is based on one of the included scripts in the public/dashboards directory of grafana
modified it to work with otsdb and nagios
/* global _ */
/*
- Simple scripted dashboard
- This script generates a dashboard object that Grafana can load. It also takes a number of user
- supplied URL parameters (in the ARGS variable)
* - Return a dashboard object, or a function
* - For async scripts, return a function, this function must take a single callback function as argument,
- call this callback function with the dashboard object (look at scripted_async.js for an example)
- Modified to work from nagios extended info url
- Takes a nagios service name and host name pair and passes it to this script
- and displays a single metric based on the service check.
*/
// accessible variables in this scope
var window, document, ARGS, $, jQuery, moment, kbn;
// Setup some variables
var dashboard;
// All url parameters are available via the ARGS object
var ARGS;
// Intialize a skeleton with nothing but a rows array and service object
dashboard = {
rows : [],
};
// Set a title
dashboard.title =ARGS.host;
// Set default time
// time can be overriden in the url using from/to parameters, but this is
// handled automatically in grafana core during dashboard initialization
dashboard.time = {
from: "now-6h",
to: "now"
};
var rows = 1;
// regex works on the following form servicename_tsdb_3m_cpu3_util
var objRegExp = /(\w+tsdb\d+\w_)(\S+)/
var newMetricName = ARGS.name.replace(objRegExp,"$2");
if(!_.isUndefined(ARGS.name)) {
metricName = newMetricName
}
for (var i = 0; i < rows; i++) {
dashboard.rows.push({
title: metricName,
height: '300px',
panels: [
{
title: metricName,
type: 'graph',
span: 12,
fill: 1,
linewidth: 2,
targets: [
{
"aggregator": "avg",
"downsampleAggregator": "avg",
"errors": {},
"metric":newMetricName,
"tags": {
"hostname": ARGS.host,
}
}
],
tooltip: {
shared: true
}
}
]
});
}
return dashboard;
returns a single metric on a single graph dashboard designed to be accessible directly from the nagios service check.
Hi,
can i get a script for openTSDB datasource instead of graphite. Actually my requirement is, i need to show cpu utility in a single graph or table with a single click for all the devices instead of selecting each single device. Please give me any suggestions. Thank you.