1
2
3
4
5
6
7
8
9
10
11
12
13 import os.path
14
15 from Products.ZenRRD.RRDUtil import RRDUtil
16
17 import logging
18 log = logging.getLogger("zenhub")
19
20
22
23 LONG_RRD_TYPES = ['COUNTER', 'DERIVE']
24
26
27 self.rrd = {}
28
29
30 self.counts = {}
31
32 self.dmd = dmd
33
34
35 - def writeRRD(self, devId, compType, compId, dpName, value):
36 ''' Write the given data to it's rrd file.
37 Also check any thresholds and send events if value is out of bounds.
38 '''
39 log.debug('Writing %s %s' % (dpName, value))
40 dev = self.getDeviceOrComponent(devId, compType, compId)
41 dp = dev.getRRDDataPoint(dpName)
42 if not dp:
43 log.warn('Did not find datapoint %s on device %s', dpName, devId)
44 return None
45 rrdKey = (dev.getPrimaryPath(), dp.getPrimaryPath())
46 rrdCreateCmd = dp.createCmd or self.getDefaultRRDCreateCommand(dev)
47 if self.rrd.has_key(rrdKey):
48 rrd = self.rrd[rrdKey]
49 else:
50 rrd = RRDUtil(rrdCreateCmd, dp.datasource.cycletime)
51 self.rrd[rrdKey] = rrd
52
53
54 if dp.rrdtype in RRDImpl.LONG_RRD_TYPES:
55 try:
56 value = long(value)
57 except ValueError:
58 log.warn("value '%s' received for data point '%s' that " \
59 "could not be converted to a long" % \
60 (value, dp.rrdtype))
61
62 value = rrd.save(os.path.join(dev.rrdPath(), dp.name()),
63 value,
64 dp.rrdtype,
65 rrdCreateCmd,
66 dp.datasource.cycletime,
67 dp.rrdmin,
68 dp.rrdmax)
69 self.checkThresholds(dev, dp, value)
70 return value
71
72
75
76
78 ''' If a compId is given then try to return that component. If unable
79 to find it or if compId is not specified then try to return the
80 given device. If unable to find then return None.
81 '''
82 d = None
83 device = self.dmd.Devices.findDevice(devId)
84 if device:
85 if compId:
86 for comp in device.getDeviceComponents():
87 if comp.meta_type == compType and comp.id == compId:
88 d = comp
89 break
90 else:
91 d = device
92 return d
93
94
96 ''' Check the given value against any thresholds. Count the number of
97 times a dp has exceeded a given threshold in self.counts. Send events
98 as appropriate.
99 '''
100 if value is None:
101 return
102
103
104 for t in [t for t in dp.datasource.rrdTemplate.thresholds()
105 if t.enabled and dp.name() in t.dsnames]:
106 log.debug('Checking %s value of %s against threshold %s: %s:%s' %
107 (dp.name(), value, t.id, t.getMinval(dev), t.getMaxval(dev)))
108 countKey = (dev.getPrimaryPath(), dp.getPrimaryPath(), t.id)
109 count = self.counts.setdefault(countKey, 0)
110 limit = None
111 how = None
112 maxv = t.getMaxval(dev)
113 if maxv is not None and value > maxv:
114 log.debug('threshold exceeded')
115 limit = maxv
116 how = 'exceeded'
117 else:
118 minv = t.getMinval(dev)
119 if minv is not None and value < minv:
120 log.debug('threshold not met')
121 limit = minv
122 how = 'not met'
123
124
125 if how or count:
126 if dev.meta_type == 'Device':
127 devId = dev.id
128 compId = ''
129 else:
130 devId = dev.device().id
131 compId = dev.id
132 if how:
133 self.counts[countKey] += 1
134 severity = t.severity
135 if t.escalateCount and count >= t.escalateCount:
136 severity += 1
137 summary = ('%s %s threshold of %s %s:' %
138 (devId, dp.name(), limit, how) +
139 ' current value %.2f' % float(value))
140 else:
141 self.counts[countKey] = 0
142 severity = 0
143 summary = ('%s %s threshold restored' %
144 (devId, dp.name()) +
145 ' current value: %.2f' % float(value))
146 self.zem.sendEvent(dict(
147 device=devId,
148 summary=summary,
149 eventClass=t.eventClass,
150 eventKey=dp.name(),
151 component=compId,
152 severity=severity))
153