From b4f64f72a3e4bf590c60b0cbd6cd365aa1a58542 Mon Sep 17 00:00:00 2001 From: Lennart Weller Date: Wed, 25 May 2016 12:36:24 +0200 Subject: Imported Upstream version 1.2.0 --- web/Makefile.am | 7 +- web/Makefile.in | 12 +- web/dashboard.css | 20 +- web/dashboard.html | 2 +- web/dashboard.js | 378 ++++++++++++++++++++++--- web/dashboard.slate.css | 20 +- web/demo.html | 84 +++--- web/demo2.html | 268 +++++++++--------- web/demosites.html | 721 ++++++++++++++++++++++++++++++++++++++++++++++++ web/index.html | 376 ++++++++++++++++++++++--- web/tv.html | 483 ++++++++++++++++---------------- web/version.txt | 2 +- 12 files changed, 1853 insertions(+), 520 deletions(-) create mode 100644 web/demosites.html (limited to 'web') diff --git a/web/Makefile.am b/web/Makefile.am index 1b6b918be..174ef229b 100644 --- a/web/Makefile.am +++ b/web/Makefile.am @@ -4,18 +4,19 @@ MAINTAINERCLEANFILES= $(srcdir)/Makefile.in dist_web_DATA = \ - robots.txt \ - index.html \ demo.html \ demo2.html \ - tv.html \ + demosites.html \ dashboard.html \ dashboard.js \ dashboard.css \ dashboard.slate.css \ favicon.ico \ + index.html \ netdata-swagger.yaml \ netdata-swagger.json \ + robots.txt \ + tv.html \ version.txt \ $(NULL) diff --git a/web/Makefile.in b/web/Makefile.in index 98d5dcc76..e95290128 100644 --- a/web/Makefile.in +++ b/web/Makefile.in @@ -188,6 +188,8 @@ OPTIONAL_MATH_CLFAGS = @OPTIONAL_MATH_CLFAGS@ OPTIONAL_MATH_LIBS = @OPTIONAL_MATH_LIBS@ OPTIONAL_NFACCT_CLFAGS = @OPTIONAL_NFACCT_CLFAGS@ OPTIONAL_NFACCT_LIBS = @OPTIONAL_NFACCT_LIBS@ +OPTIONAL_UUID_CLFAGS = @OPTIONAL_UUID_CLFAGS@ +OPTIONAL_UUID_LIBS = @OPTIONAL_UUID_LIBS@ OPTIONAL_ZLIB_CLFAGS = @OPTIONAL_ZLIB_CLFAGS@ OPTIONAL_ZLIB_LIBS = @OPTIONAL_ZLIB_LIBS@ PACKAGE = @PACKAGE@ @@ -209,6 +211,8 @@ PTHREAD_LIBS = @PTHREAD_LIBS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ @@ -269,6 +273,7 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ +varlibdir = @varlibdir@ webdir = @webdir@ # @@ -276,18 +281,19 @@ webdir = @webdir@ # MAINTAINERCLEANFILES = $(srcdir)/Makefile.in dist_web_DATA = \ - robots.txt \ - index.html \ demo.html \ demo2.html \ - tv.html \ + demosites.html \ dashboard.html \ dashboard.js \ dashboard.css \ dashboard.slate.css \ favicon.ico \ + index.html \ netdata-swagger.yaml \ netdata-swagger.json \ + robots.txt \ + tv.html \ version.txt \ $(NULL) diff --git a/web/dashboard.css b/web/dashboard.css index a7b090d66..63e2b905f 100644 --- a/web/dashboard.css +++ b/web/dashboard.css @@ -10,11 +10,22 @@ body { margin-left: 55px; } +.netdata-chart-row { + width: 100%; + text-align: center; + display: flex; + display: -webkit-flex; + display: -moz-flex; + align-items: baseline; + -moz-align-items: baseline; + -webkit-align-items: baseline; + justify-content: center; + -webkit-justify-content: center; + -moz-justify-content: center; +} + .netdata-container { - display: -webkit-flex; /* Safari */ - -webkit-flex-wrap: wrap; /* Safari 6.1+ */ display: inline-block; - flex-wrap: wrap; overflow: hidden; /* required for child elements to have absolute position */ @@ -31,10 +42,7 @@ body { } .netdata-container-with-legend { - display: -webkit-flex; /* Safari */ - -webkit-flex-wrap: wrap; /* Safari 6.1+ */ display: inline-block; - flex-wrap: wrap; overflow: hidden; /* fix minimum scrollbar issue in firefox */ diff --git a/web/dashboard.html b/web/dashboard.html index fd505078d..2b6c80684 100644 --- a/web/dashboard.html +++ b/web/dashboard.html @@ -646,4 +646,4 @@ So, to avoid flashing the charts, we destroy and re-create the charts on each up - + diff --git a/web/dashboard.js b/web/dashboard.js index b6c62ae3c..27847a243 100644 --- a/web/dashboard.js +++ b/web/dashboard.js @@ -12,6 +12,9 @@ // var netdataNoBootstrap = true; // do not load bootstrap // var netdataDontStart = true; // do not start the thread to process the charts // var netdataErrorCallback = null; // Callback function that will be invoked upon error +// var netdataNoRegistry = true; // Don't update the registry for this access +// var netdataRegistryCallback = null; // Callback function that will be invoked with one param, +// the URLs from the registry // // You can also set the default netdata server, using the following. // When this variable is not set, we assume the page is hosted on your @@ -19,8 +22,28 @@ // var netdataServer = "http://yourhost:19999"; // set your NetData server //(function(window, document, undefined) { + + // ------------------------------------------------------------------------ + // compatibility fixes + // fix IE issue with console - if(!window.console){ window.console = {log: function(){} }; } + if(!window.console) { window.console = { log: function(){} }; } + + // if string.endsWith is not defined, define it + if(typeof String.prototype.endsWith !== 'function') { + String.prototype.endsWith = function(s) { + if(s.length > this.length) return false; + return this.slice(-s.length) === s; + }; + } + + // if string.startsWith is not defined, define it + if(typeof String.prototype.startsWith !== 'function') { + String.prototype.startsWith = function(s) { + if(s.length > this.length) return false; + return this.slice(s.length) === s; + }; + } // global namespace var NETDATA = window.NETDATA || {}; @@ -53,7 +76,11 @@ NETDATA.serverDefault = netdataServer; else { var s = NETDATA._scriptSource(); - NETDATA.serverDefault = s.replace(/\/dashboard.js(\?.*)*$/g, ""); + if(s) NETDATA.serverDefault = s.replace(/\/dashboard.js(\?.*)*$/g, ""); + else { + console.log('WARNING: Cannot detect the URL of the netdata server.'); + NETDATA.serverDefault = null; + } } if(NETDATA.serverDefault === null) @@ -80,7 +107,7 @@ NETDATA.google_js = 'https://www.google.com/jsapi'; NETDATA.themes = { - default: { + white: { bootstrap_css: NETDATA.serverDefault + 'css/bootstrap.min.css', dashboard_css: NETDATA.serverDefault + 'dashboard.css', background: '#FFFFFF', @@ -95,7 +122,7 @@ easypiechart_scale: '#dfe0e0', gauge_pointer: '#C0C0C0', gauge_stroke: '#F0F0F0', - gauge_gradient: true + gauge_gradient: false }, slate: { bootstrap_css: NETDATA.serverDefault + 'css/bootstrap.slate.min.css', @@ -124,7 +151,7 @@ if(typeof netdataTheme !== 'undefined' && typeof NETDATA.themes[netdataTheme] !== 'undefined') NETDATA.themes.current = NETDATA.themes[netdataTheme]; else - NETDATA.themes.current = NETDATA.themes.default; + NETDATA.themes.current = NETDATA.themes.white; NETDATA.colors = NETDATA.themes.current.colors; @@ -188,8 +215,6 @@ last_resized: new Date().getTime(), // the timestamp of the last resize request - crossDomainAjax: false, // enable this to request crossDomain AJAX - last_page_scroll: 0, // the timestamp the last time the page was scrolled // the current profile @@ -284,6 +309,12 @@ } }; + NETDATA.statistics = { + refreshes_total: 0, + refreshes_active: 0, + refreshes_active_max: 0 + }; + // ---------------------------------------------------------------------------------------------------------------- // local storage options @@ -461,7 +492,15 @@ 403: { message: "Chart library not enabled/is failed", alert: false }, 404: { message: "Chart not found", alert: false }, 405: { message: "Cannot download charts index from server", alert: true }, - 406: { message: "Invalid charts index downloaded from server", alert: true } + 406: { message: "Invalid charts index downloaded from server", alert: true }, + 407: { message: "Cannot HELLO netdata server", alert: false }, + 408: { message: "Netdata servers sent invalid response to HELLO", alert: false }, + 409: { message: "Cannot ACCESS netdata registry", alert: false }, + 410: { message: "Netdata registry ACCESS failed", alert: false }, + 411: { message: "Netdata registry server send invalid response to DELETE ", alert: false }, + 412: { message: "Netdata registry DELETE failed", alert: false }, + 413: { message: "Netdata registry server send invalid response to SWITCH ", alert: false }, + 414: { message: "Netdata registry SWITCH failed", alert: false } }; NETDATA.errorLast = { code: 0, @@ -541,7 +580,6 @@ $.ajax({ url: host + '/api/v1/charts', - crossDomain: NETDATA.options.crossDomainAjax, async: true, cache: false }) @@ -975,6 +1013,7 @@ this.units = self.data('units') || null; // the units of the chart dimensions this.append_options = self.data('append-options') || null; // the units of the chart dimensions + this.running = false; // boolean - true when the chart is being refreshed now this.validated = false; // boolean - has the chart been validated? this.enabled = true; // boolean - is the chart enabled for refresh? this.paused = false; // boolean - is the chart paused for any reason? @@ -1098,7 +1137,7 @@ var w = that.element.offsetWidth; if(w === null || w === 0) { // the div is hidden - // this is resize the chart when next viewed + // this will resize the chart when next viewed that.tm.last_resized = 0; } else @@ -1167,7 +1206,7 @@ var lost = Math.max(h * 0.2, 5); h -= lost; - // center the text, verically + // center the text, vertically var paddingTop = (lost - 5) / 2; // but check the width too @@ -1247,8 +1286,8 @@ if(isHidden() === true) return; if(that.chart_created === true) { - // we should destroy it if(NETDATA.options.current.destroy_on_hide === true) { + // we should destroy it init(); } else { @@ -1256,6 +1295,12 @@ that.element_chart.style.display = 'none'; if(that.element_legend !== null) that.element_legend.style.display = 'none'; that.tm.last_hidden = new Date().getTime(); + + // de-allocate data + // This works, but I not sure there are no corner cases somewhere + // so it is commented - if the user has memory issues he can + // set Destroy on Hide for all charts + // that.data = null; } } @@ -2580,8 +2625,6 @@ if(this.debug === true) this.log('updateChartWithData() called.'); - this._updating = false; - // this may force the chart to be re-created resizeChart(); @@ -2676,8 +2719,8 @@ if(NETDATA.globalPanAndZoom.isActive()) this.tm.last_autorefreshed = 0; else { - if(NETDATA.options.current.parallel_refresher === true && NETDATA.options.current.concurrent_refreshes) - this.tm.last_autorefreshed = Math.round(now / this.data_update_every) * this.data_update_every; + if(NETDATA.options.current.parallel_refresher === true && NETDATA.options.current.concurrent_refreshes === true) + this.tm.last_autorefreshed = now - (now % this.data_update_every); else this.tm.last_autorefreshed = now; } @@ -2739,11 +2782,16 @@ if(this.debug === true) this.log('updating from ' + this.data_url); + NETDATA.statistics.refreshes_total++; + NETDATA.statistics.refreshes_active++; + + if(NETDATA.statistics.refreshes_active > NETDATA.statistics.refreshes_active_max) + NETDATA.statistics.refreshes_active_max = NETDATA.statistics.refreshes_active; + this._updating = true; this.xhr = $.ajax( { url: this.data_url, - crossDomain: NETDATA.options.crossDomainAjax, cache: false, async: true }) @@ -2757,6 +2805,7 @@ error('data download failed for url: ' + that.data_url); }) .always(function() { + NETDATA.statistics.refreshes_active--; that._updating = false; if(typeof callback === 'function') callback(); }); @@ -2813,13 +2862,20 @@ } }; - this.isAutoRefreshed = function() { + this.isAutoRefreshable = function() { return (this.current.autorefresh); }; this.canBeAutoRefreshed = function() { var now = new Date().getTime(); + if(this.running === true) { + if(this.debug === true) + this.log('I am already running'); + + return false; + } + if(this.enabled === false) { if(this.debug === true) this.log('I am not enabled'); @@ -2850,7 +2906,7 @@ return true; } - if(this.isAutoRefreshed() === true) { + if(this.isAutoRefreshable() === true) { // allow the first update, even if the page is not visible if(this.updates_counter && this.updates_since_last_unhide && NETDATA.options.page_is_visible === false) { if(NETDATA.options.debug.focus === true || this.debug === true) @@ -2910,8 +2966,16 @@ }; this.autoRefresh = function(callback) { - if(this.canBeAutoRefreshed() === true) { - this.updateChart(callback); + if(this.canBeAutoRefreshed() === true && this.running === false) { + var state = this; + + state.running = true; + state.updateChart(function() { + state.running = false; + + if(typeof callback !== 'undefined') + callback(); + }); } else { if(typeof callback !== 'undefined') @@ -2948,7 +3012,6 @@ $.ajax( { url: this.host + this.chart_url, - crossDomain: NETDATA.options.crossDomainAjax, cache: false, async: true }) @@ -3234,11 +3297,12 @@ var parallel = new Array(); var targets = NETDATA.options.targets; var len = targets.length; + var state; while(len--) { - if(targets[len].isVisible() === false) + state = targets[len]; + if(state.isVisible() === false || state.running === true) continue; - var state = targets[len]; if(state.library.initialized === false) { if(state.library.enabled === true) { state.library.initialize(NETDATA.chartRefresher); @@ -3253,24 +3317,15 @@ } if(parallel.length > 0) { - var parallel_jobs = parallel.length; - // this will execute the jobs in parallel $(parallel).each(function() { - this.autoRefresh(function() { - parallel_jobs--; - - if(parallel_jobs === 0) { - setTimeout(NETDATA.chartRefresher, - NETDATA.chartRefresherWaitTime()); - } - }); + this.autoRefresh(); }) } - else { - setTimeout(NETDATA.chartRefresher, - NETDATA.chartRefresherWaitTime()); - } + + // run the next refresh iteration + setTimeout(NETDATA.chartRefresher, + NETDATA.chartRefresherWaitTime()); }; NETDATA.parseDom = function(callback) { @@ -3330,7 +3385,14 @@ $('.modal').on('hidden.bs.modal', NETDATA.onscroll); $('.modal').on('shown.bs.modal', NETDATA.onscroll); + // bootstrap collapse switching + $('.collapse').on('hidden.bs.collapse', NETDATA.onscroll); + $('.collapse').on('shown.bs.collapse', NETDATA.onscroll); + NETDATA.parseDom(NETDATA.chartRefresher); + + // Registry initialization + setTimeout(NETDATA.registry.init, 3000); }; // ---------------------------------------------------------------------------------------------------------------- @@ -4623,7 +4685,7 @@ state.easyPieChartEvent.timer = null; } - if(state.isAutoRefreshed() === true && state.data !== null) { + if(state.isAutoRefreshable() === true && state.data !== null) { NETDATA.easypiechartChartUpdate(state, state.data); } else { @@ -4674,7 +4736,7 @@ NETDATA.easypiechartChartUpdate = function(state, data) { var value, max, pcent; - if(NETDATA.globalPanAndZoom.isActive() === true || state.isAutoRefreshed() === false) { + if(NETDATA.globalPanAndZoom.isActive() === true || state.isAutoRefreshable() === false) { value = null; max = 0; pcent = 0; @@ -4877,7 +4939,7 @@ state.gaugeEvent.timer = null; } - if(state.isAutoRefreshed() === true && state.data !== null) { + if(state.isAutoRefreshable() === true && state.data !== null) { NETDATA.gaugeChartUpdate(state, state.data); } else { @@ -4931,7 +4993,7 @@ NETDATA.gaugeChartUpdate = function(state, data) { var value, min, max; - if(NETDATA.globalPanAndZoom.isActive() === true || state.isAutoRefreshed() === false) { + if(NETDATA.globalPanAndZoom.isActive() === true || state.isAutoRefreshable() === false) { value = 0; min = 0; max = 1; @@ -4993,11 +5055,33 @@ colorStop: stopColor, // just experiment with them strokeColor: strokeColor, // to see which ones work best for you limitMax: true, - generateGradient: generateGradient, + generateGradient: (generateGradient === true)?true:false, gradientType: 0 }; - if(generateGradient === false && NETDATA.themes.current.gauge_gradient === true) { + if (generateGradient.constructor === Array) { + // example options: + // data-gauge-generate-gradient="[0, 50, 100]" + // data-gauge-gradient-percent-color-0="#FFFFFF" + // data-gauge-gradient-percent-color-50="#999900" + // data-gauge-gradient-percent-color-100="#000000" + + options.percentColors = new Array(); + var len = generateGradient.length; + while(len--) { + var pcent = generateGradient[len]; + var color = self.data('gauge-gradient-percent-color-' + pcent.toString()) || false; + if(color !== false) { + var a = new Array(); + a[0] = pcent / 100; + a[1] = color; + options.percentColors.unshift(a); + } + } + if(options.percentColors.length === 0) + delete options.percentColors; + } + else if(generateGradient === false && NETDATA.themes.current.gauge_gradient === true) { options.percentColors = [ [0.0, NETDATA.colorLuminance(startColor, (lum_d * 10) - (lum_d * 0))], [0.1, NETDATA.colorLuminance(startColor, (lum_d * 10) - (lum_d * 1))], @@ -5304,12 +5388,13 @@ }; // ---------------------------------------------------------------------------------------------------------------- - // Start up + // Load required JS libraries and CSS NETDATA.requiredJs = [ { url: NETDATA.serverDefault + 'lib/bootstrap.min.js', isAlreadyLoaded: function() { + // check if bootstrap is loaded if(typeof $().emulateTransitionEnd == 'function') return true; else { @@ -5401,11 +5486,214 @@ NETDATA.loadRequiredCSS(++index); }; + + // ---------------------------------------------------------------------------------------------------------------- + // Registry of netdata hosts + + NETDATA.registry = { + server: null, // the netdata registry server + person_guid: null, // the unique ID of this browser / user + machine_guid: null, // the unique ID the netdata server that served dashboard.js + hostname: null, // the hostname of the netdata server that served dashboard.js + urls: null, // the user's other URLs + urls_array: null, // the user's other URLs in an array + + parsePersonUrls: function(person_urls) { + // console.log(person_urls); + + if(person_urls) { + NETDATA.registry.urls = {}; + NETDATA.registry.urls_array = new Array(); + + var now = new Date().getTime(); + var apu = person_urls; + var i = apu.length; + while(i--) { + if(typeof NETDATA.registry.urls[apu[i][0]] === 'undefined') { + // console.log('adding: ' + apu[i][4] + ', ' + ((now - apu[i][2]) / 1000).toString()); + + var obj = { + guid: apu[i][0], + url: apu[i][1], + last_t: apu[i][2], + accesses: apu[i][3], + name: apu[i][4], + alternate_urls: new Array() + }; + + NETDATA.registry.urls[apu[i][0]] = obj; + NETDATA.registry.urls_array.push(obj); + } + else { + // console.log('appending: ' + apu[i][4] + ', ' + ((now - apu[i][2]) / 1000).toString()); + + var pu = NETDATA.registry.urls[apu[i][0]]; + if(pu.last_t < apu[i][2]) { + pu.url = apu[i][1]; + pu.last_t = apu[i][2]; + pu.name = apu[i][4]; + } + pu.accesses += apu[i][3]; + pu.alternate_urls.push(apu[i][1]); + } + } + } + + if(typeof netdataRegistryCallback === 'function') + netdataRegistryCallback(NETDATA.registry.urls_array); + }, + + init: function() { + if(typeof netdataNoRegistry !== 'undefined' && netdataNoRegistry) + return; + + NETDATA.registry.hello(NETDATA.serverDefault, function(data) { + if(data) { + NETDATA.registry.server = data.registry; + NETDATA.registry.machine_guid = data.machine_guid; + NETDATA.registry.hostname = data.hostname; + + NETDATA.registry.access(10, function (person_urls) { + NETDATA.registry.parsePersonUrls(person_urls); + + }); + } + }); + }, + + hello: function(host, callback) { + // send HELLO to a netdata server: + // 1. verifies the server is reachable + // 2. responds with the registry URL, the machine GUID of this netdata server and its hostname + $.ajax({ + url: host + '/api/v1/registry?action=hello', + async: true, + cache: false, + xhrFields: { withCredentials: true } // required for the cookie + }) + .done(function(data) { + if(typeof data.status !== 'string' || data.status !== 'ok') { + NETDATA.error(408, host + ' response: ' + JSON.stringify(data)); + data = null; + } + + if(typeof callback === 'function') + callback(data); + }) + .fail(function() { + NETDATA.error(407, host); + + if(typeof callback === 'function') + callback(null); + }); + }, + + access: function(max_redirects, callback) { + // send ACCESS to a netdata registry: + // 1. it lets it know we are accessing a netdata server (its machine GUID and its URL) + // 2. it responds with a list of netdata servers we know + // the registry identifies us using a cookie it sets the first time we access it + // the registry may respond with a redirect URL to send us to another registry + $.ajax({ + url: NETDATA.registry.server + '/api/v1/registry?action=access&machine=' + NETDATA.registry.machine_guid + '&name=' + encodeURIComponent(NETDATA.registry.hostname) + '&url=' + encodeURIComponent(NETDATA.serverDefault), // + '&visible_url=' + encodeURIComponent(document.location), + async: true, + cache: false, + xhrFields: { withCredentials: true } // required for the cookie + }) + .done(function(data) { + var redirect = null; + if(typeof data.registry === 'string') + redirect = data.registry; + + if(typeof data.status !== 'string' || data.status !== 'ok') { + NETDATA.error(409, NETDATA.registry.server + ' responded with: ' + JSON.stringify(data)); + data = null; + } + + if(data === null && redirect !== null && max_redirects > 0) { + NETDATA.registry.server = redirect; + NETDATA.registry.access(max_redirects - 1, callback); + } + else { + if(typeof data.person_guid === 'string') + NETDATA.registry.person_guid = data.person_guid; + + if(typeof callback === 'function') + callback(data.urls); + } + }) + .fail(function() { + NETDATA.error(410, NETDATA.registry.server); + + if(typeof callback === 'function') + callback(null); + }); + }, + + delete: function(delete_url, callback) { + // send DELETE to a netdata registry: + $.ajax({ + url: NETDATA.registry.server + '/api/v1/registry?action=delete&machine=' + NETDATA.registry.machine_guid + '&name=' + encodeURIComponent(NETDATA.registry.hostname) + '&url=' + encodeURIComponent(NETDATA.serverDefault) + '&delete_url=' + encodeURIComponent(delete_url), + async: true, + cache: false, + xhrFields: { withCredentials: true } // required for the cookie + }) + .done(function(data) { + if(typeof data.status !== 'string' || data.status !== 'ok') { + NETDATA.error(411, NETDATA.registry.server + ' responded with: ' + JSON.stringify(data)); + data = null; + } + + if(typeof callback === 'function') + callback(data); + }) + .fail(function() { + NETDATA.error(412, NETDATA.registry.server); + + if(typeof callback === 'function') + callback(null); + }); + }, + + switch: function(new_person_guid, callback) { + // impersonate + $.ajax({ + url: NETDATA.registry.server + '/api/v1/registry?action=switch&machine=' + NETDATA.registry.machine_guid + '&name=' + encodeURIComponent(NETDATA.registry.hostname) + '&url=' + encodeURIComponent(NETDATA.serverDefault) + '&to=' + new_person_guid, + async: true, + cache: false, + xhrFields: { withCredentials: true } // required for the cookie + }) + .done(function(data) { + if(typeof data.status !== 'string' || data.status !== 'ok') { + NETDATA.error(413, NETDATA.registry.server + ' responded with: ' + JSON.stringify(data)); + data = null; + } + + if(typeof callback === 'function') + callback(data); + }) + .fail(function() { + NETDATA.error(414, NETDATA.registry.server); + + if(typeof callback === 'function') + callback(null); + }); + } + }; + + // ---------------------------------------------------------------------------------------------------------------- + // Boot it! + NETDATA.errorReset(); NETDATA.loadRequiredCSS(0); NETDATA._loadjQuery(function() { NETDATA.loadRequiredJs(0, function() { + if(typeof $().emulateTransitionEnd !== 'function') { + // bootstrap is not available + NETDATA.options.current.show_help = false; + } + if(typeof netdataDontStart === 'undefined' || !netdataDontStart) { if(NETDATA.options.debug.main_loop === true) console.log('starting chart refresh thread'); diff --git a/web/dashboard.slate.css b/web/dashboard.slate.css index 662731061..0536a3ed6 100644 --- a/web/dashboard.slate.css +++ b/web/dashboard.slate.css @@ -18,11 +18,22 @@ body { margin-left: 55px; } +.netdata-chart-row { + width: 100%; + text-align: center; + display: flex; + display: -webkit-flex; + display: -moz-flex; + align-items: flex-end; + -moz-align-items: flex-end; + -webkit-align-items: flex-end; + justify-content: center; + -moz--webkit-justify-content: center; + -moz-justify-content: center; +} + .netdata-container { - display: -webkit-flex; /* Safari */ - -webkit-flex-wrap: wrap; /* Safari 6.1+ */ display: inline-block; - flex-wrap: wrap; overflow: hidden; /* required for child elements to have absolute position */ @@ -39,10 +50,7 @@ body { } .netdata-container-with-legend { - display: -webkit-flex; /* Safari */ - -webkit-flex-wrap: wrap; /* Safari 6.1+ */ display: inline-block; - flex-wrap: wrap; overflow: hidden; /* fix minimum scrollbar issue in firefox */ diff --git a/web/demo.html b/web/demo.html index 8a6c0c129..4b91d8394 100644 --- a/web/demo.html +++ b/web/demo.html @@ -1,42 +1,42 @@ - - - - NetData Dashboard - - - - - - - - - - - - - -
-
-
-
-
- - + + + + NetData Dashboard + + + + + + + + + + + + + +
+
+
+
+
+ + diff --git a/web/demo2.html b/web/demo2.html index 7a8d75a54..9530d914e 100644 --- a/web/demo2.html +++ b/web/demo2.html @@ -1,134 +1,134 @@ - - - - NetData Dashboard - - - - - - - - - - - - - - -
-
why netdata?
-
-
These charts visualize the same data...
- - - - - - -
-
- -
-
I can trace an issue like this
-
-
-
-
-
Can you trace an issue like these?
 
