summaryrefslogtreecommitdiffstats
path: root/web/index.html
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--web/index.html816
1 files changed, 540 insertions, 276 deletions
diff --git a/web/index.html b/web/index.html
index d8e128234..250dbfed3 100644
--- a/web/index.html
+++ b/web/index.html
@@ -35,7 +35,7 @@
<meta property="og:site_name" content="netdata"/>
<meta property="og:title" content="Get control of your Linux Servers. Simple. Effective. Awesome." />
<meta property="og:description" content="Unparalleled insights, in real-time, of everything happening on your Linux systems and applications, with stunning, interactive web dashboards and powerful performance and health alarms." />
- <meta property="og:image" content="https://cloud.githubusercontent.com/assets/2662304/20910305/65d10354-bb69-11e6-8128-c44b547517b4.png" />
+ <meta property="og:image" content="https://cloud.githubusercontent.com/assets/2662304/22945737/e98cd0c6-f2fd-11e6-96f1-5501934b0955.png" />
<meta property="og:image:type" content="image/png" />
<meta property="fb:app_id" content="1200089276712916" />
@@ -508,16 +508,36 @@
// --------------------------------------------------------------------
// check options that should be processed before loading netdata.js
+ var localStorageTested = -1;
+ function localStorageTest() {
+ if(localStorageTested !== -1)
+ return localStorageTested;
+
+ if(typeof Storage !== "undefined" && typeof localStorage === 'object') {
+ var test = 'test';
+ try {
+ localStorage.setItem(test, test);
+ localStorage.removeItem(test);
+ localStorageTested = true;
+ }
+ catch (e) {
+ localStorageTested = false;
+ }
+ }
+ else
+ localStorageTested = false;
+
+ return localStorageTested;
+ }
+
function loadLocalStorage(name) {
var ret = null;
try {
- if(typeof Storage !== "undefined" && typeof localStorage === 'object')
+ if(localStorageTest() === true)
ret = localStorage.getItem(name);
}
- catch(error) {
- ;
- }
+ catch(error) {}
if(typeof ret === 'undefined' || ret === null)
return null;
@@ -530,14 +550,12 @@
function saveLocalStorage(name, value) {
// console.log('saving: ' + name.toString() + ' = ' + value.toString());
try {
- if(typeof Storage !== "undefined" && typeof localStorage === 'object') {
+ if(localStorageTest() === true) {
localStorage.setItem(name, value.toString());
return true;
}
}
- catch(error) {
- ;
- }
+ catch(error) {}
return false;
}
@@ -579,7 +597,52 @@
var netdataRegistryCallback = function(machines_array) {
var el = '';
var a1 = '';
- var found = 0;
+ var found = 0, hosted = 0;
+ var len, i, url, hostname, icon;
+
+ if(options.hosts.length > 1) {
+ // there are mirrored hosts here
+
+ el += '<li><a href="#" onClick="return false;" style="color: #666;" target="_blank">databases available on this host</a></li>';
+ a1 += '<li><a href="#" onClick="return false;"><i class="fa fa-info-circle" aria-hidden="true" style="color: #666;"></i></a></li>';
+
+ var base = document.location.origin.toString() + document.location.pathname.toString();
+ if(base.endsWith("/host/" + options.hostname + "/"))
+ base = base.substring(0, base.length - ("/host/" + options.hostname + "/").toString().length);
+
+ if(base.endsWith("/"))
+ base = base.substring(0, base.length - 1);
+
+ var master = options.hosts[0].hostname;
+ var sorted = options.hosts.sort(function(a, b) {
+ if(a.hostname === master) return -1;
+ if(a.hostname === b.hostname) return 0;
+ else if(a.hostname > b.hostname) return 1;
+ return -1;
+ });
+
+ i = 0;
+ len = sorted.length;
+ while(len--) {
+ hostname = sorted[i].hostname;
+ if(hostname == master) {
+ url = base + "/";
+ icon = "home";
+ }
+ else {
+ url = base + "/host/" + hostname + "/";
+ icon = "window-restore";
+ }
+
+ el += '<li id="registry_server_hosted_' + len.toString() + '"><a class="registry_link" href="' + url + '" onClick="return gotoHostedModalHandler(\'' + url + '\');">' + hostname + '</a></li>';
+ a1 += '<li id="registry_action_hosted_' + len.toString() + '"><a class="registry_link" href="' + url + '" onClick="return gotoHostedModalHandler(\'' + url + '\');"><i class="fa fa-' + icon + '" aria-hidden="true" style="color: #999;"></i></a></li>';
+ hosted++;
+ i++;
+ }
+
+ el += '<li role="separator" class="divider"></li>';
+ a1 += '<li role="separator" class="divider"></li>';
+ }
if(machines_array === null) {
var ret = loadLocalStorage("registryCallback");
@@ -598,7 +661,7 @@
return 0;
});
- var len = machines.length;
+ len = machines.length;
while(len--) {
var u = machines[len];
found++;
@@ -663,10 +726,7 @@
this_is_demo = true;
}
}
- catch(error) {
- ;
- }
-
+ catch(error) {}
return this_is_demo;
}
@@ -685,15 +745,18 @@
}
function netdataReload(url) {
- var t = netdataURL(url);
- // console.log('netdataReload: ' + t);
- document.location = t;
+ document.location = netdataURL(url);
// since we play with hash
// this is needed to reload the page
location.reload();
}
+ function gotoHostedModalHandler(url) {
+ document.location = url + urlOptions.genHash();
+ return false;
+ }
+
var gotoServerValidateRemaining = 0;
var gotoServerMiddleClick = false;
var gotoServerStop = false;
@@ -830,6 +893,8 @@
var deleteRegistryUrl = null;
function deleteRegistryModalHandler(guid, name, url) {
+ void(guid);
+
deleteRegistryUrl = url;
document.getElementById('deleteRegistryServerName').innerHTML = name;
document.getElementById('deleteRegistryServerName2').innerHTML = name;
@@ -854,47 +919,28 @@
}
var options = {
- sparklines_registry: {},
menus: {},
submenu_names: {},
data: null,
hostname: 'netdata_server', // will be overwritten by the netdata server
- categories: new Array(),
+ version: 'unknown',
+ categories: [],
categories_idx: {},
- families: new Array(),
+ families: [],
families_idx: {},
+ hosts: [],
chartsPerRow: 0,
- chartsMinWidth: 1450,
- chartsHeight: 180,
- sparklinesHeight: 60,
+ // chartsMinWidth: 1450,
+ chartsHeight: 180
};
- // generate a sparkline
- // used in the documentation
- function sparkline(chart, dimension, units) {
- var key = chart + '.' + dimension;
-
- if(typeof units === 'undefined')
- units = '';
-
- if(typeof options.sparklines_registry[key] === 'undefined')
- options.sparklines_registry[key] = { count: 1 };
- else
- options.sparklines_registry[key].count++;
-
- key = key + '.' + options.sparklines_registry[key].count;
-
- var h = '<div data-netdata="' + chart + '" data-after="-120" data-width="25%" data-height="15px" data-chart-library="dygraph" data-dygraph-theme="sparkline" data-dimensions="' + dimension + '" data-show-value-of-' + dimension + '-at="' + key + '"></div> (<span id="' + key + '" style="display: inline-block; min-width: 50px; text-align: right;">X</span>' + units + ')';
-
- return h;
- }
-
function chartsPerRow(total) {
if(options.chartsPerRow === 0) {
- width = Math.floor(total / options.chartsMinWidth);
- if(width === 0) width = 1;
- return width;
+ return 1;
+ //var width = Math.floor(total / options.chartsMinWidth);
+ //if(width === 0) width = 1;
+ //return width;
}
else return options.chartsPerRow;
}
@@ -908,9 +954,11 @@
function sortObjectByPriority(object) {
var idx = {};
- var sorted = new Array();
+ var sorted = [];
for(var i in object) {
+ if(!object.hasOwnProperty(i)) continue;
+
if(typeof idx[i] === 'undefined') {
idx[i] = object[i];
sorted.push(i);
@@ -944,11 +992,52 @@
// ----------------------------------------------------------------------------
+ // user editable information
+ var customDashboard = {
+ menu: {},
+ submenu: {},
+ context: {}
+ };
+
+ // netdata standard information
var netdataDashboard = {
+ sparklines_registry: {},
+ os: 'unknown',
+
menu: {},
submenu: {},
context: {},
+ // generate a sparkline
+ // used in the documentation
+ sparkline: function (prefix, chart, dimension, units, suffix) {
+ if(options.data === null || typeof options.data.charts === 'undefined')
+ return '';
+
+ if(typeof options.data.charts[chart] === 'undefined')
+ return '';
+
+ if(typeof options.data.charts[chart].dimensions === 'undefined')
+ return '';
+
+ if(typeof options.data.charts[chart].dimensions[dimension] === 'undefined')
+ return '';
+
+ var key = chart + '.' + dimension;
+
+ if(typeof units === 'undefined')
+ units = '';
+
+ if(typeof this.sparklines_registry[key] === 'undefined')
+ this.sparklines_registry[key] = { count: 1 };
+ else
+ this.sparklines_registry[key].count++;
+
+ key = key + '.' + this.sparklines_registry[key].count;
+
+ return prefix + '<div data-netdata="' + chart + '" data-after="-120" data-width="25%" data-height="15px" data-chart-library="dygraph" data-dygraph-theme="sparkline" data-dimensions="' + dimension + '" data-show-value-of-' + dimension + '-at="' + key + '"></div> (<span id="' + key + '" style="display: inline-block; min-width: 50px; text-align: right;">X</span>' + units + ')' + suffix;
+ },
+
gaugeChart: function(title, width, dimensions, colors) {
if(typeof colors === 'undefined')
colors = '';
@@ -957,53 +1046,69 @@
dimensions = '';
return '<div data-netdata="CHART_UNIQUE_ID"'
- + ' data-dimensions="' + dimensions + '"'
- + ' data-chart-library="gauge"'
- + ' data-gauge-adjust="width"'
- + ' data-title="' + title + '"'
- + ' data-width="' + width + '"'
- + ' data-before="0"'
- + ' data-after="-CHART_DURATION"'
- + ' data-points="CHART_DURATION"'
- + ' data-colors="' + colors + '"'
- + ' role="application"></div>';
+ + ' data-dimensions="' + dimensions + '"'
+ + ' data-chart-library="gauge"'
+ + ' data-gauge-adjust="width"'
+ + ' data-title="' + title + '"'
+ + ' data-width="' + width + '"'
+ + ' data-before="0"'
+ + ' data-after="-CHART_DURATION"'
+ + ' data-points="CHART_DURATION"'
+ + ' data-colors="' + colors + '"'
+ + ' role="application"></div>';
},
anyAttribute: function(obj, attr, key, def) {
- if(typeof obj[key] !== 'undefined') {
- if(typeof obj[key][attr] !== 'undefined')
- return obj[key][attr];
+ if(typeof(obj[key]) !== 'undefined') {
+ var x = obj[key][attr];
+
+ if(typeof(x) === 'undefined')
+ return def;
+
+ if(typeof(x) === 'function') {
+ return x(netdataDashboard.os);
+ }
+
+ return x;
}
+
return def;
},
menuTitle: function(chart) {
if(typeof chart.menu_pattern !== 'undefined') {
- return (netdataDashboard.anyAttribute(netdataDashboard.menu, 'title', chart.menu_pattern, chart.menu_pattern).toString()
+ return (this.anyAttribute(this.menu, 'title', chart.menu_pattern, chart.menu_pattern).toString()
+ '&nbsp;' + chart.type.slice(-(chart.type.length - chart.menu_pattern.length - 1)).toString()).replace(/_/g, ' ');
}
- return (netdataDashboard.anyAttribute(netdataDashboard.menu, 'title', chart.menu, chart.menu)).toString().replace(/_/g, ' ');
+ return (this.anyAttribute(this.menu, 'title', chart.menu, chart.menu)).toString().replace(/_/g, ' ');
},
menuIcon: function(chart) {
if(typeof chart.menu_pattern !== 'undefined')
- return netdataDashboard.anyAttribute(netdataDashboard.menu, 'icon', chart.menu_pattern, '<i class="fa fa-puzzle-piece" aria-hidden="true"></i>').toString();
+ return this.anyAttribute(this.menu, 'icon', chart.menu_pattern, '<i class="fa fa-puzzle-piece" aria-hidden="true"></i>').toString();
- return netdataDashboard.anyAttribute(netdataDashboard.menu, 'icon', chart.menu, '<i class="fa fa-puzzle-piece" aria-hidden="true"></i>');
+ return this.anyAttribute(this.menu, 'icon', chart.menu, '<i class="fa fa-puzzle-piece" aria-hidden="true"></i>');
},
- menuInfo: function(menu) {
- return netdataDashboard.anyAttribute(netdataDashboard.menu, 'info', menu, null);
+ menuInfo: function(chart) {
+ if(typeof chart.menu_pattern !== 'undefined')
+ return this.anyAttribute(this.menu, 'info', chart.menu_pattern, null);
+
+ return this.anyAttribute(this.menu, 'info', chart.menu, null);
},
- menuHeight: function(menu, relative) {
- return netdataDashboard.anyAttribute(netdataDashboard.menu, 'height', menu, 1.0) * relative;
+ menuHeight: function(chart) {
+ if(typeof chart.menu_pattern !== 'undefined')
+ return this.anyAttribute(this.menu, 'height', chart.menu_pattern, 1.0);
+
+ return this.anyAttribute(this.menu, 'height', chart.menu, 1.0);
},
submenuTitle: function(menu, submenu) {
var key = menu + '.' + submenu;
- var title = netdataDashboard.anyAttribute(netdataDashboard.submenu, 'title', key, submenu).toString().replace(/_/g, ' ');;
+ // console.log(key);
+ var title = this.anyAttribute(this.submenu, 'title', key, submenu).toString().replace(/_/g, ' ');
if(title.length > 28) {
var a = title.substring(0, 13);
var b = title.substring(title.length - 12, title.length);
@@ -1014,31 +1119,33 @@
submenuInfo: function(menu, submenu) {
var key = menu + '.' + submenu;
- return netdataDashboard.anyAttribute(netdataDashboard.submenu, 'info', key, null);
+ return this.anyAttribute(this.submenu, 'info', key, null);
},
submenuHeight: function(menu, submenu, relative) {
var key = menu + '.' + submenu;
- return netdataDashboard.anyAttribute(netdataDashboard.submenu, 'height', key, 1.0) * relative;
+ return this.anyAttribute(this.submenu, 'height', key, 1.0) * relative;
},
contextInfo: function(id) {
- if(typeof netdataDashboard.context[id] !== 'undefined' && typeof netdataDashboard.context[id].info !== 'undefined')
- return '<div class="chart-message netdata-chart-alignment" role="document">' + netdataDashboard.context[id].info + '</div>';
+ var x = this.anyAttribute(this.context, 'info', id, null);
+
+ if(x !== null)
+ return '<div class="chart-message netdata-chart-alignment" role="document">' + x + '</div>';
else
return '';
},
contextValueRange: function(id) {
- if(typeof netdataDashboard.context[id] !== 'undefined' && typeof netdataDashboard.context[id].valueRange !== 'undefined')
- return netdataDashboard.context[id].valueRange;
+ if(typeof this.context[id] !== 'undefined' && typeof this.context[id].valueRange !== 'undefined')
+ return this.context[id].valueRange;
else
return '[null, null]';
},
contextHeight: function(id, def) {
- if(typeof netdataDashboard.context[id] !== 'undefined' && typeof netdataDashboard.context[id].height !== 'undefined')
- return def * netdataDashboard.context[id].height;
+ if(typeof this.context[id] !== 'undefined' && typeof this.context[id].height !== 'undefined')
+ return def * this.context[id].height;
else
return def;
}
@@ -1048,8 +1155,10 @@
// enrich the data structure returned by netdata
// to reflect our menu system and content
+ // FIXME: this is a shame - we should fix charts naming (issue #807)
function enrichChartData(chart) {
- var tmp = chart.type.split('_')[0];
+ var parts = chart.type.split('_');
+ var tmp = parts[0];
switch(tmp) {
case 'ap':
@@ -1058,6 +1167,22 @@
chart.menu = tmp;
break;
+ case 'apache':
+ chart.menu = chart.type;
+ if(parts.length > 2 && parts[1] === 'cache')
+ chart.menu_pattern = tmp + '_' + parts[1];
+ else if(parts.length > 1)
+ chart.menu_pattern = tmp;
+ break;
+
+ case 'bind':
+ chart.menu = chart.type;
+ if(parts.length > 2 && parts[1] === 'rndc')
+ chart.menu_pattern = tmp + '_' + parts[1];
+ else if(parts.length > 1)
+ chart.menu_pattern = tmp;
+ break;
+
case 'cgroup':
chart.menu = chart.type;
if(chart.id.match(/.*[\._\/-:]qemu[\._\/-:]*/) || chart.id.match(/.*[\._\/-:]kvm[\._\/-:]*/))
@@ -1066,27 +1191,29 @@
chart.menu_pattern = 'cgroup';
break;
- case 'apache':
- case 'exim':
- case 'dovecot':
- case 'hddtemp':
- case 'ipfs':
- case 'memcached':
- case 'mysql':
- case 'named':
- case 'nginx':
- case 'nut':
- case 'phpfpm':
- case 'postfix':
- case 'postgres':
- case 'redis':
- case 'retroshare':
- case 'smawebbox':
- case 'snmp':
- case 'squid':
- case 'tomcat':
+ case 'isc':
chart.menu = chart.type;
- chart.menu_pattern = tmp;
+ if(parts.length > 2 && parts[1] === 'dhcpd')
+ chart.menu_pattern = tmp + '_' + parts[1];
+ else if(parts.length > 1)
+ chart.menu_pattern = tmp;
+ break;
+
+ case 'ovpn':
+ chart.menu = chart.type;
+ if(parts.length > 3 && parts[1] === 'status' && parts[2] === 'log')
+ chart.menu_pattern = tmp + '_' + parts[1];
+ else if(parts.length > 1)
+ chart.menu_pattern = tmp;
+ break;
+
+ case 'smartd':
+ case 'web':
+ chart.menu = chart.type;
+ if(parts.length > 2 && parts[1] === 'log')
+ chart.menu_pattern = tmp + '_' + parts[1];
+ else if(parts.length > 1)
+ chart.menu_pattern = tmp;
break;
case 'tc':
@@ -1094,7 +1221,7 @@
// find a name for this device from fireqos info
// we strip '_(in|out)' or '(in|out)_'
- if(typeof options.submenu_names[chart.family] === 'undefined' || options.submenu_names[chart.family] === chart.family) {
+ if(chart.context === 'tc.qos' && (typeof options.submenu_names[chart.family] === 'undefined' || options.submenu_names[chart.family] === chart.family)) {
var n = chart.name.split('.')[1];
if(n.endsWith('_in'))
options.submenu_names[chart.family] = n.slice(0, n.lastIndexOf('_in'));
@@ -1104,6 +1231,8 @@
options.submenu_names[chart.family] = n.slice(3, n.length);
else if(n.startsWith('out_'))
options.submenu_names[chart.family] = n.slice(4, n.length);
+ else
+ options.submenu_names[chart.family] = n;
}
// increase the priority of IFB devices
@@ -1115,6 +1244,8 @@
default:
chart.menu = chart.type;
+ if(parts.length > 1)
+ chart.menu_pattern = tmp;
break;
}
@@ -1123,7 +1254,9 @@
// ----------------------------------------------------------------------------
- function headMain(charts, duration) {
+ function headMain(os, charts, duration) {
+ void(os);
+
var head = '';
if(typeof charts['system.swap'] !== 'undefined')
@@ -1244,7 +1377,7 @@
var hi = 0, hlen = hcharts.length;
while(hi < hlen) {
if(typeof hcharts[hi] === 'function')
- head += hcharts[hi](chart.id).replace('CHART_DURATION', duration.toString()).replace('CHART_UNIQUE_ID', chart.id);
+ head += hcharts[hi](netdataDashboard.os, chart.id).replace('CHART_DURATION', duration.toString()).replace('CHART_UNIQUE_ID', chart.id);
else
head += hcharts[hi].replace('CHART_DURATION', duration.toString()).replace('CHART_UNIQUE_ID', chart.id);
hi++;
@@ -1261,7 +1394,7 @@
var duration = Math.round(($(div).width() * pcent_width / 100 * data.update_every / 3) / 60) * 60;
var html = '';
var sidebar = '<ul class="nav dashboard-sidenav" data-spy="affix" id="sidebar_ul">';
- var mainhead = headMain(data.charts, duration);
+ var mainhead = headMain(netdataDashboard.os, data.charts, duration);
// sort the menus
var main = sortObjectByPriority(menus);
@@ -1338,7 +1471,7 @@
sidebar += '<li class="" style="padding-top:15px;"><a href="https://github.com/firehol/netdata/wiki/Add-more-charts-to-netdata" target="_blank"><i class="fa fa-plus" aria-hidden="true"></i> add more charts</a></li>';
sidebar += '<li class=""><a href="https://github.com/firehol/netdata/wiki/Add-more-alarms-to-netdata" target="_blank"><i class="fa fa-plus" aria-hidden="true"></i> add more alarms</a></li>';
- sidebar += '<li class="" style="margin:20px;color:#666;"><small>netdata on <b>' + data.hostname.toString() + '</b>, collects every ' + ((data.update_every == 1)?'second':data.update_every.toString() + ' seconds') + ' <b>' + data.dimensions_count.toLocaleString() + '</b> metrics, presented as <b>' + data.charts_count.toLocaleString() + '</b> charts and monitored by <b>' + data.alarms_count.toLocaleString() + '</b> alarms, using ' + Math.round(data.rrd_memory_bytes / 1024 / 1024).toLocaleString() + ' MB of memory for ' + Math.round(data.history / (3600/data.update_every)).toLocaleString() + ' ' + ((data.history == (3600/data.update_every))?'hour':'hours').toString() + ' of real-time history.</small></li>';
+ sidebar += '<li class="" style="margin:20px;color:#666;"><small>netdata on <b>' + data.hostname.toString() + '</b>, collects every ' + ((data.update_every == 1)?'second':data.update_every.toString() + ' seconds') + ' <b>' + data.dimensions_count.toLocaleString() + '</b> metrics, presented as <b>' + data.charts_count.toLocaleString() + '</b> charts and monitored by <b>' + data.alarms_count.toLocaleString() + '</b> alarms, using ' + Math.round(data.rrd_memory_bytes / 1024 / 1024).toLocaleString() + ' MB of memory for ' + seconds4human(data.update_every * data.history) + ' of real-time history.<br/>&nbsp;<br/><b>netdata</b><br/>v' + data.version.toString() +'</small></li>';
sidebar += '</ul>';
div.innerHTML = html;
document.getElementById('sidebar').innerHTML = sidebar;
@@ -1348,53 +1481,71 @@
function renderChartsAndMenu(data) {
var menus = options.menus;
var charts = data.charts;
+ var m, menu_key;
for(var c in charts) {
- enrichChartData(charts[c]);
+ if(!charts.hasOwnProperty(c)) continue;
+
+ var chart = charts[c];
+ enrichChartData(chart);
+ m = chart.menu;
// create the menu
- if(typeof menus[charts[c].menu] === 'undefined') {
- menus[charts[c].menu] = {
- priority: charts[c].priority,
+ if(typeof menus[m] === 'undefined') {
+ menus[m] = {
+ menu_pattern: chart.menu_pattern,
+ priority: chart.priority,
submenus: {},
- title: netdataDashboard.menuTitle(charts[c]),
- icon: netdataDashboard.menuIcon(charts[c]),
- info: netdataDashboard.menuInfo(charts[c].menu),
- height: netdataDashboard.menuHeight(charts[c].menu, options.chartsHeight)
+ title: netdataDashboard.menuTitle(chart),
+ icon: netdataDashboard.menuIcon(chart),
+ info: netdataDashboard.menuInfo(chart),
+ height: netdataDashboard.menuHeight(chart) * options.chartsHeight
};
}
+ else {
+ if(typeof(menus[m].menu_pattern) === 'undefined')
+ menus[m].menu_pattern = chart.menu_pattern;
+
+ if(chart.priority < menus[m].priority)
+ menus[m].priority = chart.priority;
+ }
- if(charts[c].priority < menus[charts[c].menu].priority)
- menus[charts[c].menu].priority = charts[c].priority;
+ menu_key = (typeof(menus[m].menu_pattern) !== 'undefined')?menus[m].menu_pattern:m;
// create the submenu
- if(typeof menus[charts[c].menu].submenus[charts[c].submenu] === 'undefined') {
- menus[charts[c].menu].submenus[charts[c].submenu] = {
- priority: charts[c].priority,
- charts: new Array(),
+ if(typeof menus[m].submenus[chart.submenu] === 'undefined') {
+ menus[m].submenus[chart.submenu] = {
+ priority: chart.priority,
+ charts: [],
title: null,
- info: netdataDashboard.submenuInfo(charts[c].menu, charts[c].submenu),
- height: netdataDashboard.submenuHeight(charts[c].menu, charts[c].submenu, menus[charts[c].menu].height)
+ info: netdataDashboard.submenuInfo(menu_key, chart.submenu),
+ height: netdataDashboard.submenuHeight(menu_key, chart.submenu, menus[m].height)
};
}
-
- if(charts[c].priority < menus[charts[c].menu].submenus[charts[c].submenu].priority)
- menus[charts[c].menu].submenus[charts[c].submenu].priority = charts[c].priority;
+ else {
+ if (chart.priority < menus[m].submenus[chart.submenu].priority)
+ menus[m].submenus[chart.submenu].priority = chart.priority;
+ }
// index the chart in the menu/submenu
- menus[charts[c].menu].submenus[charts[c].submenu].charts.push(charts[c]);
+ menus[m].submenus[chart.submenu].charts.push(chart);
}
// propagate the descriptive subname given to QoS
// to all the other submenus with the same name
- for(var m in menus) {
+ for(m in menus) {
+ if(!menus.hasOwnProperty(m)) continue;
+
for(var s in menus[m].submenus) {
+ if(!menus[m].submenus.hasOwnProperty(s)) continue;
+
// set the family using a name
if(typeof options.submenu_names[s] !== 'undefined') {
menus[m].submenus[s].title = s + ' (' + options.submenu_names[s] + ')';
}
else {
- menus[m].submenus[s].title = netdataDashboard.submenuTitle(m, s);
+ menu_key = (typeof(menus[m].menu_pattern) !== 'undefined')?menus[m].menu_pattern:m;
+ menus[m].submenus[s].title = netdataDashboard.submenuTitle(menu_key, s);
}
}
}
@@ -1423,7 +1574,7 @@
var bootstrapTableLoaded = false;
function loadBootstrapTable(callback) {
if(bootstrapTableLoaded === false) {
- bootstrapTableLoaded === true;
+ bootstrapTableLoaded = true;
loadJs(NETDATA.serverDefault + 'lib/bootstrap-table-1.11.0.min.js', function() {
loadJs(NETDATA.serverDefault + 'lib/bootstrap-table-export-1.11.0.min.js', function() {
loadJs(NETDATA.serverDefault + 'lib/tableExport-1.6.0.min.js', callback);
@@ -1439,7 +1590,7 @@
var footer = '<hr/><a href="https://github.com/firehol/netdata/wiki/Generating-Badges" target="_blank">netdata badges</a> refresh automatically. Their color indicates the state of the alarm: <span style="color: #e05d44"><b>&nbsp;red&nbsp;</b></span> is critical, <span style="color:#fe7d37"><b>&nbsp;orange&nbsp;</b></span> is warning, <span style="color: #4c1"><b>&nbsp;bright green&nbsp;</b></span> is ok, <span style="color: #9f9f9f"><b>&nbsp;light grey&nbsp;</b></span> is undefined (i.e. no data or no status), <span style="color: #000"><b>&nbsp;black&nbsp;</b></span> is not initialized. You can copy and paste their URLs to embed them in any web page.<br/>netdata can send notifications for these alarms. Check <a href="https://github.com/firehol/netdata/blob/master/conf.d/health_alarm_notify.conf">this configuration file</a> for more information.';
NETDATA.alarms.get('all', function(data) {
- options.alarm_families = new Array();
+ options.alarm_families = [];
alarmsCallback(data);
@@ -1474,70 +1625,6 @@
return t.toLocaleDateString() + space + t.toLocaleTimeString();
}
- function seconds4human(seconds, options) {
- var default_options = {
- now: 'now',
- space: '&nbsp;',
- negative_suffix: 'ago',
- hour: 'hour',
- hours: 'hours',
- minute: 'minute',
- minutes: 'minutes',
- second: 'second',
- seconds: 'seconds',
- and: 'and'
- };
-
- if(typeof options !== 'object')
- options = default_options;
- else {
- var x;
- for(x in default_options) {
- if(typeof options[x] !== 'string')
- options[x] = default_options[x];
- }
- }
-
- if(typeof seconds === 'string')
- seconds = parseInt(seconds);
-
- if(seconds === 0)
- return options.now;
-
- var suffix = '';
- if(seconds < 0) {
- seconds = -seconds;
- if(options.negative_suffix !== '') suffix = options.space + options.negative_suffix;
- }
-
- var hours = Math.floor(seconds / 3600);
- seconds -= (hours * 3600);
-
- var minutes = Math.floor(seconds / 60);
- seconds -= (minutes * 60);
-
- var txt = '';
-
- if(hours > 1) txt += hours.toString() + options.space + options.hours;
- else if(hours === 1) txt += hours.toString() + options.space + options.hour;
-
- if(hours > 0 && minutes > 0 && seconds == 0)
- txt += options.space + options.and + options.space;
- else if(hours > 0 && minutes > 0 && seconds > 0)
- txt += ',' + options.space;
-
- if(minutes > 1) txt += minutes.toString() + options.space + options.minutes;
- else if(minutes === 1) txt += minutes.toString() + options.space + options.minute;
-
- if((minutes > 0 || minutes > 0) && seconds > 0)
- txt += options.space + options.and + options.space;
-
- if(seconds > 1) txt += Math.floor(seconds).toString() + options.space + options.seconds;
- else if(seconds === 1) txt += Math.floor(seconds).toString() + options.space + options.second;
-
- return txt + suffix;
- }
-
function alarm_lookup_explain(alarm, chart) {
var dimensions = ' of all values ';
@@ -1562,7 +1649,14 @@
function alarm_to_html(alarm, full) {
var chart = options.data.charts[alarm.chart];
- var has_alarm = ((typeof alarm.warn !== 'undefined' || typeof alarm.crit !== 'undefined')?true:false);
+ if(typeof(chart) === 'undefined') {
+ // this means the charts loaded are incomplete
+ // probably netdata was restarted and more charts
+ // are now available.
+ return '';
+ }
+
+ var has_alarm = (typeof alarm.warn !== 'undefined' || typeof alarm.crit !== 'undefined');
var role_href = ((has_alarm === true)?('<br/>&nbsp;<br/>role: <b>' + alarm.recipient + '</b><br/>&nbsp;<br/><b><i class="fa fa-line-chart" aria-hidden="true"></i></b><small>&nbsp;&nbsp;<a href="#" onClick="NETDATA.alarms.scrollToChart(\'' + alarm.chart + '\'); $(\'#alarmsModal\').modal(\'hide\'); return false;">jump to chart</a></small>'):('&nbsp;'));
@@ -1572,10 +1666,13 @@
+ ((typeof alarm.crit !== 'undefined')?('<tr><td width="10%" style="text-align:right">critical&nbsp;when</td><td><span style="font-family: monospace; color: #e05d44; font-weight: bold;">' + alarm.crit + '</span></td></tr>'):'');
if(full === true) {
- html += ((typeof alarm.lookup_after !== 'undefined')?('<tr><td width="10%" style="text-align:right">db&nbsp;lookup</td><td>' + alarm_lookup_explain(alarm, chart) + '</td></tr>'):'')
+ var units = chart.units;
+ if(units === '%') units = '&#37;';
+
+ html += ((typeof alarm.lookup_after !== 'undefined')?('<tr><td width="10%" style="text-align:right">db&nbsp;lookup</td><td>' + alarm_lookup_explain(alarm, chart) + '</td></tr>'):'')
+ ((typeof alarm.calc !== 'undefined')?('<tr><td width="10%" style="text-align:right">calculation</td><td><span style="font-family: monospace;">' + alarm.calc + '</span></td></tr>'):'')
- + ((chart.green !== null)?('<tr><td width="10%" style="text-align:right">green&nbsp;threshold</td><td><code>' + chart.green + ' ' + chart.units + '</code></td></tr>'):'')
- + ((chart.red !== null)?('<tr><td width="10%" style="text-align:right">red&nbsp;threshold</td><td><code>' + chart.red + ' ' + chart.units + '</code></td></tr>'):'');
+ + ((chart.green !== null)?('<tr><td width="10%" style="text-align:right">green&nbsp;threshold</td><td><code>' + chart.green + ' ' + units + '</code></td></tr>'):'')
+ + ((chart.red !== null)?('<tr><td width="10%" style="text-align:right">red&nbsp;threshold</td><td><code>' + chart.red + ' ' + units + '</code></td></tr>'):'');
}
var delay = '';
@@ -1622,14 +1719,16 @@
// find the proper family of each alarm
var now = Date.now();
- var x;
+ var x, family, alarm;
var count_active = 0;
var count_all = 0;
var families = {};
- var families_sort = new Array();
+ var families_sort = [];
for(x in data.alarms) {
- var alarm = data.alarms[x];
- var family = alarm.family;
+ if(!data.alarms.hasOwnProperty(x)) continue;
+
+ alarm = data.alarms[x];
+ family = alarm.family;
// find the chart
var chart = options.data.charts[alarm.chart];
@@ -1648,7 +1747,7 @@
if(typeof families[family] === 'undefined') {
families[family] = {
name: family,
- arr: new Array(),
+ arr: [],
priority: chart.priority
};
@@ -1671,7 +1770,7 @@
var fc = 0;
var len = families_sorted.length;
while(len--) {
- var family = families_sorted[len].name;
+ family = families_sorted[len].name;
var active_family_added = false;
var expanded = 'true';
var collapsed = '';
@@ -1680,7 +1779,7 @@
if(fc !== 0) {
all += "</table></div></div></div>";
expanded = 'false';
- collapsed = 'class="collapsed"'
+ collapsed = 'class="collapsed"';
cin = '';
}
@@ -1693,7 +1792,7 @@
var arr = families[family].arr;
var c = arr.length;
while(c--) {
- var alarm = arr[c];
+ alarm = arr[c];
if(alarm.status === 'WARNING' || alarm.status === 'CRITICAL') {
if(!active_family_added) {
active_family_added = true;
@@ -1726,12 +1825,13 @@
if(families_sorted.length > 0) alarm_family_show(0);
// register bootstrap events
- $('#alarms_all_accordion').on('show.bs.collapse', function (d) {
+ var $accordion = $('#alarms_all_accordion');
+ $accordion.on('show.bs.collapse', function (d) {
var target = $(d.target);
var id = $(target).data('alarm-id');
alarm_family_show(id);
});
- $('#alarms_all_accordion').on('hidden.bs.collapse', function (d) {
+ $accordion.on('hidden.bs.collapse', function (d) {
var target = $(d.target);
var id = $(target).data('alarm-id');
$('#alarm_all_' + id.toString()).html('');
@@ -1756,6 +1856,8 @@
fileName: 'netdata_alarm_log'
},
rowStyle: function(row, index) {
+ void(index);
+
switch(row.status) {
case 'CRITICAL' : return { classes: 'danger' }; break;
case 'WARNING' : return { classes: 'warning' }; break;
@@ -1776,9 +1878,8 @@
title: 'Event Date',
valign: 'middle',
titleTooltip: 'The date and time the even took place',
- formatter: function(value, row, index) { return timestamp4human(value, ' '); },
+ formatter: function(value, row, index) { void(row); void(index); return timestamp4human(value, ' '); },
align: 'center',
- valign: 'middle',
switchable: false,
sortable: true
},
@@ -1788,7 +1889,6 @@
valign: 'middle',
titleTooltip: 'The host that generated this event',
align: 'center',
- valign: 'middle',
visible: false,
sortable: true
},
@@ -1796,7 +1896,7 @@
field: 'unique_id',
title: 'Unique ID',
titleTooltip: 'The host unique ID for this event',
- formatter: function(value, row, index) { return alarmid4human(value); },
+ formatter: function(value, row, index) { void(row); void(index); return alarmid4human(value); },
align: 'center',
valign: 'middle',
visible: false,
@@ -1806,7 +1906,7 @@
field: 'alarm_id',
title: 'Alarm ID',
titleTooltip: 'The ID of the alarm that generated this event',
- formatter: function(value, row, index) { return alarmid4human(value); },
+ formatter: function(value, row, index) { void(row); void(index); return alarmid4human(value); },
align: 'center',
valign: 'middle',
visible: false,
@@ -1816,7 +1916,7 @@
field: 'alarm_event_id',
title: 'Alarm Event ID',
titleTooltip: 'The incremental ID of this event for the given alarm',
- formatter: function(value, row, index) { return alarmid4human(value); },
+ formatter: function(value, row, index) { void(row); void(index); return alarmid4human(value); },
align: 'center',
valign: 'middle',
visible: false,
@@ -1845,6 +1945,8 @@
title: 'Alarm',
titleTooltip: 'The alarm name that generated this event',
formatter: function(value, row, index) {
+ void(row);
+ void(index);
return value.toString().replace(/_/g, ' ');
},
align: 'center',
@@ -1853,10 +1955,29 @@
sortable: true
},
{
+ field: 'value_string',
+ title: 'Friendly Value',
+ titleTooltip: 'The value of the alarm, that triggered this event',
+ align: 'right',
+ valign: 'middle',
+ sortable: true
+ },
+ {
+ field: 'old_value_string',
+ title: 'Friendly Old Value',
+ titleTooltip: 'The value of the alarm, just before this event',
+ align: 'right',
+ valign: 'middle',
+ visible: false,
+ sortable: true
+ },
+ {
field: 'old_value',
title: 'Old Value',
titleTooltip: 'The value of the alarm, just before this event',
formatter: function(value, row, index) {
+ void(row);
+ void(index);
return ((value !== null)?Math.round(value * 100) / 100:'NaN').toString();
},
align: 'center',
@@ -1869,10 +1990,13 @@
title: 'Value',
titleTooltip: 'The value of the alarm, that triggered this event',
formatter: function(value, row, index) {
+ void(row);
+ void(index);
return ((value !== null)?Math.round(value * 100) / 100:'NaN').toString();
},
align: 'right',
valign: 'middle',
+ visible: false,
sortable: true
},
{
@@ -1881,6 +2005,7 @@
titleTooltip: 'The units of the value of the alarm',
align: 'left',
valign: 'middle',
+ visible: false,
sortable: true
},
{
@@ -1905,7 +2030,11 @@
field: 'duration',
title: 'Last Duration',
titleTooltip: 'The duration the alarm was at its previous state, just before this event',
- formatter: function(value, row, index) { return seconds4human(value, { negative_suffix: '', space: ' ', now: 'no time' }); },
+ formatter: function(value, row, index) {
+ void(row);
+ void(index);
+ return seconds4human(value, { negative_suffix: '', space: ' ', now: 'no time' });
+ },
align: 'center',
valign: 'middle',
visible: false,
@@ -1915,7 +2044,11 @@
field: 'non_clear_duration',
title: 'Raised Duration',
titleTooltip: 'The duration the alarm was raised, just before this event',
- formatter: function(value, row, index) { return seconds4human(value, { negative_suffix: '', space: ' ', now: 'no time' }); },
+ formatter: function(value, row, index) {
+ void(row);
+ void(index);
+ return seconds4human(value, { negative_suffix: '', space: ' ', now: 'no time' });
+ },
align: 'center',
valign: 'middle',
visible: false,
@@ -1935,6 +2068,9 @@
title: 'Processed Status',
titleTooltip: 'True when this event is processed',
formatter: function(value, row, index) {
+ void(row);
+ void(index);
+
if(value === true)
return 'DONE';
else
@@ -1950,6 +2086,9 @@
title: 'Updated Status',
titleTooltip: 'True when this event has been updated by another event',
formatter: function(value, row, index) {
+ void(row);
+ void(index);
+
if(value === true)
return 'UPDATED';
else
@@ -1964,7 +2103,7 @@
field: 'updated_by_id',
title: 'Updated By ID',
titleTooltip: 'The unique ID of the event that obsoleted this one',
- formatter: function(value, row, index) { return alarmid4human(value); },
+ formatter: function(value, row, index) { void(row); void(index); return alarmid4human(value); },
align: 'center',
valign: 'middle',
visible: false,
@@ -1974,7 +2113,7 @@
field: 'updates_id',
title: 'Updates ID',
titleTooltip: 'The unique ID of the event obsoleted because of this event',
- formatter: function(value, row, index) { return alarmid4human(value); },
+ formatter: function(value, row, index) { void(row); void(index); return alarmid4human(value); },
align: 'center',
valign: 'middle',
visible: false,
@@ -1993,7 +2132,7 @@
field: 'exec_run',
title: 'Script Run At',
titleTooltip: 'The date and time the script has been ran',
- formatter: function(value, row, index) { return timestamp4human(value, ' '); },
+ formatter: function(value, row, index) { void(row); void(index); return timestamp4human(value, ' '); },
align: 'center',
valign: 'middle',
visible: false,
@@ -2004,6 +2143,9 @@
title: 'Script Return Value',
titleTooltip: 'The return code of the script',
formatter: function(value, row, index) {
+ void(row);
+ void(index);
+
if(value === 0)
return 'OK (returned 0)';
else
@@ -2018,7 +2160,12 @@
field: 'delay',
title: 'Script Delay',
titleTooltip: 'The hysteresis of the notification',
- formatter: function(value, row, index) { return seconds4human(value, { negative_suffix: '', space: ' ', now: 'no time' }); },
+ formatter: function(value, row, index) {
+ void(row);
+ void(index);
+
+ return seconds4human(value, { negative_suffix: '', space: ' ', now: 'no time' });
+ },
align: 'center',
valign: 'middle',
visible: false,
@@ -2028,7 +2175,7 @@
field: 'delay_up_to_timestamp',
title: 'Script Delay Run At',
titleTooltip: 'The date and time the script should be run, after hysteresis',
- formatter: function(value, row, index) { return timestamp4human(value, ' '); },
+ formatter: function(value, row, index) { void(row); void(index); return timestamp4human(value, ' '); },
align: 'center',
valign: 'middle',
visible: false,
@@ -2059,9 +2206,75 @@
});
}
+ function seconds4human(seconds, options) {
+ var default_options = {
+ now: 'now',
+ space: '&nbsp;',
+ negative_suffix: 'ago',
+ hour: 'hour',
+ hours: 'hours',
+ minute: 'minute',
+ minutes: 'minutes',
+ second: 'second',
+ seconds: 'seconds',
+ and: 'and'
+ };
+
+ if(typeof options !== 'object')
+ options = default_options;
+ else {
+ var x;
+ for(x in default_options) {
+ if(typeof options[x] !== 'string')
+ options[x] = default_options[x];
+ }
+ }
+
+ if(typeof seconds === 'string')
+ seconds = parseInt(seconds);
+
+ if(seconds === 0)
+ return options.now;
+
+ var suffix = '';
+ if(seconds < 0) {
+ seconds = -seconds;
+ if(options.negative_suffix !== '') suffix = options.space + options.negative_suffix;
+ }
+
+ var hours = Math.floor(seconds / 3600);
+ seconds -= (hours * 3600);
+
+ var minutes = Math.floor(seconds / 60);
+ seconds -= (minutes * 60);
+
+ var txt = '';
+
+ if(hours > 1) txt += hours.toString() + options.space + options.hours;
+ else if(hours === 1) txt += hours.toString() + options.space + options.hour;
+
+ if(hours > 0 && minutes > 0 && seconds == 0)
+ txt += options.space + options.and + options.space;
+ else if(hours > 0 && minutes > 0 && seconds > 0)
+ txt += ',' + options.space;
+
+ if(minutes > 1) txt += minutes.toString() + options.space + options.minutes;
+ else if(minutes === 1) txt += minutes.toString() + options.space + options.minute;
+
+ if((minutes > 0 || minutes > 0) && seconds > 0)
+ txt += options.space + options.and + options.space;
+
+ if(seconds > 1) txt += Math.floor(seconds).toString() + options.space + options.seconds;
+ else if(seconds === 1) txt += Math.floor(seconds).toString() + options.space + options.second;
+
+ return txt + suffix;
+ }
+
function alarmsCallback(data) {
var count = 0;
for(x in data.alarms) {
+ if(!data.alarms.hasOwnProperty(x)) continue;
+
var alarm = data.alarms[x];
if(alarm.status === 'WARNING' || alarm.status === 'CRITICAL')
count++;
@@ -2073,6 +2286,43 @@
document.getElementById('alarms_count_badge').innerHTML = '';
}
+ function initializeDynamicDashboardWithData(data) {
+ if(data !== null) {
+ options.hostname = data.hostname;
+ options.data = data;
+ options.version = data.version;
+ netdataDashboard.os = data.os;
+
+ if(typeof data.hosts != 'undefined')
+ options.hosts = data.hosts;
+
+ // update the dashboard hostname
+ document.getElementById('hostname').innerHTML = options.hostname;
+ document.getElementById('hostname').href = NETDATA.serverDefault;
+ document.getElementById('netdataVersion').innerHTML = options.version;
+
+ // update the dashboard title
+ document.title = options.hostname + ' netdata dashboard';
+
+ // close the splash screen
+ $("#loadOverlay").css("display","none");
+
+ // create a chart_by_name index
+ data.charts_by_name = {};
+ var charts = data.charts;
+ var x;
+ for(x in charts) {
+ if(!charts.hasOwnProperty(x)) continue;
+
+ var chart = charts[x];
+ data.charts_by_name[chart.name] = chart;
+ }
+
+ // render all charts
+ renderChartsAndMenu(data);
+ }
+ }
+
function initializeDynamicDashboard(netdata_url) {
if(typeof netdata_url === 'undefined' || netdata_url === null)
netdata_url = NETDATA.serverDefault;
@@ -2087,31 +2337,16 @@
// download all the charts the server knows
NETDATA.chartRegistry.downloadAll(netdata_url, function(data) {
- if(data !== null) {
- options.hostname = data.hostname;
- options.data = data;
-
- // update the dashboard hostname
- document.getElementById('hostname').innerHTML = options.hostname;
- document.getElementById('hostname').href = NETDATA.serverDefault;
-
- // update the dashboard title
- document.title = options.hostname + ' netdata dashboard';
-
- // close the splash screen
- $("#loadOverlay").css("display","none");
-
- // create a chart_by_name index
- data.charts_by_name = {};
- var charts = data.charts;
- var x;
- for(x in charts) {
- var chart = charts[x];
- data.charts_by_name[chart.name] = chart;
+ if(data != null) {
+ if(typeof data.custom_info !== 'undefined' && data.custom_info !== "") {
+ loadJs(data.custom_info, function () {
+ $.extend(true, netdataDashboard, customDashboard);
+ initializeDynamicDashboardWithData(data);
+ });
+ }
+ else {
+ initializeDynamicDashboardWithData(data);
}
-
- // render all charts
- renderChartsAndMenu(data);
}
});
});
@@ -2123,8 +2358,23 @@
document.getElementById('versionCheckLog').innerHTML = msg;
}
- function getNetdataVersion(callback) {
- versionLog('Downloading installed version info from netdata...');
+ function getNetdataCommitIdFromVersion() {
+ var s = options.version.split('-');
+
+ if(s.length !== 3) return null;
+ if(s[2][0] == 'g') {
+ var v = s[2].split('_')[0].substring(1, 8);
+ if(v.length === 7) {
+ versionLog('Installed git commit id of netdata is ' + v);
+ document.getElementById('netdataCommitId').innerHTML = v;
+ return v;
+ }
+ }
+ return null;
+ }
+
+ function getNetdataCommitId(force, callback) {
+ versionLog('Downloading installed git commit id from netdata...');
$.ajax({
url: 'version.txt',
@@ -2134,24 +2384,34 @@
})
.done(function(data) {
data = data.replace(/(\r\n|\n|\r| |\t)/gm,"");
- if(data.length !== 40) {
- versionLog('Received version string is invalid.');
- callback(null);
+
+ var c = getNetdataCommitIdFromVersion();
+ if(c !== null && data.length === 40 && data.substring(0, 7) !== c) {
+ versionLog('Installed files commit id and internal netdata git commit id do not match');
+ data = c;
}
- else {
- versionLog('Installed version of netdata is ' + data);
- document.getElementById('netdataVersion').innerHTML = data;
+
+ if(data.length >= 7) {
+ versionLog('Installed git commit id of netdata is ' + data);
+ document.getElementById('netdataCommitId').innerHTML = data.substring(0, 7);
callback(data);
}
})
.fail(function() {
- versionLog('Failed to download installed version info from netdata!');
- callback(null);
+ versionLog('Failed to download installed git commit id from netdata!');
+
+ if(force === true) {
+ var c = getNetdataCommitIdFromVersion();
+ if(c === null) versionLog('Cannot find the git commit id of netdata.');
+ callback(c);
+ }
+ else
+ callback(null);
});
}
function getGithubLatestCommit(callback) {
- versionLog('Downloading latest version info from github...');
+ versionLog('Downloading latest git commit id info from github...');
$.ajax({
url: 'https://api.github.com/repos/firehol/netdata/commits',
@@ -2159,17 +2419,17 @@
cache: false
})
.done(function(data) {
- versionLog('Latest version info from github is ' + data[0].sha);
+ versionLog('Latest git commit id from github is ' + data[0].sha);
callback(data[0].sha);
})
.fail(function() {
- versionLog('Failed to download installed version info from github!');
+ versionLog('Failed to download installed git commit id from github!');
callback(null);
});
}
- function checkForUpdate(callback) {
- getNetdataVersion(function(sha1) {
+ function checkForUpdate(force, callback) {
+ getNetdataCommitId(force, function(sha1) {
if(sha1 === null) callback(null, null);
getGithubLatestCommit(function(sha2) {
@@ -2199,26 +2459,26 @@
}
}
- checkForUpdate(function(sha1, sha2) {
+ checkForUpdate(force, function(sha1, sha2) {
var save = false;
if(sha1 === null) {
save = false;
- versionLog('<p><big>Failed to get your netdata version!</big></p><p>You can always get the latest version of netdata from <a href="https://github.com/firehol/netdata" target="_blank">its github page</a>.</p>');
+ versionLog('<p><big>Failed to get your netdata git commit id!</big></p><p>You can always get the latest netdata from <a href="https://github.com/firehol/netdata" target="_blank">its github page</a>.</p>');
}
else if(sha2 === null) {
save = false;
- versionLog('<p><big>Failed to get the latest version from github.</big></p><p>You can always get the latest version of netdata from <a href="https://github.com/firehol/netdata" target="_blank">its github page</a>.</p>');
+ versionLog('<p><big>Failed to get the latest git commit id from github.</big></p><p>You can always get the latest netdata from <a href="https://github.com/firehol/netdata" target="_blank">its github page</a>.</p>');
}
else if(sha1 === sha2) {
save = true;
- versionLog('<p><big>You already have the latest version of netdata!</big></p><p>No update yet?<br/>Probably, we need some motivation to keep going on!</p><p>If you haven\'t already, <a href="https://github.com/firehol/netdata" target="_blank">give netdata a <b>Star</b> at its github page</a>.</p>');
+ versionLog('<p><big>You already have the latest netdata!</big></p><p>No update yet?<br/>Probably, we need some motivation to keep going on!</p><p>If you haven\'t already, <a href="https://github.com/firehol/netdata" target="_blank">give netdata a <b>Star</b> at its github page</a>.</p>');
}
else {
save = true;
var compare = 'https://github.com/firehol/netdata/compare/' + sha1.toString() + '...' + sha2.toString();
- versionLog('<p><big><strong>New version of netdata available!</strong></big></p><p>Latest version: ' + sha2.toString() + '</p><p><a href="' + compare + '" target="_blank">Click here for the changes log</a> since your installed version, and<br/><a href="https://github.com/firehol/netdata/wiki/Updating-Netdata" target="_blank">click here for directions on updating</a> your netdata installation.</p><p>We suggest to review the changes log for new features you may be interested, or important bug fixes you may need.<br/>Keeping your netdata updated, is generally a good idea.</p>');
+ versionLog('<p><big><strong>New version of netdata available!</strong></big></p><p>Latest commit: <b><code>' + sha2.substring(0, 7).toString() + '</code></b></p><p><a href="' + compare + '" target="_blank">Click here for the changes log</a> since your installed version, and<br/><a href="https://github.com/firehol/netdata/wiki/Updating-Netdata" target="_blank">click here for directions on updating</a> your netdata installation.</p><p>We suggest to review the changes log for new features you may be interested, or important bug fixes you may need.<br/>Keeping your netdata updated, is generally a good idea.</p>');
document.getElementById('update_badge').innerHTML = '!';
}
@@ -2345,7 +2605,7 @@
{
//console.log('They were open tags');
//console.log(openTags);
- for (j = 0; j < openTags.length; j++) {
+ for (var j = 0; j < openTags.length; j++) {
//console.log('Cierro tag ' + openTags[j]);
bag += '</' + openTags[j] + '>'; // Close all tags that were opened
@@ -2391,8 +2651,9 @@
//console.log('hash = ' + urlOptions.hash);
}
+ var $sidebar = $('#sidebar');
/* activate bootstrap sidebar (affix) */
- $('#sidebar').affix({
+ $sidebar.affix({
offset: {
top: (isdemo())?150:0,
bottom: 0
@@ -2402,7 +2663,7 @@
/* fix scrolling of very long affix lists
http://stackoverflow.com/questions/21691585/bootstrap-3-1-0-affix-too-long
*/
- $('#sidebar').on('affixed.bs.affix', function() {
+ $sidebar.on('affixed.bs.affix', function() {
$(this).removeAttr('style');
});
@@ -2413,7 +2674,7 @@
});
// change the URL based on the current position of the screen
- $('#sidebar').on('activate.bs.scrollspy', function (e) {
+ $sidebar.on('activate.bs.scrollspy', function (e) {
// console.log(e);
var el = $(e.target);
//if(el.find('ul').size() == 0) {
@@ -2440,13 +2701,13 @@
// console.log('switching ' + option.toString());
self.bootstrapToggle(NETDATA.getOption(option)?'on':'off');
}
- }
+ };
var theme_sync_option = function(option) {
var self = $('#' + option);
self.bootstrapToggle(netdataTheme === 'slate'?'on':'off');
- }
+ };
sync_option('eliminate_zero_dimensions');
sync_option('destroy_on_hide');
@@ -2504,19 +2765,21 @@
netdataReload();
});
- $('#updateModal').on('show.bs.modal', function() {
+ var $updateModal = $('#updateModal');
+ $updateModal.on('show.bs.modal', function() {
versionLog('checking, please wait...');
});
- $('#updateModal').on('shown.bs.modal', function() {
+ $updateModal.on('shown.bs.modal', function() {
notifyForUpdate(true);
});
- $('#alarmsModal').on('shown.bs.modal', function() {
+ var $alarmsModal = $('#alarmsModal');
+ $alarmsModal.on('shown.bs.modal', function() {
NETDATA.pause(alarmsUpdateModal);
});
- $('#alarmsModal').on('hidden.bs.modal', function() {
+ $alarmsModal.on('hidden.bs.modal', function() {
NETDATA.unpause();
document.getElementById('alarms_active').innerHTML =
document.getElementById('alarms_all').innerHTML =
@@ -2632,7 +2895,7 @@
});
NETDATA.requiredJs.push({
- url: NETDATA.serverDefault + 'dashboard_info.js?v20170115-1',
+ url: NETDATA.serverDefault + 'dashboard_info.js?v20170308-1',
async: false,
isAlreadyLoaded: function() { return false; }
});
@@ -3144,7 +3407,8 @@
<h4 class="modal-title" id="updateModalLabel">Update Check</h4>
</div>
<div class="modal-body">
- Your netdata version: <b><code><span id="netdataVersion">Unknown</span></code></b>
+ Your netdata version: <b><code><span id="netdataVersion">Unknown</span></code></b><br/>
+ Your netdata commit: <b><code><span id="netdataCommitId">Unknown</span></code></b>
<br/>
<div style="padding: 10px;"></div>
<div id="versionCheckLog">Not checked yet. Please press the Check Now button.</div>
@@ -3259,4 +3523,4 @@
</div>
</body>
</html>
-<script type="text/javascript" src="dashboard.js?v20170118-11"></script>
+<script type="text/javascript" src="dashboard.js?v20170211-2"></script>