FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
netdata/python.d/mdstat.chart.py at master · devanthonyp/netdata · GitHub
devanthonyp
/
netdata
Public
forked from
netdata/netdata
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Pull requests
0
Actions
Projects
Wiki
Security and quality
0
Insights
Additional navigation options
Code
Pull requests
Actions
Projects
Wiki
Security and quality
Insights
Expand file tree
Breadcrumbs
netdata
/
python.d
/
mdstat.chart.py
Copy path
More file actions
More file actions
Latest commit
History
History
History
204 lines (157 loc) · 5.57 KB
Breadcrumbs
netdata
/
python.d
/
mdstat.chart.py
Copy path
File metadata and controls
204 lines (157 loc) · 5.57 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# -*- coding: utf-8 -*-
# Description: mdstat netdata python.d module
# Author: Ilya Mashchenko (l2isbad)
# SPDX-License-Identifier: GPL-3.0+
import
re
from
collections
import
defaultdict
from
bases
.
FrameworkServices
.
SimpleService
import
SimpleService
MDSTAT
=
'/proc/mdstat'
MISMATCH_CNT
=
'/sys/block/{0}/md/mismatch_cnt'
ORDER
=
[
'mdstat_health'
]
CHARTS
=
{
'mdstat_health'
: {
'options'
: [
None
,
'Faulty Devices In MD'
,
'failed disks'
,
'health'
,
'md.health'
,
'line'
],
'lines'
:
list
()
}
}
RE_DISKS
=
re
.
compile
(
r' (?P<array>[a-zA-Z_0-9]+) : active .+\['
r'(?P<total_disks>[0-9]+)/'
r'(?P<inuse_disks>[0-9]+)\]'
)
RE_STATUS
=
re
.
compile
(
r' (?P<array>[a-zA-Z_0-9]+) : active .+ '
r'(?P<operation>[a-z]+) =[ ]{1,2}'
r'(?P<operation_status>[0-9.]+).+finish='
r'(?P<finish_in>([0-9.]+))min speed='
r'(?P<speed>[0-9]+)'
)
def
md_charts
(
name
):
order
=
[
'{0}_disks'
.
format
(
name
),
'{0}_operation'
.
format
(
name
),
'{0}_mismatch_cnt'
.
format
(
name
),
'{0}_finish'
.
format
(
name
),
'{0}_speed'
.
format
(
name
)
]
charts
=
dict
()
charts
[
order
[
0
]]
=
{
'options'
: [
None
,
'Disks Stats'
,
'disks'
,
name
,
'md.disks'
,
'stacked'
],
'lines'
: [
[
'{0}_total_disks'
.
format
(
name
),
'total'
,
'absolute'
],
[
'{0}_inuse_disks'
.
format
(
name
),
'inuse'
,
'absolute'
]
]
}
charts
[
order
[
1
]]
=
{
'options'
: [
None
,
'Current Status'
,
'percent'
,
name
,
'md.status'
,
'line'
],
'lines'
: [
[
'{0}_resync'
.
format
(
name
),
'resync'
,
'absolute'
,
1
,
100
],
[
'{0}_recovery'
.
format
(
name
),
'recovery'
,
'absolute'
,
1
,
100
],
[
'{0}_reshape'
.
format
(
name
),
'reshape'
,
'absolute'
,
1
,
100
],
[
'{0}_check'
.
format
(
name
),
'check'
,
'absolute'
,
1
,
100
],
]
}
charts
[
order
[
2
]]
=
{
'options'
: [
None
,
'Mismatch Count'
,
'unsynchronized blocks'
,
name
,
'md.mismatch_cnt'
,
'line'
],
'lines'
: [
[
'{0}_mismatch_cnt'
.
format
(
name
),
'count'
,
'absolute'
]
]
}
charts
[
order
[
3
]]
=
{
'options'
: [
None
,
'Approximate Time Until Finish'
,
'seconds'
,
name
,
'md.rate'
,
'line'
],
'lines'
: [
[
'{0}_finish_in'
.
format
(
name
),
'finish in'
,
'absolute'
,
1
,
1000
]
]
}
charts
[
order
[
4
]]
=
{
'options'
: [
None
,
'Operation Speed'
,
'KB/s'
,
name
,
'md.rate'
,
'line'
],
'lines'
: [
[
'{0}_speed'
.
format
(
name
),
'speed'
,
'absolute'
,
1
,
1000
]
]
}
return
order
,
charts
class
MD
:
def
__init__
(
self
,
raw_data
):
self
.
name
=
raw_data
[
"array"
]
self
.
d
=
raw_data
def
data
(
self
):
rv
=
{
'total_disks'
:
self
.
d
[
'total_disks'
],
'inuse_disks'
:
self
.
d
[
'inuse_disks'
],
'health'
:
int
(
self
.
d
[
'total_disks'
])
-
int
(
self
.
d
[
'inuse_disks'
]),
'resync'
:
0
,
'recovery'
:
0
,
'reshape'
:
0
,
'check'
:
0
,
'finish_in'
:
0
,
'speed'
:
0
,
}
v
=
read_lines
(
MISMATCH_CNT
.
format
(
self
.
name
))
if
v
:
rv
[
'mismatch_cnt'
]
=
v
if
self
.
d
.
get
(
'operation'
):
rv
[
self
.
d
[
'operation'
]]
=
float
(
self
.
d
[
'operation_status'
])
*
100
rv
[
'finish_in'
]
=
float
(
self
.
d
[
'finish_in'
])
*
1000
*
60
rv
[
'speed'
]
=
float
(
self
.
d
[
'speed'
])
*
1000
return
dict
((
'{0}_{1}'
.
format
(
self
.
name
,
k
),
v
)
for
k
,
v
in
rv
.
items
())
class
Service
(
SimpleService
):
def
__init__
(
self
,
configuration
=
None
,
name
=
None
):
SimpleService
.
__init__
(
self
,
configuration
=
configuration
,
name
=
name
)
self
.
order
=
ORDER
self
.
definitions
=
CHARTS
self
.
mds
=
list
()
@
staticmethod
def
get_mds
():
raw
=
read_lines
(
MDSTAT
)
if
not
raw
:
return
None
return
find_mds
(
raw
)
def
get_data
(
self
):
"""
Parse data from _get_raw_data()
:return: dict
"""
mds
=
self
.
get_mds
()
if
not
mds
:
return
None
data
=
dict
()
for
md
in
mds
:
if
md
.
name
not
in
self
.
mds
:
self
.
mds
.
append
(
md
.
name
)
self
.
add_new_md_charts
(
md
.
name
)
data
.
update
(
md
.
data
())
return
data
def
check
(
self
):
if
not
self
.
get_mds
():
self
.
error
(
'Failed to read data from {0} or there is no active arrays'
.
format
(
MDSTAT
))
return
False
return
True
def
add_new_md_charts
(
self
,
name
):
order
,
charts
=
md_charts
(
name
)
self
.
charts
[
'mdstat_health'
].
add_dimension
([
'{0}_health'
.
format
(
name
),
name
])
for
chart_name
in
order
:
params
=
[
chart_name
]
+
charts
[
chart_name
][
'options'
]
dims
=
charts
[
chart_name
][
'lines'
]
chart
=
self
.
charts
.
add_chart
(
params
)
for
dim
in
dims
:
chart
.
add_dimension
(
dim
)
def
find_mds
(
raw_data
):
data
=
defaultdict
(
str
)
counter
=
1
for
row
in
(
elem
.
strip
()
for
elem
in
raw_data
):
if
not
row
:
counter
+=
1
continue
data
[
counter
]
=
' '
.
join
([
data
[
counter
],
row
])
mds
=
list
()
for
v
in
data
.
values
():
m
=
RE_DISKS
.
search
(
v
)
if
not
m
:
continue
d
=
m
.
groupdict
()
m
=
RE_STATUS
.
search
(
v
)
if
m
:
d
.
update
(
m
.
groupdict
())
mds
.
append
(
MD
(
d
))
return
sorted
(
mds
,
key
=
lambda
md
:
md
.
name
)
def
read_lines
(
path
):
try
:
with
open
(
path
)
as
f
:
return
f
.
readlines
()
except
(
IOError
,
OSError
):
return
None
Back
|
FazBrowse Home
|
New Git URL