-
-
-
-
-
- -
-
I can trace an issue like this
-
-
-
-
-
Can you trace an issue like these?
 
-
-
-
-
-
-
Hover on the chart below, to see the selected value on the charts above!
-
-
- - + + + + NetData Dashboard + + + + + + + + + + + + + + +
+
why netdata?
+
+
These charts visualize the same data...
+ + + + + + +
+
+ +
+
I can trace an issue like this
+
+
+
+
+
Can you trace an issue like these?
 
+
+
+
+
+
+ +
+
I can trace an issue like this
+
+
+
+
+
Can you trace an issue like these?
 
+
+
+
+
+
+
Hover on the chart below, to see the selected value on the charts above!
+
+
+ + diff --git a/web/demosites.html b/web/demosites.html new file mode 100644 index 000000000..f5047f4b2 --- /dev/null +++ b/web/demosites.html @@ -0,0 +1,721 @@ + + + + NetData - Real-time performance monitoring, done right! + + + + + + + + + + + + + + + + + + + + + +
+ +
+ netdata +
+
+ real-time performance monitoring +
+
+ scaled out! +
+
+ pick a netdata demo server +
+
+ these demo servers show what you will get by installing netdata +
+ +
+
+ +
+
+
+
+
+
 
+ +
+ Donated by DigitalOcean.com +
+
+
+
+
+
+
+
+
 
