From: Costa Tsaousis Date: Tue, 31 May 2016 06:34:06 +0000 (+0300) Subject: Merge pull request #468 from ktsaou/master X-Git-Tag: v1.3.0~183 X-Git-Url: https://arthur.barton.de/gitweb/?a=commitdiff_plain;h=1f7a68fb4aec58088cd66267b263a0d421c5b3f1;hp=fdb2a27096338679cca4a664b1070080c7737575;p=netdata.git Merge pull request #468 from ktsaou/master fixed memory leak in web client handling --- diff --git a/charts.d/mysql.chart.sh b/charts.d/mysql.chart.sh index 56dce42d..4fcbe7b1 100755 --- a/charts.d/mysql.chart.sh +++ b/charts.d/mysql.chart.sh @@ -200,7 +200,7 @@ mysql_check() { if [ ${#mysql_opts[@]} -eq 0 ] then - if [ ${unconfigured} -eq 1 && ${tryroot} -eq 0 ] + if [ ${unconfigured} -eq 1 -a ${tryroot} -eq 0 ] then mysql_check tryroot "${@}" return $? diff --git a/src/web_client.c b/src/web_client.c index b4e07ff4..a6831870 100644 --- a/src/web_client.c +++ b/src/web_client.c @@ -240,6 +240,12 @@ struct web_client *web_client_free(struct web_client *w) debug(D_WEB_CLIENT_ACCESS, "%llu: Closing web client from %s port %s.", w->id, w->client_ip, w->client_port); +#ifdef NETDATA_WITH_ZLIB + if(w->response.zinitialized) { + deflateEnd(&w->response.zstream); + } +#endif // NETDATA_WITH_ZLIB + if(w->prev) w->prev->next = w->next; if(w->next) w->next->prev = w->prev; if(w->response.header_output) buffer_free(w->response.header_output); diff --git a/system/Makefile.am b/system/Makefile.am index f16a720e..b2e49c5a 100644 --- a/system/Makefile.am +++ b/system/Makefile.am @@ -7,6 +7,7 @@ CLEANFILES = \ netdata.logrotate \ netdata.service \ netdata-init-d \ + netdata-lsb \ $(NULL) include $(top_srcdir)/build/subst.inc @@ -18,6 +19,7 @@ nodist_noinst_DATA = \ netdata.logrotate \ netdata.service \ netdata-init-d \ + netdata-lsb \ $(NULL) dist_noinst_DATA = \ @@ -25,5 +27,6 @@ dist_noinst_DATA = \ netdata.logrotate.in \ netdata.service.in \ netdata-init-d.in \ + netdata-lsb.in \ netdata.conf \ $(NULL) diff --git a/system/netdata-init-d.in b/system/netdata-init-d.in old mode 100755 new mode 100644 index 07d5a19e..d72dd2e5 --- a/system/netdata-init-d.in +++ b/system/netdata-init-d.in @@ -1,8 +1,8 @@ #!/bin/sh # -# netdata Real-time charts for system monitoring +# netdata Real-time performance monitoring, done right # chkconfig: 345 99 01 -# description: Netdata is a daemon that collects data in realtime (per second) +# description: Netdata is a daemon that collects data in real-time (per second) # and presents a web site to view and analyze them. The presentation # is also real-time and full of interactive charts that precisely # render all collected values. diff --git a/system/netdata-lsb.in b/system/netdata-lsb.in new file mode 100644 index 00000000..d8165977 --- /dev/null +++ b/system/netdata-lsb.in @@ -0,0 +1,100 @@ +#!/bin/bash +# +### BEGIN INIT INFO +# Provides: netdata +# Required-Start: $local_fs $remote_fs $network $named $time apache2 httpd squid nginx mysql named opensips upsd hostapd postfix lm_sensors +# Required-Stop: $local_fs $remote_fs $network $named $time apache2 httpd squid nginx mysql named opensips upsd hostapd postfix lm_sensors +# Should-Start: $local_fs $network $named $remote_fs $time $all +# Should-Stop: $local_fs $network $named $remote_fs $time $all +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Start and stop the netdata real-time monitoring server daemon +# Description: Controls the main netdata monitoring server daemon "netdata". +# and all its plugins. +### END INIT INFO +# +set -e +set -u +${DEBIAN_SCRIPT_DEBUG:+ set -v -x} + +DAEMON="netdata" +DAEMON_PATH=@sbindir_POST@ +PIDFILE=@localstatedir_POST@/$DAEMON.pid +DAEMONOPTS="-P $PIDFILE" + +test -x $DAEMON_PATH/$DAEMON || exit 0 + +. /lib/lsb/init-functions + +# Safeguard (relative paths, core dumps..) +cd / +umask 022 + +service_start() { + log_daemon_msg "Starting real-time performance monitoring" "netdata" + start_daemon -p $PIDFILE $DAEMON_PATH/$DAEMON $DAEMONOPTS + RETVAL=$? + log_end_msg $RETVAL + return $RETVAL +} + +service_stop() { + log_daemon_msg "Stopping real-time performance monitoring" "netdata" + killproc -p ${PIDFILE} $DAEMON_PATH/$DAEMON + RETVAL=$? + log_end_msg $RETVAL + + if [ $RETVAL -eq 0 ]; then + rm -f ${PIDFILE} + fi + return $RETVAL +} + +condrestart() { + if ! service_status > /dev/null; then + RETVAL=$1 + return + fi + + service_stop + service_start +} + +service_status() { + status_of_proc -p $PIDFILE $DAEMON_PATH/$DAEMON netdata +} + + +# +# main() +# + +case "${1:-''}" in + 'start') + service_start + ;; + + 'stop') + service_stop + ;; + + 'restart') + service_stop + service_start + ;; + + 'try-restart') + condrestart 0 + ;; + + 'force-reload') + condrestart 7 + ;; + + 'status') + service_status && exit 0 || exit $? + ;; + *) + echo "Usage: $0 {start|stop|restart|try-restart|force-reload|status}" + exit 1 +esac diff --git a/system/netdata-openrc.in b/system/netdata-openrc.in old mode 100755 new mode 100644 diff --git a/system/netdata.service.in b/system/netdata.service.in index 91db6122..5a119553 100644 --- a/system/netdata.service.in +++ b/system/netdata.service.in @@ -1,5 +1,5 @@ [Unit] -Description=Linux real time system monitoring, over the web +Description=Linux real time system monitoring, done right After=network.target httpd.service squid.service nfs-server.service mysqld.service named.service postfix.service [Service] diff --git a/web/dashboard.css b/web/dashboard.css index 63e2b905..eb2ed1b0 100644 --- a/web/dashboard.css +++ b/web/dashboard.css @@ -6,6 +6,19 @@ body { font-variant: normal; } +.morelink { + color: #765d9c; + text-decoration: none; +} +.morelink:hover { + color: #563d7c; + text-decoration: none; +} +.morelink:focus { + color: #765d9c; + text-decoration: none; +} + .netdata-chart-alignment { margin-left: 55px; } diff --git a/web/dashboard.slate.css b/web/dashboard.slate.css index 0536a3ed..9223958a 100644 --- a/web/dashboard.slate.css +++ b/web/dashboard.slate.css @@ -14,6 +14,19 @@ body { border-left: 2px solid #765d9c; } +.morelink { + color: #765d9c; + text-decoration: none; +} +.morelink:hover { + color: #563d7c; + text-decoration: none; +} +.morelink:focus { + color: #765d9c; + text-decoration: none; +} + .netdata-chart-alignment { margin-left: 55px; } diff --git a/web/index.html b/web/index.html index d79ede3c..803ba047 100644 --- a/web/index.html +++ b/web/index.html @@ -1341,6 +1341,46 @@ var submenuData = { }; var chartData = { + 'mysql.net': { + info: 'The amount of data sent to mysql clients (out) and received from mysql clients (in).' + }, + + 'mysql.queries': { + info: 'The number of statements executed by the server.' + }, + + 'mysql.handlers': { + info: 'Usage of the internal handlers of mysql. This chart provides very good insights of what the mysql server is actually doing.' + + ' (if the chart is not showing all these dimensions it is because they are zero - set Which dimensions to show? to All from the dashboard settings, to render even the zero values)' + }, + + 'mysql.table_locks': { + info: 'MySQL table locks counters: ' + }, + 'system.cpu': { info: 'Total CPU utilization (all cores). 100% here means there is no CPU idle time at all. You can get per core usage at the CPUs section and per application usage at the Applications Monitoring section.
Keep an eye on iowait ' + sparkline('system.cpu', 'iowait', '%') + '. If it is constantly high, your disks are a bottleneck and they slow your system down.
Another important metric worth monitoring, is softirq ' + sparkline('system.cpu', 'softirq', '%') + '. A constantly high percentage of softirq may indicate network drivers issues.' }, @@ -2218,6 +2258,141 @@ function finalizePage() { NETDATA.globalPanAndZoom.setMaster(NETDATA.options.targets[0], after, before); } + // ------------------------------------------------------------------------ + // https://github.com/viralpatel/jquery.shorten/blob/master/src/jquery.shorten.js + $.fn.shorten = function(settings) { + "use strict"; + + var config = { + showChars: 750, + minHideChars: 10, + ellipsesText: "...", + moreText: ' show more information', + lessText: ' show less information', + onLess: function() { NETDATA.onscroll(); }, + onMore: function() { NETDATA.onscroll(); }, + errMsg: null, + force: false + }; + + if (settings) { + $.extend(config, settings); + } + + if ($(this).data('jquery.shorten') && !config.force) { + return false; + } + $(this).data('jquery.shorten', true); + + $(document).off("click", '.morelink'); + + $(document).on({ + click: function() { + + var $this = $(this); + if ($this.hasClass('less')) { + $this.removeClass('less'); + $this.html(config.moreText); + $this.parent().prev().animate({'height':'0'+'%'}, 0, function () { $this.parent().prev().prev().show(); }).hide(0, function() { + config.onLess(); + }); + + } else { + $this.addClass('less'); + $this.html(config.lessText); + $this.parent().prev().animate({'height':'100'+'%'}, 0, function () { $this.parent().prev().prev().hide(); }).show(0, function() { + config.onMore(); + }); + } + return false; + } + }, '.morelink'); + + return this.each(function() { + var $this = $(this); + + var content = $this.html(); + var contentlen = $this.text().length; + if (contentlen > config.showChars + config.minHideChars) { + var c = content.substr(0, config.showChars); + if (c.indexOf('<') >= 0) // If there's HTML don't want to cut it + { + var inTag = false; // I'm in a tag? + var bag = ''; // Put the characters to be shown here + var countChars = 0; // Current bag size + var openTags = []; // Stack for opened tags, so I can close them later + var tagName = null; + + for (var i = 0, r = 0; r <= config.showChars; i++) { + if (content[i] == '<' && !inTag) { + inTag = true; + + // This could be "tag" or "/tag" + tagName = content.substring(i + 1, content.indexOf('>', i)); + + // If its a closing tag + if (tagName[0] == '/') { + + + if (tagName != '/' + openTags[0]) { + config.errMsg = 'ERROR en HTML: the top of the stack should be the tag that closes'; + } else { + openTags.shift(); // Pops the last tag from the open tag stack (the tag is closed in the retult HTML!) + } + + } else { + // There are some nasty tags that don't have a close tag like
+ if (tagName.toLowerCase() != 'br') { + openTags.unshift(tagName); // Add to start the name of the tag that opens + } + } + } + if (inTag && content[i] == '>') { + inTag = false; + } + + if (inTag) { bag += content.charAt(i); } // Add tag name chars to the result + else { + r++; + if (countChars <= config.showChars) { + bag += content.charAt(i); // Fix to ie 7 not allowing you to reference string characters using the [] + countChars++; + } else // Now I have the characters needed + { + if (openTags.length > 0) // I have unclosed tags + { + //console.log('They were open tags'); + //console.log(openTags); + for (j = 0; j < openTags.length; j++) { + //console.log('Cierro tag ' + openTags[j]); + bag += ''; // Close all tags that were opened + + // You could shift the tag from the stack to check if you end with an empty stack, that means you have closed all open tags + } + break; + } + } + } + } + c = $('
').html(bag + '' + config.ellipsesText + '').html(); + }else{ + c+=config.ellipsesText; + } + + var html = '
' + c + + '
' + content + + '
' + config.moreText + ''; + + $this.html(html); + $this.find(".allcontent").hide(); // Hide all text + $('.shortcontent p:last', $this).css('margin-bottom', 0); //Remove bottom margin on last paragraph as it's likely shortened + } + }); + + }; + $(".chart-message").shorten(); + // ------------------------------------------------------------------------ + // let it run (update the charts) NETDATA.unpause();