]> arthur.barton.de Git - netdata.git/commitdiff
Merge pull request #1491 from ktsaou/master
authorCosta Tsaousis <costa@tsaousis.gr>
Mon, 2 Jan 2017 00:37:03 +0000 (02:37 +0200)
committerGitHub <noreply@github.com>
Mon, 2 Jan 2017 00:37:03 +0000 (02:37 +0200)
registry memory optimization and code simplification

conf.d/Makefile.am
conf.d/health.d/mdstat.conf [new file with mode: 0644]
conf.d/python.d/mdstat.conf [new file with mode: 0644]
python.d/Makefile.am
python.d/mdstat.chart.py [new file with mode: 0644]
python.d/mysql.chart.py
src/freebsd_sysctl.c
web/index.html

index 3fa1990933acf9b357766ddc873eb82c8f56f11c..9404124e99b369da3909f002b72b5872d2ef7976 100644 (file)
@@ -34,6 +34,7 @@ dist_pythonconfig_DATA = \
     python.d/hddtemp.conf \
     python.d/ipfs.conf \
     python.d/isc_dhcpd.conf \
+    python.d/mdstat.conf \
     python.d/memcached.conf \
     python.d/mysql.conf \
     python.d/nginx.conf \
@@ -57,6 +58,7 @@ dist_healthconfig_DATA = \
     health.d/disks.conf \
     health.d/entropy.conf \
     health.d/ipc.conf \
+    health.d/mdstat.conf \
     health.d/memcached.conf \
     health.d/mysql.conf \
     health.d/named.conf \
diff --git a/conf.d/health.d/mdstat.conf b/conf.d/health.d/mdstat.conf
new file mode 100644 (file)
index 0000000..f780a91
--- /dev/null
@@ -0,0 +1,18 @@
+template: mdstat_disks
+      on: md.disks
+   units: active devices
+   every: 1s
+    calc: $total - $inuse
+    crit: $this > 0
+    info: Array is degraded!
+      to: sysadmin
+
+template: mdstat_last_collected
+      on: md.disks
+    calc: $now - $last_collected_t
+   units: seconds ago
+   every: 1s
+    warn: $this > (($status >= $WARNING)  ? ($update_every) : ( 5 * $update_every))
+    crit: $this > (($status == $CRITICAL) ? ($update_every) : (60 * $update_every))
+    info: number of seconds since the last successful data collection
+      to: sysadmin
diff --git a/conf.d/python.d/mdstat.conf b/conf.d/python.d/mdstat.conf
new file mode 100644 (file)
index 0000000..c89d463
--- /dev/null
@@ -0,0 +1,26 @@
+# netdata python.d.plugin configuration for mdstat
+#
+# This file is in YaML format. Generally the format is:
+#
+# name: value
+#
+
+# ----------------------------------------------------------------------
+# Global Variables
+# These variables set the defaults for all JOBs, however each JOB
+# may define its own, overriding the defaults.
+
+# update_every sets the default data collection frequency.
+# If unset, the python.d.plugin default is used.
+# update_every: 1
+
+# priority controls the order of charts at the netdata dashboard.
+# Lower numbers move the charts towards the top of the page.
+# If unset, the default for python.d.plugin is used.
+# priority: 60000
+
+# retries sets the number of retries to be made in case of failures.
+# If unset, the default for python.d.plugin is used.
+# Attempts to restore the service are made once every update_every
+# and only if the module has collected values in the past.
+# retries: 5
index be41dde381f577b7746e050acecfcee1f683cf06..2cf7d2ef01d2eb0919aa40dc3fa2b565f6e6ff96 100644 (file)
@@ -19,6 +19,7 @@ dist_python_SCRIPTS = \
     hddtemp.chart.py \
     ipfs.chart.py \
     isc_dhcpd.chart.py \
+    mdstat.chart.py \
     memcached.chart.py \
     mysql.chart.py \
     nginx.chart.py \
