1
2
3
4
5
6
7
8
9
10
11
12
13
14 import time
15
16 from Globals import InitializeClass
17 from Products.ZenUtils import Map
18 from Products.ZenEvents.ZenEventClasses import Status_Ping, Status_Snmp
19 from Products.ZenEvents.ZenEventClasses import Status_OSProcess
20
21 from AccessControl import ClassSecurityInfo
22
23 CACHE_TIME = 60.
24
25 _cache = Map.Locked(Map.Timed({}, CACHE_TIME))
26
30
36
38 security = ClassSecurityInfo()
39 security.setDefaultAccess('allow')
40
41 "Simple record for holding availability information"
42 - def __init__(self, device, component, downtime, total, systems=''):
47
50
53
56
59
62
66
69
74
80
81 InitializeClass(Availability)
82
84 "Determine availability by counting the amount of time down"
85
86 - def __init__(self,
87 startDate = None,
88 endDate = None,
89 eventClass=Status_Ping,
90 severity=5,
91 device=None,
92 component=''):
99
100
104
106 return hash(self.tuple())
107
110
111
112 - def run(self, dmd):
113 """Run the report, returning an Availability object for each device"""
114
115
116 __pychecker__='no-local'
117 zem = dmd.ZenEventManager
118 cols = 'device, component, firstTime, lastTime'
119 endDate = self.endDate or time.time()
120 startDate = self.startDate
121 if not startDate:
122 days = zem.defaultAvailabilityDays
123 startDate = time.time() - days*60*60*24
124 env = self.__dict__.copy()
125 env.update(locals())
126 w = ' WHERE severity >= %(severity)s '
127 w += ' AND lastTime > %(startDate)s '
128 w += ' AND firstTime <= %(endDate)s '
129 w += ' AND firstTime != lastTime '
130 w += " AND eventClass = '%(eventClass)s' "
131 w += " AND prodState >= 1000 "
132 if self.device:
133 w += " AND device = '%(device)s' "
134 if self.component:
135 w += " AND component like '%%%(component)s%%' "
136 env['w'] = w % env
137 s = ('SELECT %(cols)s FROM ( '
138 ' SELECT %(cols)s FROM history %(w)s '
139 ' UNION '
140 ' SELECT %(cols)s FROM status %(w)s '
141 ') AS U ' % env)
142
143 devices = {}
144 conn = zem.connect()
145 try:
146 curs = conn.cursor()
147 curs.execute(s)
148 while 1:
149 rows = curs.fetchmany()
150 if not rows: break
151 for row in rows:
152 device, component, first, last = row
153 last = min(last, endDate)
154 first = max(first, startDate)
155 k = (device, component)
156 try:
157 devices[k] += last - first
158 except KeyError:
159 devices[k] = last - first
160 finally: zem.close(conn)
161 total = endDate - startDate
162 if self.device:
163 deviceList = []
164 device = dmd.Devices.findDevice(self.device)
165 if device:
166 deviceList = [device]
167 devices.setdefault( (self.device, self.component), 0)
168 else:
169 deviceList = [d for d in dmd.Devices.getSubDevices()]
170 if not self.component:
171 for d in dmd.Devices.getSubDevices():
172 devices.setdefault( (d.id, self.component), 0)
173 deviceLookup = dict([(d.id, d) for d in deviceList])
174 result = []
175 for (d, c), v in devices.items():
176 dev = deviceLookup.get(d, None)
177 sys = (dev and dev.getSystemNamesString()) or ''
178 result.append( Availability(d, c, v, total, sys) )
179
180 if self.component:
181 for d in deviceList:
182 for c in d.getMonitoredComponents():
183 if c.name().find(self.component) >= 0:
184 a = Availability(d.id, c.name(), 0, total,
185 d.getSystemNamesString())
186 result.append(a)
187 return result
188
189
190 -def query(dmd, *args, **kwargs):
198
199
200 if __name__ == '__main__':
201 import pprint
202 r = Report(time.time() - 60*60*24*30)
203 start = time.time() - 60*60*24*30
204
205 r.component = None
206 r.eventClass = Status_Snmp
207 r.severity = 3
208 from Products.ZenUtils.ZCmdBase import ZCmdBase
209 z = ZCmdBase()
210 pprint.pprint(r.run(z.dmd))
211 a = query(z.dmd, start, device='gate.zenoss.loc', eventClass=Status_Ping)
212 assert 0 <= float(a[0]) <= 1.
213 b = query(z.dmd, start, device='gate.zenoss.loc', eventClass=Status_Ping)
214 assert a == b
215 assert id(a) == id(b)
216 pprint.pprint(r.run(z.dmd))
217 r.component = 'httpd'
218 r.eventClass = Status_OSProcess
219 r.severity = 4
220 pprint.pprint(r.run(z.dmd))
221 r.device = 'gate.zenoss.loc'
222 r.component = ''
223 r.eventClass = Status_Ping
224 r.severity = 4
225 pprint.pprint(r.run(z.dmd))
226