From 6c751d34c3e0ebc9cb5fb0a6648b02e46cd920a2 Mon Sep 17 00:00:00 2001 From: "Costa Tsaousis (ktsaou)" Date: Sat, 16 Jan 2016 04:26:37 +0200 Subject: [PATCH] minor modification for clean exit; dashboard fixes for inheriting chart colors on gauge and easypiechart; added demo2.html --- src/common.c | 5 +- src/plugin_nfacct.c | 2 + src/plugin_proc.c | 4 ++ src/plugin_tc.c | 4 +- src/plugins_d.c | 8 +-- web/Makefile.am | 1 + web/dashboard.html | 14 +++--- web/dashboard.js | 117 +++++++++++++++++++++++++------------------- web/demo2.html | 97 ++++++++++++++++++++++++++++++++++++ web/index.html | 8 --- 10 files changed, 189 insertions(+), 71 deletions(-) create mode 100755 web/demo2.html diff --git a/src/common.c b/src/common.c index bde93500..e3c3afe3 100755 --- a/src/common.c +++ b/src/common.c @@ -146,8 +146,11 @@ void *mymmap(const char *filename, size_t size, int flags, int ksm) error("Cannot seek to beginning of file '%s'.", filename); // don't use MADV_SEQUENTIAL|MADV_DONTFORK, they disable MADV_MERGEABLE + if(madvise(mem, size, MADV_SEQUENTIAL|MADV_DONTFORK) != 0) + error("Cannot advise the kernel about the memory usage (MADV_SEQUENTIAL|MADV_DONTFORK) of file '%s'.", filename); + if(madvise(mem, size, MADV_MERGEABLE) != 0) - error("Cannot advise the kernel about the memory usage of file '%s'.", filename); + error("Cannot advise the kernel about the memory usage (MADV_MERGEABLE) of file '%s'.", filename); } else error("Cannot allocate PRIVATE ANONYMOUS memory for KSM for file '%s'.", filename); diff --git a/src/plugin_nfacct.c b/src/plugin_nfacct.c index c088069a..8c613c4c 100644 --- a/src/plugin_nfacct.c +++ b/src/plugin_nfacct.c @@ -119,6 +119,8 @@ void *nfacct_main(void *ptr) { // ------------------------------------------------------------------------ while(1) { + if(unlikely(netdata_exit)) break; + seq++; nlh = nfacct_nlmsg_build_hdr(buf, NFNL_MSG_ACCT_GET, NLM_F_DUMP, seq); diff --git a/src/plugin_proc.c b/src/plugin_proc.c index 6a9d47bc..7f79364e 100755 --- a/src/plugin_proc.c +++ b/src/plugin_proc.c @@ -13,6 +13,7 @@ #include "log.h" #include "rrd.h" #include "plugin_proc.h" +#include "main.h" void *proc_main(void *ptr) { @@ -59,6 +60,7 @@ void *proc_main(void *ptr) unsigned long long usec = 0, susec = 0; for(;1;) { + if(unlikely(netdata_exit)) break; // BEGIN -- the job to be done @@ -129,6 +131,8 @@ void *proc_main(void *ptr) // END -- the job is done + if(unlikely(netdata_exit)) break; + // find the time to sleep in order to wait exactly update_every seconds gettimeofday(&now, NULL); usec = usecdiff(&now, &last) - susec; diff --git a/src/plugin_tc.c b/src/plugin_tc.c index ae6f4ad1..15b8077c 100755 --- a/src/plugin_tc.c +++ b/src/plugin_tc.c @@ -509,6 +509,8 @@ void *tc_main(void *ptr) uint32_t first_hash; for(;1;) { + if(unlikely(netdata_exit)) break; + FILE *fp; struct tc_device *device = NULL; struct tc_class *class = NULL; @@ -523,7 +525,7 @@ void *tc_main(void *ptr) } while(fgets(buffer, TC_LINE_MAX, fp) != NULL) { - if(netdata_exit) break; + if(unlikely(netdata_exit)) break; buffer[TC_LINE_MAX] = '\0'; // debug(D_TC_LOOP, "TC: read '%s'", buffer); diff --git a/src/plugins_d.c b/src/plugins_d.c index ef43ab1a..767ca27c 100755 --- a/src/plugins_d.c +++ b/src/plugins_d.c @@ -125,6 +125,8 @@ void *pluginsd_worker_thread(void *arg) #endif while(likely(1)) { + if(unlikely(netdata_exit)) break; + FILE *fp = mypopen(cd->cmd, &cd->pid); if(unlikely(!fp)) { error("Cannot popen(\"%s\", \"r\").", cd->cmd); @@ -139,7 +141,7 @@ void *pluginsd_worker_thread(void *arg) uint32_t hash; while(likely(fgets(line, PLUGINSD_LINE_MAX, fp) != NULL)) { - if(netdata_exit) break; + if(unlikely(netdata_exit)) break; line[PLUGINSD_LINE_MAX] = '\0'; @@ -439,7 +441,7 @@ void *pluginsd_main(void *ptr) if(scan_frequency < 1) scan_frequency = 1; while(likely(1)) { - if(netdata_exit) break; + if(unlikely(netdata_exit)) break; dir = opendir(dir_name); if(unlikely(!dir)) { @@ -448,7 +450,7 @@ void *pluginsd_main(void *ptr) } while(likely((file = readdir(dir)))) { - if(netdata_exit) break; + if(unlikely(netdata_exit)) break; debug(D_PLUGINSD, "PLUGINSD: Examining file '%s'", file->d_name); diff --git a/web/Makefile.am b/web/Makefile.am index 1010dbdf..9bd67cdf 100644 --- a/web/Makefile.am +++ b/web/Makefile.am @@ -7,6 +7,7 @@ dist_web_DATA = \ robots.txt \ index.html \ demo.html \ + demo2.html \ dashboard.html \ dashboard.js \ dashboard.css \ diff --git a/web/dashboard.html b/web/dashboard.html index 82f8128c..8b8a6990 100755 --- a/web/dashboard.html +++ b/web/dashboard.html @@ -598,7 +598,7 @@ C3 charts are not usable in large scale. They suffer from the following issues:
  • lack of a raw data format, so every time a chart is updated, data convertion in javascript is required
  • lack of stacked charts support
  • -So, we avoid flashing the charts, here we destroy and re-create the charts on each update. Also, since they manipulate the data with javascript we were forced to lower the detail they render to get acceptable results. +So, to avoid flashing the charts, we destroy and re-create the charts on each update. Also, since they manipulate the data with javascript we were forced to lower the detail they render to get acceptable speeds.

    - rendered in X ms + rendered in X ms

    - rendered in X ms + rendered in X ms

    - rendered in X ms + rendered in X ms
    diff --git a/web/dashboard.js b/web/dashboard.js index aa114a37..066613e6 100755 --- a/web/dashboard.js +++ b/web/dashboard.js @@ -216,6 +216,8 @@ smooth_plot: true, // enable smooth plot, where possible + charts_selection_animation_delay: 50, // delay to animate charts when syncing selection + color_fill_opacity_line: 1.0, color_fill_opacity_area: 0.2, color_fill_opacity_stacked: 0.8, @@ -1886,7 +1888,7 @@ } var show_undefined = true; - if(Math.abs(this.data.last_entry - this.data.before) <= this.data.view_update_every) + if(Math.abs(this.netdata_last - this.view_before) <= this.data_update_every) show_undefined = false; if(show_undefined) { @@ -1894,7 +1896,7 @@ return; } - this.legendSetDate(this.data.before * 1000); + this.legendSetDate(this.view_before); var labels = this.data.dimension_names; var i = labels.length; @@ -1944,17 +1946,24 @@ this.colors = new Array(); this.colors_available = new Array(); - // this.colors_assigned = {}; var c = $(this.element).data('colors'); + // this.log('read colors: ' + c); if(typeof c !== 'undefined' && c !== null) { if(typeof c !== 'string') { this.log('invalid color given: ' + c + ' (give a space separated list of colors)'); } else { c = c.split(' '); - for(var i = 0, len = c.length; i < len ; i++) - this.colors_available.push(c[i]); + var added = 0; + + while(added < 20) { + for(var i = 0, len = c.length; i < len ; i++) { + added++; + this.colors_available.push(c[i]); + // this.log('adding color: ' + c[i]); + } + } } } @@ -1996,9 +2005,9 @@ // do we have to update the current values? // we do this, only when the visible chart is current - if(Math.abs(this.data.last_entry - this.data.before) <= this.data.view_update_every) { + if(Math.abs(this.netdata_last - this.view_before) <= this.data_update_every) { if(this.debug === true) - this.log('chart in running... updating values on legend...'); + this.log('chart is in latest position... updating values on legend...'); //var labels = this.data.dimension_names; //var i = labels.length; @@ -2015,6 +2024,7 @@ this._chartDimensionColor(this.chart.dimensions[dim].name); } // we will re-generate the colors for the chart + // based on the selected dimensions this.colors = null; if(this.debug === true) @@ -2332,12 +2342,12 @@ if(NETDATA.options.current.pan_and_zoom_data_padding === true && this.requested_padding !== null) { if(this.view_after < this.data_after) { - console.log('adusting view_after from ' + this.view_after + ' to ' + this.data_after); + // console.log('adusting view_after from ' + this.view_after + ' to ' + this.data_after); this.view_after = this.data_after; } if(this.view_before > this.data_before) { - console.log('adusting view_before from ' + this.view_before + ' to ' + this.data_before); + // console.log('adusting view_before from ' + this.view_before + ' to ' + this.data_before); this.view_before = this.data_before; } } @@ -3273,14 +3283,14 @@ } return true; - } + }; NETDATA.dygraphClearSelection = function(state, t) { if(typeof state.dygraph_instance !== 'undefined') { state.dygraph_instance.clearSelection(); } return true; - } + }; NETDATA.dygraphSmoothInitialize = function(callback) { $.ajax({ @@ -3521,14 +3531,11 @@ if(NETDATA.options.debug.dygraph === true) state.log('dygraphDrawCallback()'); - var first = state.data.first_entry * 1000; - var last = state.data.last_entry * 1000; - var x_range = dygraph.xAxisRange(); var after = Math.round(x_range[0]); var before = Math.round(x_range[1]); - if(before <= last && after >= first) + if(before <= state.netdata_last && after >= state.netdata_first) state.updateChartPanOrZoom(after, before); } }, @@ -3739,8 +3746,8 @@ var after = new_x_range[0]; var before = new_x_range[1]; - var first = (state.data.first_entry + state.data.view_update_every) * 1000; - var last = (state.data.last_entry + state.data.view_update_every) * 1000; + var first = state.netdata_first + state.data_update_every; + var last = state.netdata_last + state.data_update_every; if(before > last) { after -= (before - last); @@ -4319,10 +4326,10 @@ }; NETDATA.easypiechartSetSelection = function(state, t) { - if(t < state.data_after || t > state.data_before) + if(state.timeIsVisible(t) !== true) return NETDATA.easypiechartClearSelection(state); - var slot = Math.floor(state.data.result.length - 1 - (t - state.data_after) / state.data_update_every); + var slot = state.calculateRowForTime(t); if(slot < 0 || slot >= state.data.result.length) return NETDATA.easypiechartClearSelection(state); @@ -4334,7 +4341,7 @@ }; } - var value = state.data.result[slot]; + var value = state.data.result[state.data.result.length - 1 - slot]; var max = (state.easyPieChartMax === null)?state.data.max:state.easyPieChartMax; var pcent = NETDATA.percentFromValueMax(value, max); @@ -4348,7 +4355,7 @@ state.easyPieChartEvent.timer = setTimeout(function() { state.easyPieChartEvent.timer = null; state.easyPieChart_instance.update(state.easyPieChartEvent.pcent); - }, 100); + }, NETDATA.options.current.charts_selection_animation_delay); } return true; @@ -4507,26 +4514,25 @@ if(typeof max !== 'number') max = 0; if(value > max) max = value; if(value < min) min = value; + if(min > max) { + var t = min; + min = max; + max = t; + } + else if(min == max) + max = min + 1; - var dvalue = state.gauge_instance.displayedValue; + // gauge.js has an issue if the needle + // is smaller than min or larger than max + // when we set the new values + // the needle will go crazy - if(dvalue >= min && dvalue <= max) { - state.gauge_instance.minValue = min; - state.gauge_instance.maxValue = max; - state.gauge_instance.set(value); - } - else { - // the current display value of the gauge - // is outside min-max. - // we have to disable animation - // otherwise, the gauge will go crazy - var old_speed = state.___gaugeOld__.speed; - NETDATA.gaugeAnimation(state, false); - state.gauge_instance.minValue = min; - state.gauge_instance.maxValue = max; - state.gauge_instance.set(value); - NETDATA.gaugeAnimation(state, old_speed); - } + // to prevent it, we always feed it + // with a percentage, so that the needle + // is always between min and max + var pcent = (value - min) * 100 / (max - min); + + state.gauge_instance.set(pcent); state.___gaugeOld__.value = value; state.___gaugeOld__.min = min; @@ -4570,10 +4576,10 @@ }; NETDATA.gaugeSetSelection = function(state, t) { - if(t < state.data_after || t > state.data_before) + if(state.timeIsVisible(t) !== true) return NETDATA.gaugeClearSelection(state); - var slot = Math.floor(state.data.result.length - 1 - (t - state.data_after) / state.data_update_every); + var slot = state.calculateRowForTime(t); if(slot < 0 || slot >= state.data.result.length) return NETDATA.gaugeClearSelection(state); @@ -4586,7 +4592,7 @@ }; } - var value = state.data.result[slot]; + var value = state.data.result[state.data.result.length - 1 - slot]; var max = (state.gaugeMax === null)?state.data.max:state.gaugeMax; var min = 0; @@ -4601,7 +4607,7 @@ state.gaugeEvent.timer = setTimeout(function() { state.gaugeEvent.timer = null; NETDATA.gaugeSet(state, state.gaugeEvent.value, state.gaugeEvent.min, state.gaugeEvent.max); - }, 100); + }, NETDATA.options.current.charts_selection_animation_delay); } return true; @@ -4635,7 +4641,12 @@ var value = data.result[0]; var max = self.data('gauge-max-value') || null; var adjust = self.data('gauge-adjust') || null; - + var pointerColor = self.data('gauge-pointer-color') || '#C0C0C0'; + var strokeColor = self.data('gauge-stroke-color') || '#F0F0F0'; + var startColor = self.data('gauge-start-color') || state.chartColors()[0]; + var stopColor = self.data('gauge-stop-color') || void 0; + var generateGradient = self.data('gauge-generate-gradient') || false; + if(max === null) { max = data.max; state.gaugeMax = null; @@ -4661,13 +4672,13 @@ pointer: { length: 0.8, // 0.9 The radius of the inner circle strokeWidth: 0.035, // The rotation offset - color: '#C0C0C0' // Fill color + color: pointerColor // Fill color }, - colorStart: state.chartColors()[0], // Colors - colorStop: void 0, // just experiment with them - strokeColor: '#F0F0F0', // to see which ones work best for you + colorStart: startColor, // Colors + colorStop: stopColor, // just experiment with them + strokeColor: strokeColor, // to see which ones work best for you limitMax: true, - generateGradient: false, + generateGradient: generateGradient, gradientType: 0, percentColors: [ [0.0, NETDATA.colorLuminance(state.chartColors()[0], (lum_d * 10) - (lum_d * 0))], @@ -4742,6 +4753,10 @@ maxLabel: null }; + // we will always feed a percentage + state.gauge_instance.minValue = 0; + state.gauge_instance.maxValue = 100; + NETDATA.gaugeAnimation(state, animate); NETDATA.gaugeSet(state, value, 0, max); NETDATA.gaugeSetLabels(state, value, 0, max); @@ -4927,7 +4942,7 @@ legend: function(state) { return null; }, autoresize: function(state) { return false; }, max_updates_to_recreate: function(state) { return 5000; }, - track_colors: function(state) { return false; }, + track_colors: function(state) { return true; }, pixels_per_point: function(state) { return 3; }, aspect_ratio: 100 }, @@ -4945,7 +4960,7 @@ legend: function(state) { return null; }, autoresize: function(state) { return false; }, max_updates_to_recreate: function(state) { return 5000; }, - track_colors: function(state) { return false; }, + track_colors: function(state) { return true; }, pixels_per_point: function(state) { return 3; }, aspect_ratio: 70 } diff --git a/web/demo2.html b/web/demo2.html new file mode 100755 index 00000000..8c3a202e --- /dev/null +++ b/web/demo2.html @@ -0,0 +1,97 @@ + + + + NetData Dashboard + + + + + + + + + + + + + + + +
    +
    why netdata?
    +
    +
    These charts update the same data...
    +
    +
    +
    +
    +
    Hover on the peaks and the lows of the chart below, to see the diff on the charts above!
    +
    +
    + + diff --git a/web/index.html b/web/index.html index daafdaeb..8887b7a4 100755 --- a/web/index.html +++ b/web/index.html @@ -979,7 +979,6 @@ function prepareScreen(data) { + ' data-before="0"' + ' data-after="-' + duration.toString() + '"' + ' data-points="' + duration.toString() + '"' - + ' data-colors="' + NETDATA.colors[0] + '"' + ' role="application">'; head += '
    '; break; @@ -1063,7 +1061,6 @@ function prepareScreen(data) { + ' data-before="0"' + ' data-after="-' + duration.toString() + '"' + ' data-points="' + duration.toString() + '"' - + ' data-colors="' + NETDATA.colors[0] + '"' + ' role="application">'; head += '
    '; break; case 'disk_backlog': c = '#DD4477'; break; @@ -1159,7 +1155,6 @@ function prepareScreen(data) { + ' data-before="0"' + ' data-after="-' + duration.toString() + '"' + ' data-points="' + duration.toString() + '"' - + ' data-colors="' + NETDATA.colors[0] + '"' + ' role="application">'; head += '
    '; } @@ -1197,7 +1191,6 @@ function prepareScreen(data) { + ' data-before="0"' + ' data-after="-' + duration.toString() + '"' + ' data-points="' + duration.toString() + '"' - + ' data-colors="' + NETDATA.colors[0] + '"' + ' role="application">'; head += '
    '; } -- 2.39.2