]> arthur.barton.de Git - netdata.git/commitdiff
Merge pull request #1474 from vlvkobal/master
authorCosta Tsaousis <costa@tsaousis.gr>
Fri, 30 Dec 2016 00:36:49 +0000 (02:36 +0200)
committerGitHub <noreply@github.com>
Fri, 30 Dec 2016 00:36:49 +0000 (02:36 +0200)
FreeBSD plugin: add system interrupts chart

conf.d/health.d/backend.conf
conf.d/health.d/mysql.conf
configs.signatures
python.d/mysql.chart.py
web/dashboard.css
web/dashboard.js
web/dashboard.slate.css
web/index.html

index d127c0f8d157224fcde2785b7a48e6984324f8be..9c193e7b9203be3fbe459cd1c44ac82865e93603 100644 (file)
     info: number of metrics lost due to repeating failures to contact the backend server
       to: dba
 
-   alarm: backend_slow
-      on: netdata.backend_latency
-   units: %
-    calc: $latency * 100 / ($update_every * 1000)
-   every: 10s
-    warn: $this > 50
-    crit: $this > 100
-   delay: down 5m multiplier 1.5 max 1h
-    info: the percentage of time between iterations needed by the backend time to process the data sent by netdata
-      to: dba
+# this chart has been removed from netdata
+#   alarm: backend_slow
+#      on: netdata.backend_latency
+#   units: %
+#    calc: $latency * 100 / ($update_every * 1000)
+#   every: 10s
+#    warn: $this > 50
+#    crit: $this > 100
+#   delay: down 5m multiplier 1.5 max 1h
+#    info: the percentage of time between iterations needed by the backend time to process the data sent by netdata
+#      to: dba
index f95d7c598c961d721a74660ae38374c56ffc5665..78773e5b5b0b141489d334cbdbaf0b5bbe535b11 100644 (file)
@@ -11,3 +11,75 @@ template: mysql_last_collected_secs
    delay: down 5m multiplier 1.5 max 1h
     info: number of seconds since the last successful data collection
       to: dba
