netdataShowHelp = true;
if(typeof netdataShowAlarms === 'undefined')
- netdataShowAlarms = true;
+ netdataShowAlarms = false;
NETDATA.colors = NETDATA.themes.current.colors;
NETDATA.parseDom(NETDATA.chartRefresher);
// Alarms initialization
- if(netdataShowAlarms === true)
- setTimeout(NETDATA.alarms.init, 1000);
+ setTimeout(NETDATA.alarms.init, 1000);
// Registry initialization
setTimeout(NETDATA.registry.init, 1500);
// Registry of netdata hosts
NETDATA.alarms = {
- server: null,
- current: null,
- callback: null,
+ notifications: false, // when true, the browser supports notifications (may not be granted though)
+ last_notification_id: 0, // the id of the last alarm_log we have raised an alarm for
+ notifications_shown: new Array(),
+
+ server: null, // the server to connect to for fetching alarms
+ current: null, // the list of raised alarms
+ notified: { alarms: {} }, // the list of raised alarms for which we have shown notifications
+
+ callback: null, // a callback function to call every time the list of raised alarms is refreshed
+
+ notify: function(entry) {
+ // console.log('alarm ' + entry.unique_id);
+
+ if(entry.updated === true) {
+ // console.log('alarm ' + entry.unique_id + ' has been updated by another alarm');
+ return;
+ }
+
+ var name = entry.name.replace(/_/g, ' ');
+ var title = name + ' = ' + ((entry.value === null)?'NaN':Math.floor(entry.value)).toString() + ' ' + entry.units;
+ var body = entry.info + ' of ' + entry.chart + ' (' + entry.family + ')';
+ var tag = entry.alarm_id;
+ var icon = 'images/seo-performance-128.png';
+ var interaction = false;
+ var data = entry;
+
+ switch(entry.status) {
+ case 'UNINITIALIZED':
+ // console.log('alarm ' + entry.unique_id + ' is UNINITIALIZED');
+ return;
+
+ case 'UNDEFINED':
+ // console.log('alarm ' + entry.unique_id + ' is UNDEFINED');
+ return;
+
+ case 'CLEAR':
+ if(NETDATA.alarms.last_notification_id === 0) {
+ // console.log('alarm ' + entry.unique_id + ' is not current');
+ return;
+ }
+ if(entry.old_status === 'UNINITIALIZED' || entry.old_status === 'UNDEFINED') {
+ // console.log('alarm' + entry.unique_id + ' switch to CLEAR from ' + entry.old_status);
+ return;
+ }
+ title = entry.name + ' back to normal';
+ icon = 'images/check-mark-2-128-green.png'
+ interaction = false;
+ break;
+
+ case 'WARNING':
+ icon = 'images/alert-128-orange.png';
+ interaction = false;
+ break;
+
+ case 'CRITICAL':
+ icon = 'images/alert-128-red.png'
+ interaction = true;
+ break;
+
+ default:
+ console.log('invalid alarm status ' + entry.status);
+ return;
+ }
+
+ // cleanup old notifications with the same alarm_id as this one
+ var len = NETDATA.alarms.notifications_shown.length;
+ while(len--) {
+ var n = NETDATA.alarms.notifications_shown[len];
+ if(n.data.alarm_id === entry.alarm_id) {
+ // console.log('removing old alarm ' + n.data.unique_id);
+
+ // close the notification
+ n.close.bind(n);
+
+ // remove it from the array
+ NETDATA.alarms.notifications_shown.splice(len, 1);
+ len = NETDATA.alarms.notifications_shown.length;
+ }
+ }
+
+ // show this notification
+ // console.log('new notification: ' + title);
+ var n = new Notification(title, {
+ body: body,
+ tag: tag,
+ requireInteraction: interaction,
+ icon: NETDATA.serverDefault + icon,
+ data: data
+ });
+
+ // console.log(n);
+ NETDATA.alarms.notifications_shown.push(n);
+ // console.log(entry);
+ },
+
+ notifyAll: function() {
+ NETDATA.alarms.notified = NETDATA.alarms.current;
+
+ // console.log('FETCHING ALARM LOG');
+ NETDATA.alarms.get_log(NETDATA.alarms.last_notification_id, function(data) {
+ // console.log('ALARM LOG FETCHED');
+
+ if(data === null || typeof data !== 'object') {
+ console.log('invalid alarms log response');
+ return;
+ }
+
+ if(data.length === 0) {
+ console.log('received empty alarm log');
+ return;
+ }
+
+ data.sort(function(a, b) {
+ if(a.unique_id > b.unique_id) return -1;
+ if(a.unique_id < b.unique_id) return 1;
+ return 0;
+ });
+
+ var len = data.length;
+ while(len--) {
+ if(data[len].unique_id > NETDATA.alarms.last_notification_id) {
+ NETDATA.alarms.notify(data[len]);
+ }
+ }
+
+ NETDATA.alarms.last_notification_id = data[0].unique_id;
+ })
+ },
+
+ check_notifications: function() {
+ // returns true if we should fire 1+ notifications
+
+ if(NETDATA.alarms.notifications !== true) {
+ // console.log('notifications not available');
+ return false;
+ }
+
+ if(Notification.permission !== 'granted') {
+ // console.log('notifications not granted');
+ return false;
+ }
+
+ if(typeof NETDATA.alarms.current !== 'undefined' && typeof NETDATA.alarms.current.alarms === 'object') {
+ // console.log('can do alarms');
+
+ var current = NETDATA.alarms.current.alarms;
+ var old = NETDATA.alarms.notified.alarms;
+ var x;
+
+ if(Object.keys(current).length !== Object.keys(old).length) {
+ // console.log('alarm count differs');
+ return true;
+ }
+ else {
+ for(x in current) {
+ if(!(x in old)) {
+ // console.log('new alarm detected: ' + x);
+ return true;
+ }
+
+ if(current[x].status !== old[x].status) {
+ // console.log('alarm changed state: ' + x);
+ return true;
+ }
+ }
+ }
+
+ //console.log('alarms did not change');
+ }
+ // else console.log('cannot process alarms');
+
+ return false;
+ },
get: function(what, callback) {
$.ajax({
update_forever: function() {
NETDATA.alarms.get('active', function(data) {
if(data !== null) {
- if('Notification' in window && NETDATA.alarms.current != null) {
- if(Object.keys(NETDATA.alarms.current.alarms).length < Object.keys(data.alarms).length) {
- if (Notification.permission === 'granted') {
- new Notification('Netdata Alarm!', {body: 'Your Server needs attention!',
- icon: 'images/seo-performance-128.png'});
- }
- }
- }
NETDATA.alarms.current = data;
+ if(NETDATA.alarms.check_notifications() === true) {
+ NETDATA.alarms.notifyAll();
+ }
+
if (typeof NETDATA.alarms.callback === 'function') {
NETDATA.alarms.callback(data);
}
});
},
- get_log: function(callback) {
+ get_log: function(last_id, callback) {
$.ajax({
- url: NETDATA.alarms.server + '/api/v1/alarm_log',
+ url: NETDATA.alarms.server + '/api/v1/alarm_log?after=' + last_id.toString(),
async: true,
cache: false,
xhrFields: { withCredentials: true } // required for the cookie
host = host.substring(0, host.length - 1);
NETDATA.alarms.server = host;
- NETDATA.alarms.update_forever();
- if ('Notification' in window && Notification.permission === 'default') {
- Notification.requestPermission();
+ if(netdataShowAlarms === true) {
+ NETDATA.alarms.update_forever();
+
+ if('Notification' in window) {
+ // console.log('notifications available');
+ NETDATA.alarms.notifications = true;
+
+ if(Notification.permission === 'default')
+ Notification.requestPermission();
+ }
}
}
};