]> arthur.barton.de Git - netdata.git/commitdiff
Merge pull request #468 from ktsaou/master
authorCosta Tsaousis <costa@tsaousis.gr>
Tue, 31 May 2016 06:34:06 +0000 (09:34 +0300)
committerCosta Tsaousis <costa@tsaousis.gr>
Tue, 31 May 2016 06:34:06 +0000 (09:34 +0300)
fixed memory leak in web client handling

charts.d/mysql.chart.sh
src/web_client.c
system/Makefile.am
system/netdata-init-d.in [changed mode: 0755->0644]
system/netdata-lsb.in [new file with mode: 0644]
system/netdata-openrc.in [changed mode: 0755->0644]
system/netdata.service.in
web/dashboard.css
web/dashboard.slate.css
web/index.html

index 56dce42d74bb9bd3cb96e7cde467ecd9fa800103..4fcbe7b1c79dc185ebde28d01819e4c100f96eb5 100755 (executable)
@@ -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 $?
index b4e07ff48e7e33dba0802d9c6f0299d6d8c48040..a6831870d8ad4b65545dab74171f1a600557bc5c 100644 (file)
@@ -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);
index f16a720e2d2bdbfe4ff8179a121a3afe657b5e0f..b2e49c5af0f096faf7ab6dab1dbd6ceffc3c5094 100644 (file)
@@ -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)
old mode 100755 (executable)
new mode 100644 (file)
index 07d5a19..d72dd2e
@@ -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 (file)
index 0000000..d816597
--- /dev/null
@@ -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
old mode 100755 (executable)
new mode 100644 (file)
index 91db6122d8c6a0f8d2ede7f43bdc7c92ebf62aaa..5a119553cb2c804390693288540697c0e3bd9feb 100644 (file)
@@ -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]
index 63e2b905fdb9a5a10743ab3a1cfa7297773a61b1..eb2ed1b0d97c5c5698e986895491ed12dae905b3 100644 (file)
@@ -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;
 }
index 0536a3ed68c8f680f3088e883df47b5c99edad09..9223958ae7a9b095301c9d903a34f6e847d1b36a 100644 (file)
@@ -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;
 }
index d79ede3c4757c2303ea89a6e6f6aeb4586a0f941..803ba04703d29f6ba8c1f87b111d3f92e477f97e 100644 (file)
@@ -1341,6 +1341,46 @@ var submenuData = {
 };
 
 var chartData = {
+       'mysql.net': {
+               info: 'The amount of data sent to mysql clients (<strong>out</strong>) and received from mysql clients (<strong>in</strong>).'
+       },
+
+       'mysql.queries': {
+               info: 'The number of statements executed by the server.<ul>' +
+               '<li><strong>queries</strong> counts the statements executed within stored SQL programs.</li>' +
+               '<li><strong>questions</strong> counts the statements sent to the mysql server by mysql clients.</li>' +
+               '<li><strong>slow queries</strong> counts the number of statements that took more than <a href="http://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_long_query_time" target="_blank">long_query_time</a> seconds to be executed.' +
+               ' For more information about slow queries check the mysql <a href="http://dev.mysql.com/doc/refman/5.7/en/slow-query-log.html" target="_blank">slow query log</a>.</li>' +
+               '</ul>'
+       },
+
+       '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 <strong>Which dimensions to show?</strong> to <strong>All</strong> from the dashboard settings, to render even the zero values)<ul>' +
+               '<li><strong>commit</strong>, the number of internal <a href="http://dev.mysql.com/doc/refman/5.7/en/commit.html" target="_blank">COMMIT</a> statements.</li>' +
+               '<li><strong>delete</strong>, the number of times that rows have been deleted from tables.</li>' +
+               '<li><strong>prepare</strong>, a counter for the prepare phase of two-phase commit operations.</li>' +
+               '<li><strong>read first</strong>, the number of times the first entry in an index was read. A high value suggests that the server is doing a lot of full index scans; e.g. <strong>SELECT col1 FROM foo</strong>, with col1 indexed.</li>' +
+               '<li><strong>read key</strong>, the number of requests to read a row based on a key. If this value is high, it is a good indication that your tables are properly indexed for your queries.</li>' +
+               '<li><strong>read next</strong>, the number of requests to read the next row in key order. This value is incremented if you are querying an index column with a range constraint or if you are doing an index scan.</li>' +
+               '<li><strong>read prev</strong>, the number of requests to read the previous row in key order. This read method is mainly used to optimize <strong>ORDER BY ... DESC</strong>.</li>' +
+               '<li><strong>read rnd</strong>, the number of requests to read a row based on a fixed position. A high value indicates you are doing a lot of queries that require sorting of the result. You probably have a lot of queries that require MySQL to scan entire tables or you have joins that do not use keys properly.</li>' +
+               '<li><strong>read rnd next</strong>, the number of requests to read the next row in the data file. This value is high if you are doing a lot of table scans. Generally this suggests that your tables are not properly indexed or that your queries are not written to take advantage of the indexes you have.</li>' +
+               '<li><strong>rollback</strong>, the number of requests for a storage engine to perform a rollback operation.</li>' +
+               '<li><strong>savepoint</strong>, the number of requests for a storage engine to place a savepoint.</li>' +
+               '<li><strong>savepoint rollback</strong>, the number of requests for a storage engine to roll back to a savepoint.</li>' +
+               '<li><strong>update</strong>, the number of requests to update a row in a table.</li>' +
+               '<li><strong>write</strong>, the number of requests to insert a row in a table.</li>' +
+               '</ul>'
+       },
+
+       'mysql.table_locks': {
+               info: 'MySQL table locks counters: <ul>' +
+               '<li><strong>immediate</strong>, the number of times that a request for a table lock could be granted immediately.</li>' +
+               '<li><strong>waited</strong>, the number of times that a request for a table lock could not be granted immediately and a wait was needed. If this is high and you have performance problems, you should first optimize your queries, and then either split your table or tables or use replication.</li>' +
+               '</ul>'
+       },
+
        '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 <a href="#cpu">CPUs</a> section and per application usage at the <a href="#apps">Applications Monitoring</a> section.<br/>Keep an eye on <b>iowait</b> ' + sparkline('system.cpu', 'iowait', '%') + '. If it is constantly high, your disks are a bottleneck and they slow your system down.<br/>Another important metric worth monitoring, is <b>softirq</b> ' + 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: '<i class="fa fa-expand" aria-hidden="true"></i> show more information',
+                       lessText: '<i class="fa fa-compress" aria-hidden="true"></i> 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 <br/>
+                                                               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 += '</' + openTags[j] + '>'; // 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 = $('<div/>').html(bag + '<span class="ellip">' + config.ellipsesText + '</span>').html();
+                               }else{
+                                       c+=config.ellipsesText;
+                               }
+
+                               var html = '<div class="shortcontent">' + c +
+                                               '</div><div class="allcontent">' + content +
+                                               '</div><span><a href="javascript://nop/" class="morelink">' + config.moreText + '</a></span>';
+
+                               $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();