+
+
+# -----------------------------------------------------------------------------
+# slow queries
+
+template: mysql_10s_slow_queries
+      on: mysql.queries
+  lookup: sum -10s of slow_queries
+   units: slow queries
+   every: 10s
+    warn: $this > (($status >= $WARNING)  ? (5)  : (10))
+    crit: $this > (($status == $CRITICAL) ? (10) : (20))
+   delay: down 5m multiplier 1.5 max 1h
+    info: number of mysql slow queries over the last 10 seconds
+      to: dba
+
+
+# -----------------------------------------------------------------------------
+# lock waits
+
+template: mysql_10s_table_locks_immediate
+      on: mysql.table_locks
+  lookup: sum -10s absolute of immediate
+   units: immediate locks
+   every: 10s
+    info: number of table immediate locks over the last 10 seconds
+      to: dba
+
+template: mysql_10s_table_locks_waited
+      on: mysql.table_locks
+  lookup: sum -10s absolute of waited
+   units: waited locks
+   every: 10s
+    info: number of table waited locks over the last 10 seconds
+      to: dba
+
+template: mysql_10s_waited_locks_ratio
+      on: mysql.table_locks
+    calc: ($mysql_10s_table_locks_waited * 100) / ($mysql_10s_table_locks_waited + $mysql_10s_table_locks_immediate)
+   units: %
+   every: 10s
+    warn: $this > (($status >= $WARNING)  ? (10) : (25))
+    crit: $this > (($status == $CRITICAL) ? (25) : (50))
+   delay: down 30m multiplier 1.5 max 1h
+    info: the ratio of mysql waited table locks, for the last 10 seconds
+      to: dba
+
+
+# -----------------------------------------------------------------------------
+# replication
+
+template: mysql_replication
+      on: mysql.slave_status
+    calc: ($sql_running == -1 OR $io_running == -1)?0:1
+   units: status
+   every: 10s
+    crit: $this == 0
+   delay: down 5m multiplier 1.5 max 1h
+    info: checks if mysql replication has stopped
+      to: dba
+
+template: mysql_replication_lag
+      on: mysql.slave_behind
+    calc: $seconds
+   units: seconds
+   every: 10s
+    warn: $this > (($status >= $WARNING)  ? (5)  : (10))
+    crit: $this > (($status == $CRITICAL) ? (10) : (30))
+   delay: down 15m multiplier 1.5 max 1h
+    info: the number of seconds mysql replication is behind this master
+      to: dba
+
index 09bba63371516b1de6b3c0278f362ff6f78c5175..13265fe9500315242728ac5d97a3bdd140fee404 100644 (file)
@@ -35,6 +35,7 @@ declare -A configs_signatures=(
   ['1fa47f32ab52a22f8e7087cae85dd25e']='health.d/net.conf'
   ['20be73f473e59bc7de1fe61d53466aba']='health.d/ram.conf'
   ['21924a6ab8008d16ffac340f226ebad9']='python.d/nginx.conf'
+  ['219c5bb81965fa17d4940d4aa343c282']='health.d/mysql.conf'
   ['22952dbf42647c583b005054b23b545f']='health.d/disks.conf'
   ['22ceb822983134a7ca67343241f30341']='health.d/disks.conf'
   ['2385e5d35b440619621c4af62492d91b']='health.d/disks.conf'
@@ -148,6 +149,8 @@ declare -A configs_signatures=(
   ['6b917300747e7e8314844237e2462261']='python.d/apache_cache.conf'
   ['6bf0de6e3b251b765b10a71d8c5c319d']='python.d/apache.conf'
   ['6cba40e32a7e98a98c31a209913839cc']='python.d/nginx_log.conf'
+  ['6d02c2dd0863e09ad9dbba53e3b58116']='health.d/mysql.conf'
+  ['6ea958ca521e0514af57c08b518d8c5c']='health.d/backend.conf'
   ['70105b1744a8e13f49083d7f1981aea2']='python.d/ipfs.conf'
   ['707a63f53f4b32e01d134ae90ba94aad']='health_alarm_notify.conf'
   ['707a63f53f4b32e01d134ae90ba94aad']='health_email_recipients.conf'
@@ -192,6 +195,7 @@ declare -A configs_signatures=(
   ['899bcb0b3f4375b0a1280296be930201']='health.d/named.conf'
   ['89fb3cbb223be4fa0cb676cfa3b07055']='health.d/backend.conf'
   ['8a1b95d375992d7b11330a0ac46f369c']='health.d/disks.conf'
+  ['8a66a3085ad8892a002ff39b18b2cb07']='python.d/fail2ban.conf'
   ['8c1d41e2c88aeca78bc319ed74c8748c']='python.d/phpfpm.conf'
   ['8d0552371a7c9725a04196fa560813d1']='health.d/cpu.conf'
   ['8dc0bd0a70b5117454bd5f5b98f91c2c']='health.d/disks.conf'
@@ -199,6 +203,7 @@ declare -A configs_signatures=(
   ['919911d13901d60a7580f5dfd7fc87bb']='health.d/ram.conf'
   ['91c757ef6be3abdb86906d9dbb9c217a']='fping.conf'
   ['91cf3b3d42cac969b8b3fd4f531ecfb3']='python.d/squid.conf'
+  ['9542f80def48ba105190f6cdaa18248e']='health.d/mysql.conf'
   ['97eee7a30e6419df4537242e9d4a719d']='health.d/mysql.conf'
   ['97f337eb96213f3ede05e522e3743a6c']='python.d/memcached.conf'
   ['99a3de85d1e7826ed64a5f8576712e5d']='python.d.conf'
index dab6fad3be5f548ae3f72c304db7904f9572b582..b2e9ba07837ff0285e8357a1bba5173db95445be 100644 (file)
@@ -40,6 +40,7 @@ retries = 60
 
 # query executed on MySQL server
 QUERY = "SHOW GLOBAL STATUS;"
+QUERY_SLAVE = "SHOW SLAVE STATUS;"
 
 ORDER = ['net',
          'queries',
@@ -55,7 +56,7 @@ ORDER = ['net',
          'innodb_buffer_pool_read_ahead', 'innodb_buffer_pool_reqs', 'innodb_buffer_pool_ops',
          'qcache_ops', 'qcache', 'qcache_freemem', 'qcache_memblocks',
          'key_blocks', 'key_requests', 'key_disk_ops',
-         'files', 'files_rate']
+         'files', 'files_rate', 'slave_behind', 'slave_status']
 
 CHARTS = {
     'net': {
@@ -298,8 +299,18 @@ CHARTS = {
             ["Connection_errors_peer_address", "peer_addr", "incremental"],
             ["Connection_errors_select", "select", "incremental"],
             ["Connection_errors_tcpwrap", "tcpwrap", "incremental"]
+        ]},
+    'slave_behind': {
+        'options': [None, 'Slave Behind Seconds', 'seconds', 'slave', 'mysql.slave_behind', 'line'],
+        'lines': [
+            ["slave_behind", "seconds", "absolute"]
+        ]},
+    'slave_status': {
+        'options': [None, 'Slave Status', 'status', 'slave', 'mysql.slave_status', 'line'],
+        'lines': [
+            ["slave_sql", "sql_running", "absolute"],
+            ["slave_io", "io_running", "absolute"]
         ]}
-
 }
 
 
@@ -310,6 +321,7 @@ class Service(SimpleService):
         self.order = ORDER
         self.definitions = CHARTS
         self.connection = None
+        self.do_slave = -1
 
     def _parse_config(self, configuration):
         """
@@ -348,6 +360,67 @@ class Service(SimpleService):
             self.error("problem connecting to server:", e)
             raise RuntimeError
 
+    def _get_data_slave(self):
+        """
+        Get slave raw data from MySQL server
+        :return: dict
+        """
+        if self.connection is None:
+            try:
+                self._connect()
+            except RuntimeError:
+                return None
+
+        slave_data = None
+        slave_raw_data = None
+        try:
+            cursor = self.connection.cursor()
+            if cursor.execute(QUERY_SLAVE):
+                slave_raw_data = dict(list(zip([elem[0] for elem in cursor.description], cursor.fetchone())))
+
+        except MySQLdb.OperationalError as e:
+            self.debug("Reconnecting for query", QUERY_SLAVE, ":", str(e))
+            try:
+                self._connect()
+                cursor = self.connection.cursor()
+                if cursor.execute(QUERY_SLAVE):
+                    slave_raw_data = dict(list(zip([elem[0] for elem in cursor.description], cursor.fetchone())))
+            except Exception as e:
+                self.error("retried, but cannot execute query", QUERY_SLAVE, ":", str(e))
+                self.connection.close()
+                self.connection = None
+                return None
+
+        except Exception as e:
+            self.error("cannot execute query", QUERY_SLAVE, ":", str(e))
+            self.connection.close()
+            self.connection = None
+            return None
+
+        if slave_raw_data is not None:
+            slave_data = {
+                'slave_behind': None,
+                'slave_sql': None,
+                'slave_io': None
+            }
+
+            try:
+                slave_data['slave_behind'] = int(slave_raw_data.setdefault('Seconds_Behind_Master', -1))
+            except:
+                slave_data['slave_behind'] = None
+
+            try:
+                slave_data['slave_sql'] = 1 if slave_raw_data.get('Slave_SQL_Running') == 'Yes' else -1
+            except:
+                slave_data['slave_sql'] = None
+
+            try:
+                slave_data['slave_io'] = 1 if slave_raw_data.get('Slave_IO_Running') == 'Yes' else -1
+            except:
+                slave_data['slave_io'] = None
+
+        return slave_data
+
     def _get_data(self):
         """
         Get raw data from MySQL server
@@ -362,23 +435,47 @@ class Service(SimpleService):
             cursor = self.connection.cursor()
             cursor.execute(QUERY)
             raw_data = cursor.fetchall()
+
         except MySQLdb.OperationalError as e:
-            self.debug("Reconnecting due to", str(e))
-            self._connect()
-            cursor = self.connection.cursor()
-            cursor.execute(QUERY)
-            raw_data = cursor.fetchall()
+            self.debug("Reconnecting for query", QUERY, ":", str(e))
+            try:
+                self._connect()
+                cursor = self.connection.cursor()
+                cursor.execute(QUERY)
+                raw_data = cursor.fetchall()
+            except Exception as e:
+                self.error("retried, but cannot execute query", QUERY, ":", str(e))
+                self.connection.close()
+                self.connection = None
+                return None
+
         except Exception as e:
-            self.error("cannot execute query.", e)
+            self.error("cannot execute query", QUERY, ":", str(e))
             self.connection.close()
             self.connection = None
             return None
 
         data = dict(raw_data)
+
+        # check for slave data
+        # the first time is -1 (so we do it)
+        # then it is set to 1 or 0 and we keep it like that
+        if self.do_slave != 0:
+            slave_data = self._get_data_slave()
+            if slave_data is not None:
+                data.update(slave_data)
+                if self.do_slave == -1:
+                    self.do_slave = 1
+            else:
+                if self.do_slave == -1:
+                    self.error("replication metrics will be disabled - please allow netdata to collect them.")
+                    self.do_slave = 0
+
+        # do calculations
         try:
             data["Thread_cache_misses"] = int(data["Threads_created"] * 10000 / float(data["Connections"]))
         except:
-            data["Thread_cache_misses"] = 0
+            data["Thread_cache_misses"] = None
 
         return data
 
index 572d2144f7b08cc9dc9f47162da6105d14897443..8eeaa8bec45c41451beeda56235ebac8b33438d0 100644 (file)
@@ -537,7 +537,7 @@ body {
 
 .ps-container.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail > .ps-scrollbar-x {
     background-color: #aaa; /* scrollbar color when dragged away */
-    height: 4px;
+    height: 5px;
 }
 
 .ps-container.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail {
@@ -547,7 +547,7 @@ body {
 
 .ps-container.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail > .ps-scrollbar-y {
     background-color: #aaa; /* scrollbar color when dragged away */
-    width: 4px;
+    width: 5px;
 }
 
 .ps-container > .ps-scrollbar-x-rail {
@@ -561,7 +561,7 @@ body {
     transition: background-color .2s linear, opacity .2s linear;
     bottom: 0px;
     /* there must be 'bottom' for ps-scrollbar-x-rail */
-    height: 8px;
+    height: 15px;
 }
 
 .ps-container > .ps-scrollbar-x-rail > .ps-scrollbar-x {
@@ -579,7 +579,7 @@ body {
     transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -webkit-border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;
     bottom: 2px;
     /* there must be 'bottom' for ps-scrollbar-x */
-    height: 4px; /* the width of the scrollbar */
+    height: 5px; /* the width of the scrollbar */
 }
 
 .ps-container > .ps-scrollbar-x-rail:hover > .ps-scrollbar-x, .ps-container > .ps-scrollbar-x-rail:active > .ps-scrollbar-x {
@@ -597,7 +597,7 @@ body {
     transition: background-color .2s linear, opacity .2s linear;
     right: 0;
     /* there must be 'right' for ps-scrollbar-y-rail */
-    width: 8px;
+    width: 15px;
 }
 
 .ps-container > .ps-scrollbar-y-rail > .ps-scrollbar-y {
@@ -615,11 +615,11 @@ body {
     transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -webkit-border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;
     right: 2px;
     /* there must be 'right' for ps-scrollbar-y */
-    width: 4px; /* the width of the scrollbar */
+    width: 5px; /* the width of the scrollbar */
 }
 
 .ps-container > .ps-scrollbar-y-rail:hover > .ps-scrollbar-y, .ps-container > .ps-scrollbar-y-rail:active > .ps-scrollbar-y {
-    width: 4px;
+    width: 5px;
 }
 
 .ps-container:hover.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail {
@@ -629,7 +629,7 @@ body {
 
 .ps-container:hover.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail > .ps-scrollbar-x {
     background-color: #bbb; /* scrollbar color when dragged */
-    height: 4px;
+    height: 5px;
 }
 
 .ps-container:hover.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail {
@@ -639,7 +639,7 @@ body {
 
 .ps-container:hover.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail > .ps-scrollbar-y {
     background-color: #bbb; /* scrollbar color when dragged */
-    width: 4px;
+    width: 5px;
 }
 
 .ps-container:hover > .ps-scrollbar-x-rail,
index 82d1f4b315ed0665fff8ed6465400a091cef29d4..0aa4529aa0b3625332f7083669874d84aa3d19d0 100644 (file)
@@ -125,7 +125,7 @@ var NETDATA = window.NETDATA || {};
     NETDATA.themes = {
         white: {
             bootstrap_css: NETDATA.serverDefault + 'css/bootstrap-3.3.7.css',
-            dashboard_css: NETDATA.serverDefault + 'dashboard.css?v20161229-1',
+            dashboard_css: NETDATA.serverDefault + 'dashboard.css?v20161229-2',
             background: '#FFFFFF',
             foreground: '#000000',
             grid: '#F0F0F0',
@@ -142,7 +142,7 @@ var NETDATA = window.NETDATA || {};
         },
         slate: {
             bootstrap_css: NETDATA.serverDefault + 'css/bootstrap-slate-flat-3.3.7.css?v20161229-1',
-            dashboard_css: NETDATA.serverDefault + 'dashboard.slate.css?v20161229-1',
+            dashboard_css: NETDATA.serverDefault + 'dashboard.slate.css?v20161229-2',
             background: '#272b30',
             foreground: '#C8C8C8',
             grid: '#283236',
index b4e3fbe0a943c7f11e279481d4f12b963c40a334..36ea6dc6a2fe96b4df058e2c090c5218774d2b29 100644 (file)
@@ -555,7 +555,7 @@ code {
 
 .ps-container.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail > .ps-scrollbar-x {
     background-color: #aaa; /* scrollbar color when dragged away */
-    height: 4px;
+    height: 5px;
 }
 
 .ps-container.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail {
@@ -565,7 +565,7 @@ code {
 
 .ps-container.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail > .ps-scrollbar-y {
     background-color: #aaa; /* scrollbar color when dragged away */
-    width: 4px;
+    width: 5px;
 }
 
 .ps-container > .ps-scrollbar-x-rail {
@@ -579,7 +579,7 @@ code {
     transition: background-color .2s linear, opacity .2s linear;
     bottom: 0px;
     /* there must be 'bottom' for ps-scrollbar-x-rail */
-    height: 8px;
+    height: 15px;
 }
 
 .ps-container > .ps-scrollbar-x-rail > .ps-scrollbar-x {
@@ -597,11 +597,11 @@ code {
     transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -webkit-border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;
     bottom: 2px;
     /* there must be 'bottom' for ps-scrollbar-x */
-    height: 4px; /* the width of the scrollbar */
+    height: 5px; /* the width of the scrollbar */
 }
 
 .ps-container > .ps-scrollbar-x-rail:hover > .ps-scrollbar-x, .ps-container > .ps-scrollbar-x-rail:active > .ps-scrollbar-x {
-    height: 4px;
+    height: 5px;
 }
 
 .ps-container > .ps-scrollbar-y-rail {
@@ -615,7 +615,7 @@ code {
     transition: background-color .2s linear, opacity .2s linear;
     right: 0;
     /* there must be 'right' for ps-scrollbar-y-rail */
-    width: 8px;
+    width: 15px;
 }
 
 .ps-container > .ps-scrollbar-y-rail > .ps-scrollbar-y {
@@ -633,11 +633,11 @@ code {
     transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -webkit-border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;
     right: 2px;
     /* there must be 'right' for ps-scrollbar-y */
-    width: 4px; /* the width of the scrollbar */
+    width: 5px; /* the width of the scrollbar */
 }
 
 .ps-container > .ps-scrollbar-y-rail:hover > .ps-scrollbar-y, .ps-container > .ps-scrollbar-y-rail:active > .ps-scrollbar-y {
-    width: 4px;
+    width: 5px;
 }
 
 .ps-container:hover.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail {
@@ -647,7 +647,7 @@ code {
 
 .ps-container:hover.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail > .ps-scrollbar-x {
     background-color: #bbb; /* scrollbar color when dragged */
-    height: 4px;
+    height: 5px;
 }
 
 .ps-container:hover.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail {
@@ -657,7 +657,7 @@ code {
 
 .ps-container:hover.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail > .ps-scrollbar-y {
     background-color: #bbb; /* scrollbar color when dragged */
-    width: 4px;
+    width: 5px;
 }
 
 .ps-container:hover > .ps-scrollbar-x-rail,
index a5cb3729db54ff468e3850015b5d8e44d1e3dea4..a4de20ea5fd35080b65ccf99e6cb23c743b344c4 100644 (file)
 
                 function alarm_to_html(alarm, full) {
                     var chart = options.data.charts[alarm.chart];
+                    var has_alarm = ((typeof alarm.warn !== 'undefined' || typeof alarm.crit !== 'undefined')?true:false);
 
                     var html = '<tr><td class="text-center" style="vertical-align:middle" width="40%"><b>' + alarm.chart + '</b><br/>&nbsp;<br/><embed src="' + NETDATA.alarms.server + '/api/v1/badge.svg?chart=' + alarm.chart + '&alarm=' + alarm.name + '&refresh=auto" type="image/svg+xml" height="20"/><br/>&nbsp;<br/><span style="font-size: 18px">' + alarm.info + '</span><br/>&nbsp;<br/>role: <b>' + alarm.recipient + '</b><br/>&nbsp;<br/><b><i class="fa fa-line-chart" aria-hidden="true"></i></b><small>&nbsp;&nbsp;<a href="#" onClick="NETDATA.alarms.scrollToChart(\'' + alarm.chart + '\'); $(\'#alarmsModal\').modal(\'hide\'); return false;">jump to chart</a></small></td>'
                         + '<td><table class="table">'
                     }
 
                     html += '<tr><td width="10%" style="text-align:right">check&nbsp;every</td><td>' + seconds4human(alarm.update_every, { negative_suffix: '' }) + '</td></tr>'
-                        + '<tr><td width="10%" style="text-align:right">execute</td><td><span style="font-family: monospace;">' + alarm.exec + '</span>' + delay + '</td></tr>'
+                        + ((has_alarm === true)?('<tr><td width="10%" style="text-align:right">execute</td><td><span style="font-family: monospace;">' + alarm.exec + '</span>' + delay + '</td></tr>'):'')
                         + '<tr><td width="10%" style="text-align:right">source</td><td><span style="font-family: monospace;">' + alarm.source + '</span></td></tr>'
                         + '</table></td></tr>';
 
             });
             Ps.update(sidebar);
 
-            var registry = document.getElementById('registry-dropdown');
+            var registry = document.getElementById('myNetdataDropdownUL');
             Ps.initialize(registry, {
-                wheelSpeed: 0.5,
+                wheelSpeed: 1,
                 wheelPropagation: false,
                 swipePropagation: false,
                 minScrollbarLength: null,
                 Ps.update(sidebar);
                 Ps.update(registry);
             };
+
+            $('#myNetdataDropdownParent')
+                .on('show.bs.dropdown', function () {
+                    NETDATA.pause(function() {});
+                })
+                .on('shown.bs.dropdown', function () {
+                    Ps.update(registry);
+                })
+                .on('hidden.bs.dropdown', function () {
+                    NETDATA.unpause();
+                });
         }
 
         function resetDashboardOptions() {
         <div class="container">
             <nav id="mynetdata_nav" class="collapse navbar-collapse navbar-left hidden-sm hidden-xs" role="navigation" style="padding-right: 20px;">
                 <ul class="nav navbar-nav">
-                    <li class="dropdown">
-                        <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="current_view">my-netdata <strong class="caret"></strong></a>
-                        <ul class="dropdown-menu scrollable-menu inpagemenu multi-column columns-2" role="menu" id="registry-dropdown">
+                    <li class="dropdown" id="myNetdataDropdownParent">
+                        <a href="#" class="dropdown-toggle" data-toggle="dropdown">my-netdata <strong class="caret"></strong></a>
+                        <ul class="dropdown-menu scrollable-menu inpagemenu multi-column columns-2" role="menu" id="myNetdataDropdownUL">
                             <div class="row">
                                 <div class="col-sm-6" style="width: 85%; padding-right: 0;">
                                     <ul id="mynetdata_servers" class="multi-column-dropdown">
                     <li><a href="#" class="btn" data-toggle="modal" data-target="#alarmsModal" title="alarms"><i class="fa fa-bell"></i>&nbsp;<span class="hidden-sm">Alarms&nbsp;</span><span id="alarms_count_badge" class="badge"></span></a></li>
                     <li><a href="#" class="btn" data-toggle="modal" data-target="#optionsModal" title="dashboard settings"><i class="fa fa-sliders"></i>&nbsp;<span class="hidden-sm">Settings</span></a></li>
                     <li><a href="https://github.com/firehol/netdata/wiki" class="btn" target="_blank" title="netdata community"><i class="fa fa-github"></i>&nbsp;<span class="hidden-sm hidden-md">Community</span></a></li>
-                    <li class="hidden-sm" id="updateButton"><a href="#" class="btn" data-toggle="modal" data-target="#updateModal" title="check for update"><i class="fa fa-cloud-download"></i><span id="update_badge" class="badge"></span>&nbsp;<span class="hidden-sm hidden-md">Update</span></a></li>
+                    <li class="hidden-sm" id="updateButton"><a href="#" class="btn" data-toggle="modal" data-target="#updateModal" title="check for update"><i class="fa fa-cloud-download"></i> <span class="hidden-sm hidden-md">Update </span><span id="update_badge" class="badge"></span></a></li>
                     <li class="hidden-sm"><a href="#" class="btn" data-toggle="modal" data-target="#helpModal" title="dashboard help"><i class="fa fa-question-circle"></i>&nbsp;<span class="hidden-sm hidden-md">Help</span></a></li>
-                    <!--
-                    <li class="dropdown hidden-md hidden-lg hidden-xs">
-                        <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="current_view">Menu <strong class="caret"></strong></a>
-                        <ul class="dropdown-menu scrollable-menu inpagemenu" role="menu">
-                            <li><a href="#" class="btn" data-toggle="modal" data-target="#alarmsModal"><i class="fa fa-bell"></i> alarms</a></li>
-                            <li><a href="#" class="btn" data-toggle="modal" data-target="#optionsModal"><i class="fa fa-sliders"></i> settings</a></li>
-                            <li><a href="https://github.com/firehol/netdata/wiki" class="btn" target="_blank"><i class="fa fa-github"></i> community</a></li>
-                            <li><a href="#" class="btn" data-toggle="modal" data-target="#helpModal"><i class="fa fa-question-circle"></i> help</a></li>
-                        </ul>
-                    </li>
-                    -->
                     <li class="dropdown hidden-sm hidden-md hidden-lg">
-                        <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="current_view">my-netdata <strong class="caret"></strong></a>
+                        <a href="#" class="dropdown-toggle" data-toggle="dropdown">my-netdata <strong class="caret"></strong></a>
                         <ul id="mynetdata_servers2" class="dropdown-menu scrollable-menu inpagemenu" role="menu">
                             <li><a href="#" onclick="return false;" style="color: #999;">loading...</a></li>
                         </ul>
     </div>
 </body>
 </html>
-<script type="text/javascript" src="dashboard.js?v20161229-3"></script>
+<script type="text/javascript" src="dashboard.js?v20161229-4"></script>