+ +
+ Donated by CDN77.com +
+
+
+
+
+
+
+
+
 
+ +
+   +
+
+
+
+
+ +
+ this page is a custom netdata dashboard +
+
+ charts are coming from 3 servers, in parallel +
+ the servers are not aware of this multi-server dashboard, +
+ each server is not aware of the other 2 servers, +
+ but on this dashboard they are one! +
+
+ + hover on a chart below, or drag it to show the past - the others will follow! +
+ double click on a chart to reset them all +
+ +
+ our ngnix performance +
+
+ (we proxy netdata through nginx, on the demo sites) +
+ + + + + +
+
+
+
+ EU - London web requests/s +
+
+
+
+
+ +
+
+ US - Atlanta web requests/s +
+
+
+
+
+ +
+
+ EU - Greece web requests/s +
+
+
+
+
+
+ +
+
+
+ EU - London active connections +
+
+
+
+
+ +
+
+ US - Atlanta active connections +
+
+
+
+
+ +
+
+ EU - Greece active connections +
+
+
+
+
+
+
+ +
+ these charts are draggable and touchable, double click them to reset them +
+ + +
+ bandwidth consumption on the demo sites +
+
+ Linux QoS is configured by FireQOS +
+ + + + + +
+
+
+
+
+ +
+
+ +
+ +
+
+
+
+
+
+
+ +
+ +
+
+ +
+ +
+
+
+
+
+
+ these legends are interactive and the charts are resizable here ^^^ +
+ +
+ DDoS protection performance on the demo sites +
+
+ iptables SYNPROXY configured by FireHOL +
+ +
+ +
+
+ EU - London, TCP SYN packets/s received +
+
+
+
+
+ +
+
+ US - Atlanta, TCP SYN packets/s received +
+
+
+
+
+ +
+
+ EU - Greece, TCP SYN packets/s received +
+
+
+
+
+
+
+ did you notice the decimal numbers? +
netdata interpolates collected values at second boundaries, with nanosecond detail!
+
+ + +
+ CPU Utilization of the demo sites +
+ +
+
+
+
+ +
+
+
+ +
+
+
+
+
+ what is using so much CPU? +
The site iplists.firehol.org is maintained by FireHOL - the CPU is used for comparing security IP Lists.
+
+ +
+ CPU Usage of the netdata user +
+
+ netdata monitors users, user groups, applications (process trees) +
+ and containers (lxc, docker, etc.) +
+ +
+ +
+
+ EU - London, CPU % of a single core +
+
+
+
+
+ +
+
+ US - Atlanta, CPU % of a single core +
+
+
+
+
+ +
+
+ EU - Greece, CPU % of a single core +
+
+
+
+
+
+
+ this utilization is about the whole netdata process tree and the percentage is of a single core! +
including BASH plugins (it monitors mysql on the demo sites), node.js plugins (it monitors bind9 on the demo sites), etc. +
and including the chart refreshes for the dashboards of all viewers.
+
+ +
+ want to know more? +
+ jump to the netdata page at github +
+ it needs just 3 mins to be installed on your servers! +
+   +
+
+ + + diff --git a/web/index.html b/web/index.html index 6f6013da1..9cc2b4bbe 100644 --- a/web/index.html +++ b/web/index.html @@ -191,6 +191,42 @@ font-weight: 500; } + .dropdown-menu { + min-width: 200px; + } + .dropdown-menu.columns-2 { + margin: 0; + padding: 0; + width: 400px; + } + .dropdown-menu li a { + padding: 5px 15px; + font-weight: 300; + } + .dropdown-menu.multi-column { + overflow-x: hidden; + } + .multi-column-dropdown { + list-style: none; + padding: 0; + } + .multi-column-dropdown li a { + display: block; + clear: both; + line-height: 1.428571429; + white-space: normal; + } + .multi-column-dropdown li a:hover { + text-decoration: none; + color: #f5f5f5; + background-color: #262626; + } + .scrollable-menu { + height: auto; + max-height: 80vh; + overflow-x: hidden; + } + /* Back to top (hidden on mobile) */ .back-to-top, .dashboard-theme-toggle { @@ -320,6 +356,7 @@ else return ret; } + var netdataTheme = getTheme('slate'); function setTheme(theme) { @@ -327,15 +364,94 @@ return saveLocalStorage('netdataTheme', theme); } + + var netdataRegistryCallback = function(urls_array) { + var el = ''; + var a1 = ''; + var found = 0; + + if(urls_array) { + function name_comparator_desc(a, b) { + if (a.name > b.name) return -1; + if (a.name < b.name) return 1; + return 0; + } + + var urls = urls_array.sort(name_comparator_desc); + var len = urls.length; + while(len--) { + var u = urls[len]; + + var status = "enabled"; + found++; + + if(u.guid === NETDATA.registry.machine_guid) + status = "disabled" + + el += '
  • ' + u.name + '
  • '; + a1 += '
  • '; + } + } + + if(!found) { + if(urls) + el += '
  • your netdata server list is empty...
  • '; + else + el += '
  • failed to contact the registry...
  • '; + + a1 += '
  •  
  • '; + + el += '' + + '
  • EU - London (DigitalOcean.com)
  • ' + + '
  • US - Atlanta (CDN77.com)
  • ' + + '
  • EU - Athens
  • '; + a1 += '' + + '
  •  
  • ' + + '
  •  
  • '+ + '
  •  
  • '; + } + + el += ''; + a1 += ''; + + el += '
  • What is this?
  • '; + a1 += '
  • ' + + document.getElementById('mynetdata_servers').innerHTML = el; + document.getElementById('mynetdata_servers2').innerHTML = el; + document.getElementById('mynetdata_actions1').innerHTML = a1; + }; + - + @@ -456,9 +584,6 @@ D3, Copyright 2015, Mike Bostock, BSD License - node-int64, - Copyright 2014, Robert Kieffer, MIT License - @@ -775,16 +900,86 @@ - - - - - - - - - - - -
    - - PLEASE RESPECT OUR DEMO SITE RESOURCES - DON'T PUT THIS AS-IS ON TV - CLOSE IT WHEN YOU DON'T NEED IT ! - - -
    -
    - CPU On both servers -
    -
    -
    -
    -
    -
    -
    - - -
    -
    - Disk I/O on both servers -
    -
    -
    -
    -
    -
    - - -
    -
    - IPv4 traffic on both servers -
    -
    -
    -
    -
    -
    - -
    -
    - Netdata statistics on both servers -
    -
    -
    - netdata.firehol.org -
    -
    -
    -
    -
    -
    -
    - your netdata server -
    -
    -
    -
    -
    -
    -
    -
    -
    - - + + + + NetData TV Dashboard + + + + + + + + + + + + + + + + + + + +
    + +
    +
    + CPU On both servers +
    +
    +
    +
    +
    +
    +
    + + +
    +
    + Disk I/O on both servers +
    +
    +
    +
    +
    +
    + + +
    +
    + IPv4 traffic on both servers +
    +
    +
    +
    +
    +
    + +
    +
    + Netdata statistics on both servers +
    +
    +
    + netdata.firehol.org +
    +
    +
    +
    +
    +
    +
    + your netdata server +
    +
    +
    +
    +
    +
    +
    +
    +
    + + diff --git a/web/version.txt b/web/version.txt index 9aef34725..afce0e539 100644 --- a/web/version.txt +++ b/web/version.txt @@ -1 +1 @@ -39c196708756fc8f85bfc70c931836479be3b9c2 +bb4aa949f5ac825253d8adc6070661299abc1c3b -- cgit v1.2.3