@cryptotaxi247 / netdata-1 / commits / d72a06648

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