smartd_log module: now produces 2 sets of charts for every smart attribute (raw, normalized)
lgz committed
Dec 1, 2017 at 14:33 UTC
d72a066481d7f88568a5088b0c0e7bbc43bf93d2
1 file changed
+49
-48
python.d/smartd_log.chart.py
+49
-48
@@ -105,14 +105,15 @@ REGEX = re.compile(
105
)
106
107
108
-def chart_template(attr, raw):
109
- chart_name = 'attr_id' + attr
110
- title = SMART_ATTR[attr]
111
- units = 'raw' if raw else 'normalized'
108
+def chart_template(chart_name):
109
+ units, attr_id = chart_name.split('_')[-2:]
110
+ title = '{value_type} {description}'.format(value_type=units.capitalize(),
111
+ description=SMART_ATTR[attr_id])
112
+ family = SMART_ATTR[attr_id].lower()
113
114
return {
115
chart_name: {
115
- 'options': [None, title, units, title.lower(), 'smartd_log.' + chart_name, 'line'],
116
+ 'options': [None, title, units, family, 'smartd_log.' + chart_name, 'line'],
117
'lines': []
118
}
119
}
@@ -194,14 +195,12 @@ class Disk:
195
in REGEX.findall(last_line))
196
return True
197
197
- def data(self, raw=None):
198
+ def data(self):
199
data = dict()
200
for attr in self.attributes.values():
200
- value = attr.raw if raw else attr.normalized
201
- if value is None:
202
- continue
203
- key = '_'.join([self.name, attr.id])
204
- data[key] = value
201
+ data['_'.join([self.name, 'normalized', attr.id])] = attr.normalized
202
+ if attr.raw is not None:
203
+ data['_'.join([self.name, 'raw', attr.id])] = attr.raw
204
return data
205
206
@@ -261,54 +260,34 @@ class Service(SimpleService):
260
disk.status = False
261
continue
262
264
- data.update(disk.data(self.raw))
263
+ data.update(disk.data())
264
265
return data or None
266
267
def create_charts(self, order):
268
for attr in order:
270
- chart_id = 'attr_id' + attr
271
- chart = chart_template(attr, self.raw)
269
+ raw_name, normalized_name = 'attr_id_raw_' + attr, 'attr_id_normalized_' + attr
270
+ raw, normalized = chart_template(raw_name), chart_template(normalized_name)
271
+ self.order.extend([normalized_name, raw_name])
272
+ self.definitions.update(raw)
273
+ self.definitions.update(normalized)
274
275
for disk in self.disks:
276
if attr not in disk.attributes:
277
self.debug("'{disk}' has no attribute '{attr_id}'".format(disk=disk.name,
278
attr_id=attr))
279
continue
280
+ normalized[normalized_name]['lines'].append(['_'.join([disk.name, 'normalized', attr]), disk.name])
281
279
- if self.raw and disk.attributes[attr].raw is None:
280
- self.debug("'{disk}' attribute '{attr_id}' value not in {limits}".format(disk=disk.name,
281
- attr_id=attr,
282
- limits=LIMITS[attr]))
282
+ if not self.raw:
283
continue
284
- chart[chart_id]['lines'].append(['_'.join([disk.name, attr]), disk.name])
285
-
286
- self.order.append(chart_id)
287
- self.definitions.update(chart)
288
-
289
- def scan(self, only_new=None):
290
- new_disks = list()
291
- for f in os.listdir(self.log_path):
292
- full_path = os.path.join(self.log_path, f)
293
-
294
- if DiskLogFile.is_valid(full_path, self.exclude):
295
- disk = Disk(full_path, self.age)
284
297
- active = disk.is_active()
298
- if active is None:
285
+ if disk.attributes[attr].raw is not None:
286
+ raw[raw_name]['lines'].append(['_'.join([disk.name, 'raw', attr]), disk.name])
287
continue
300
-
301
- if active:
302
- if not only_new:
303
- new_disks.append(disk)
304
- else:
305
- if disk not in self.disks:
306
- new_disks.append(disk)
307
- else:
308
- if not only_new:
309
- self.debug("'{disk}' not updated in the last {age} minutes, "
310
- "skipping it.".format(disk=disk.name, age=self.age))
311
- return new_disks
288
+ self.debug("'{disk}' attribute '{attr_id}' value not in {limits}".format(disk=disk.name,
289
+ attr_id=attr,
290
+ limits=LIMITS[attr]))
291
292
def cleanup_and_rescan(self):
293
self.cleanup()
@@ -318,11 +297,11 @@ class Service(SimpleService):
297
valid = False
298
299
for chart in self.charts:
321
- idx = chart.id[7:]
300
+ value_type, idx = chart.id.split('_')[2:]
301
302
if idx in disk.attributes:
303
valid = True
325
- dimension_id = '_'.join([disk.name, idx])
304
+ dimension_id = '_'.join([disk.name, value_type, idx])
305
306
if dimension_id in chart:
307
chart.hide_dimension(dimension_id=dimension_id, reverse=True)
@@ -336,10 +315,32 @@ class Service(SimpleService):
315
316
if not disk.is_active():
317
disk.status = False
339
-
318
if not disk.status:
319
for chart in self.charts:
342
- dimension_id = '_'.join([disk.name, chart.id[7:]])
320
+ dimension_id = '_'.join([disk.name, chart.id[8:]])
321
chart.hide_dimension(dimension_id=dimension_id)
322
323
self.disks = [disk for disk in self.disks if disk.status]
324
+
325
+ def scan(self, only_new=None):
326
+ new_disks = list()
327
+ for f in os.listdir(self.log_path):
328
+ full_path = os.path.join(self.log_path, f)
329
+
330
+ if DiskLogFile.is_valid(full_path, self.exclude):
331
+ disk = Disk(full_path, self.age)
332
+
333
+ active = disk.is_active()
334
+ if active is None:
335
+ continue
336
+ if active:
337
+ if not only_new:
338
+ new_disks.append(disk)
339
+ else:
340
+ if disk not in self.disks:
341
+ new_disks.append(disk)
342
+ else:
343
+ if not only_new:
344
+ self.debug("'{disk}' not updated in the last {age} minutes, "
345
+ "skipping it.".format(disk=disk.name, age=self.age))
346
+ return new_disks