diff --git a/python.d/mdstat.chart.py b/python.d/mdstat.chart.py
new file mode 100644 (file)
index 0000000..f2c7ab5
--- /dev/null
@@ -0,0 +1,93 @@
+# -*- coding: utf-8 -*-
+# Description: mdstat netdata python.d module
+# Author: l2isbad
+
+from base import SimpleService
+from re import compile
+priority = 60000
+retries = 60
+update_every = 1
+
+
+class Service(SimpleService):
+    def __init__(self, configuration=None, name=None):
+        SimpleService.__init__(self, configuration=configuration, name=name)
+        self.order = ['agr_health']
+        self.definitions = {'agr_health':
+                                {'options':
+                                     [None, 'Faulty devices in MD', 'failed disks', 'health', 'md.health', 'line'],
+                                 'lines': []}}
+        self.proc_mdstat = '/proc/mdstat'
+        self.regex_disks = compile(r'((?<=\ )[a-zA-Z_0-9]+(?= : active)).*?((?<= \[)[0-9]+)/([0-9]+(?=\] ))')
+        self.regex_status = compile(r'([a-zA-Z_0-9]+)( : active)[^:]*?([a-z]+) = ([0-9.]+(?=%)).*?((?<=finish=)[0-9.]+)min speed=([0-9]+)')
+
+    def check(self):
+        raw_data = self._get_raw_data()
+        if not raw_data:
+            self.error('Cant read mdstat data from %s' % (self.proc_mdstat))
+            return False
+        else:
+            md_list = [md[0] for md in self.regex_disks.findall(raw_data)]
+            for md in md_list:
+                self.order.append(md)
+                self.order.append(''.join([md, '_status']))
+                self.order.append(''.join([md, '_rate']))
+                self.definitions['agr_health']['lines'].append([''.join([md, '_health']), md, 'absolute'])
+                self.definitions[md] = {'options':
+                                            [None, 'MD disks stats', 'disks', md, 'md.disks', 'stacked'],
+                                        'lines': [[''.join([md, '_total']), 'total', 'absolute'],
+                                                  [''.join([md, '_inuse']), 'inuse', 'absolute']]}
+                self.definitions[''.join([md, '_status'])] = {'options':
+                                            [None, 'MD current status', 'percent', md, 'md.status', 'line'],
+                                        'lines': [[''.join([md, '_resync']), 'resync', 'absolute', 1, 100],
+                                                  [''.join([md, '_recovery']), 'recovery', 'absolute', 1, 100],
+                                                  [''.join([md, '_check']), 'check', 'absolute', 1, 100]]}
+                self.definitions[''.join([md, '_rate'])] = {'options':
+                                            [None, 'MD operation status', 'rate', md, 'md.rate', 'line'],
+                                        'lines': [[''.join([md, '_finishin']), 'finish min', 'absolute', 1, 100],
+                                                  [''.join([md, '_rate']), 'megabyte/s', 'absolute', -1, 100]]}
+            self.info('Plugin was started successfully. MDs to monitor %s' % (md_list))
+            to_netdata = {}
+
+            return True
+
+    def _get_raw_data(self):
+        """
+        Read data from /proc/mdstat
+        :return: str
+        """
+        try:
+            with open(self.proc_mdstat, 'rt') as proc_mdstat:
+                raw_result = proc_mdstat.read()
+        except Exception:
+            return None
+        else:
+            raw_result = ' '.join(raw_result.split())
+            return raw_result
+
+    def _get_data(self):
+        """
+        Parse data from _get_raw_data()
+        :return: dict
+        """
+        raw_mdstat = self._get_raw_data()
+        mdstat_disks = self.regex_disks.findall(raw_mdstat)
+        mdstat_status = self.regex_status.findall(raw_mdstat)
+        to_netdata = {}
+
+        for md in mdstat_disks:
+            to_netdata[''.join([md[0], '_total'])] = int(md[1])
+            to_netdata[''.join([md[0], '_inuse'])] = int(md[2])
+            to_netdata[''.join([md[0], '_health'])] = int(md[1]) - int(md[2])
+            to_netdata[''.join([md[0], '_check'])] = 0
+            to_netdata[''.join([md[0], '_resync'])] = 0
+            to_netdata[''.join([md[0], '_recovery'])] = 0
+            to_netdata[''.join([md[0], '_finishin'])] = 0
+            to_netdata[''.join([md[0], '_rate'])] = 0
+        
+        for md in mdstat_status:
+            to_netdata[''.join([md[0], '_' + md[2]])] = round(float(md[3]) * 100)
+            to_netdata[''.join([md[0], '_finishin'])] = round(float(md[4]) * 100)
+            to_netdata[''.join([md[0], '_rate'])] = round(float(md[5]) / 1000 * 100)
+
+        return to_netdata
index b2e9ba07837ff0285e8357a1bba5173db95445be..0e3a032998c2535f10a0d46a08408f0519254f09 100644 (file)
@@ -473,7 +473,7 @@ class Service(SimpleService):
 
         # do calculations
         try:
-            data["Thread_cache_misses"] = int(data["Threads_created"] * 10000 / float(data["Connections"]))
+            data["Thread_cache_misses"] = round(float(data["Threads_created"]) / float(data["Connections"]) * 10000)
         except:
             data["Thread_cache_misses"] = None
 
index c0ff137d4d10296675e7fe5f273d8adfe36cc5d3..59393d7bfc84f7ddd8fea685fd2fec22ee4d6b9a 100644 (file)
@@ -701,8 +701,8 @@ int do_freebsd_sysctl(int update_every, usec_t dt) {
                         } else break;
                     }
                 }
-                total_xsw.bytes_used += xsw.xsw_used * system_pagesize;
-                total_xsw.bytes_total += xsw.xsw_nblks * system_pagesize;
+                total_xsw.bytes_used += xsw.xsw_used;
+                total_xsw.bytes_total += xsw.xsw_nblks;
             }
 
             if (likely(do_swap)) {
@@ -711,8 +711,8 @@ int do_freebsd_sysctl(int update_every, usec_t dt) {
                     st = rrdset_create("system", "swap", NULL, "swap", NULL, "System Swap", "MB", 201, update_every, RRDSET_TYPE_STACKED);
                     st->isdetail = 1;
 
-                    rrddim_add(st, "free",    NULL, 1, 1048576, RRDDIM_ABSOLUTE);
-                    rrddim_add(st, "used",    NULL, 1, 1048576, RRDDIM_ABSOLUTE);
+                    rrddim_add(st, "free",    NULL, system_pagesize, 1048576, RRDDIM_ABSOLUTE);
+                    rrddim_add(st, "used",    NULL, system_pagesize, 1048576, RRDDIM_ABSOLUTE);
                 }
                 else rrdset_next(st);
 
index a4de20ea5fd35080b65ccf99e6cb23c743b344c4..80b721fcb72bc7edf211ca6e19ff7e1d6c151251 100644 (file)
         font-weight: 500;
         color: #767676;
     }
+    .dashboard-sidebar .nav > li > a > .fa {
+        width: 20px;
+        text-align: center;
+    }
     .dashboard-sidebar .nav > li > a:hover,
     .dashboard-sidebar .nav > li > a:focus {
         padding-left: 19px;