]> arthur.barton.de Git - netdata.git/blob - python.d/mdstat.chart.py
dns_query_time plugin: added
[netdata.git] / python.d / mdstat.chart.py
1 # -*- coding: utf-8 -*-
2 # Description: mdstat netdata python.d module
3 # Author: l2isbad
4
5 from base import SimpleService
6 from re import compile
7 priority = 60000
8 retries = 60
9 update_every = 1
10
11
12 class Service(SimpleService):
13     def __init__(self, configuration=None, name=None):
14         SimpleService.__init__(self, configuration=configuration, name=name)
15         self.order = ['agr_health']
16         self.definitions = {'agr_health':
17                                 {'options':
18                                      [None, 'Faulty devices in MD', 'failed disks', 'health', 'md.health', 'line'],
19                                  'lines': []}}
20         self.proc_mdstat = '/proc/mdstat'
21         self.regex_disks = compile(r'((?<=\ )[a-zA-Z_0-9]+(?= : active)).*?((?<= \[)[0-9]+)/([0-9]+(?=\] ))')
22         self.regex_status = compile(r'([a-zA-Z_0-9]+)( : active)[^:]*?([a-z]+) = ([0-9.]+(?=%)).*?((?<=finish=)[0-9.]+)min speed=([0-9]+)')
23
24     def check(self):
25         raw_data = self._get_raw_data()
26         if not raw_data:
27             self.error('Cant read mdstat data from %s' % (self.proc_mdstat))
28             return False
29         
30         md_list = [md[0] for md in self.regex_disks.findall(raw_data)]
31
32         if not md_list:
33             self.error('No active arrays in %s' % (self.proc_mdstat))
34             return False
35         else:
36             for md in md_list:
37                 self.order.append(md)
38                 self.order.append(''.join([md, '_status']))
39                 self.order.append(''.join([md, '_rate']))
40                 self.definitions['agr_health']['lines'].append([''.join([md, '_health']), md, 'absolute'])
41                 self.definitions[md] = {'options':
42                                             [None, '%s disks stats' % md, 'disks', md, 'md.disks', 'stacked'],
43                                         'lines': [[''.join([md, '_total']), 'total', 'absolute'],
44                                                   [''.join([md, '_inuse']), 'inuse', 'absolute']]}
45                 self.definitions[''.join([md, '_status'])] = {'options':
46                                             [None, '%s current status' % md, 'percent', md, 'md.status', 'line'],
47                                         'lines': [[''.join([md, '_resync']), 'resync', 'absolute', 1, 100],
48                                                   [''.join([md, '_recovery']), 'recovery', 'absolute', 1, 100],
49                                                   [''.join([md, '_reshape']), 'reshape', 'absolute', 1, 100],
50                                                   [''.join([md, '_check']), 'check', 'absolute', 1, 100]]}
51                 self.definitions[''.join([md, '_rate'])] = {'options':
52                                             [None, '%s operation status' % md, 'rate', md, 'md.rate', 'line'],
53                                         'lines': [[''.join([md, '_finishin']), 'finish min', 'absolute', 1, 100],
54                                                   [''.join([md, '_rate']), 'megabyte/s', 'absolute', -1, 100]]}
55             self.info('Plugin was started successfully. MDs to monitor %s' % (md_list))
56
57             return True
58
59     def _get_raw_data(self):
60         """
61         Read data from /proc/mdstat
62         :return: str
63         """
64         try:
65             with open(self.proc_mdstat, 'rt') as proc_mdstat:
66                 raw_result = proc_mdstat.read()
67         except Exception:
68             return None
69         else:
70             raw_result = ' '.join(raw_result.split())
71             return raw_result
72
73     def _get_data(self):
74         """
75         Parse data from _get_raw_data()
76         :return: dict
77         """
78         raw_mdstat = self._get_raw_data()
79         mdstat_disks = self.regex_disks.findall(raw_mdstat)
80         mdstat_status = self.regex_status.findall(raw_mdstat)
81         to_netdata = {}
82
83         for md in mdstat_disks:
84             to_netdata[''.join([md[0], '_total'])] = int(md[1])
85             to_netdata[''.join([md[0], '_inuse'])] = int(md[2])
86             to_netdata[''.join([md[0], '_health'])] = int(md[1]) - int(md[2])
87             to_netdata[''.join([md[0], '_check'])] = 0
88             to_netdata[''.join([md[0], '_resync'])] = 0
89             to_netdata[''.join([md[0], '_reshape'])] = 0
90             to_netdata[''.join([md[0], '_recovery'])] = 0
91             to_netdata[''.join([md[0], '_finishin'])] = 0
92             to_netdata[''.join([md[0], '_rate'])] = 0
93         
94         for md in mdstat_status:
95             to_netdata[''.join([md[0], '_' + md[2]])] = round(float(md[3]) * 100)
96             to_netdata[''.join([md[0], '_finishin'])] = round(float(md[4]) * 100)
97             to_netdata[''.join([md[0], '_rate'])] = round(float(md[5]) / 1000 * 100)
98
99         return to_netdata