Source code for tensor.sources.linux.sensors

import os

from zope.interface import implementer

from twisted.internet import defer

from tensor.interfaces import ITensorSource
from tensor.objects import Source


@implementer(ITensorSource)
[docs]class Sensors(Source): """Returns lm-sensors output NB. This is very untested on different configurations and versions. Please report any issues with the output of the `sensors` command to help improve it. **Metrics:** :(service name).(adapter).(sensor): Sensor value """ ssh = True @defer.inlineCallbacks def _get_sensors(self): out, err, code = yield self.fork('/usr/bin/sensors') if code == 0: defer.returnValue(out.strip('\n').split('\n')) else: defer.returnValue([]) def _parse_sensors(self, sensors): adapters = {} adapter = None for i in sensors: l = i.strip() if not l: continue if ':' in l: n, v = l.split(':') vals = v.strip().split() if n=='Adapter': continue if '\xc2\xb0' in vals[0]: val = vals[0].split('\xc2\xb0')[0] unit = vals[0][-1] elif len(vals)>1: val = vals[0] unit = vals[1] else: continue val = float(val) adapters[adapter][n] = val else: adapter = l adapters[adapter] = {} return adapters @defer.inlineCallbacks def get(self): sensors = yield self._get_sensors() adapters = self._parse_sensors(sensors) events = [] for adapter, v in adapters.items(): for sensor, val in v.items(): events.append( self.createEvent('ok', 'Sensor %s:%s - %s' % (adapter, sensor, val), val, prefix='%s.%s' % (adapter, sensor,))) defer.returnValue(events)
@implementer(ITensorSource)
[docs]class SMART(Source): """Returns SMART output for all disks **Metrics:** :(service name).(disk).(sensor): Sensor value """ ssh = True def __init__(self, *a, **kw): Source.__init__(self, *a, **kw) self.devices = [] @defer.inlineCallbacks def _get_disks(self): out, err, code = yield self.fork('/usr/sbin/smartctl', args=('--scan',)) if code != 0: defer.returnValue([]) out = out.strip('\n').split('\n') devices = [] for ln in out: if '/dev' in ln: devices.append(ln.split()[0]) defer.returnValue(devices) @defer.inlineCallbacks def _get_smart(self, device): out, err, code = yield self.fork('/usr/sbin/smartctl', args=('-A', device)) if code == 0: defer.returnValue(out.strip('\n').split('\n')) else: defer.returnValue([]) def _parse_smart(self, smart): mark = False attributes = {} for l in smart: ln = l.strip('\n').strip() if not ln: continue if mark: (id, attribute, flag, val, worst,thresh, type, u, wf, raw ) = ln.split(None, 9) try: raw = int(raw.split()[0]) attributes[attribute.replace('_', ' ')] = raw except: pass if ln[:3] == 'ID#': mark = True return attributes @defer.inlineCallbacks def get(self): disks = self._get_disks() if not self.devices: self.devices = yield self._get_disks() events = [] for disk in self.devices: smart = yield self._get_smart(disk) stats = self._parse_smart(smart) for sensor, val in stats.items(): events.append( self.createEvent('ok', 'Attribute %s:%s - %s' % (disk, sensor, val), val, prefix='%s.%s' % (disk, sensor,))) defer.returnValue(events)