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
75 InitializeClass(Availability)
76
78 "Determine availability by counting the amount of time down"
79
93
94
98
100 return hash(self.tuple())
101
104
105
106 - def run(self, dmd):
107 """Run the report, returning an Availability object for each device"""
108
109
110 zem = dmd.ZenEventManager
111 cols = 'device, component, firstTime, lastTime'
112 endDate = self.endDate or time.time()
113 startDate = self.startDate
114 if not startDate:
115 days = zem.defaultAvailabilityDays
116 startDate = time.time() - days*60*60*24
117 env = self.__dict__.copy()
118 env.update(locals())
119 w = ' WHERE severity >= %(severity)s '
120 w += ' AND lastTime > %(startDate)s '
121 w += ' AND firstTime <= %(endDate)s '
122 w += ' AND firstTime != lastTime '
123 w += " AND eventClass = '%(eventClass)s' "
124 if self.device:
125 w += " AND device = '%(device)s' "
126 if self.component:
127 w += " AND component like '%%%(component)s%%' "
128 env['w'] = w % env
129 s = ('SELECT %(cols)s FROM ( '
130 ' SELECT %(cols)s FROM history %(w)s '
131 ' UNION '
132 ' SELECT %(cols)s FROM status %(w)s '
133 ') AS U ' % env)
134
135 devices = {}
136 conn = zem.connect()
137 try:
138 curs = conn.cursor()
139 curs.execute(s)
140 while 1:
141 rows = curs.fetchmany()
142 if not rows: break
143 for row in rows:
144 device, component, first, last = row
145 last = min(last, endDate)
146 first = max(first, startDate)
147 k = (device, component)
148 try:
149 devices[k] += last - first
150 except KeyError:
151 devices[k] = last - first
152 finally: zem.close(conn)
153 total = endDate - startDate
154 if self.device:
155 deviceList = [dmd.Devices.findDevice(self.device)]
156 devices.setdefault( (self.device, self.component), 0)
157 else:
158 deviceList = [d for d in dmd.Devices.getSubDevices()]
159 if not self.component:
160 for d in dmd.Devices.getSubDevices():
161 devices.setdefault( (d.id, self.component), 0)
162 deviceLookup = dict([(d.id, d) for d in deviceList])
163 result = []
164 for (d, c), v in devices.items():
165 dev = deviceLookup.get(d, None)
166 sys = (dev and dev.getSystemNamesString()) or ''
167 result.append( Availability(d, c, v, total, sys) )
168
169 if self.component:
170 for d in deviceList:
171 for c in d.getMonitoredComponents():
172 if c.name().find(self.component) >= 0:
173 a = Availability(d.id, c.name(), 0, total,
174 d.getSystemNamesString())
175 result.append(a)
176 return result
177
178
179 -def query(dmd, *args, **kwargs):
187
188
189 if __name__ == '__main__':
190 import pprint
191 r = Report(time.time() - 60*60*24*30)
192 start = time.time() - 60*60*24*30
193
194 r.component = None
195 r.eventClass = Status_Snmp
196 r.severity = 3
197 from Products.ZenUtils.ZCmdBase import ZCmdBase
198 z = ZCmdBase()
199 pprint.pprint(r.run(z.dmd))
200 a = query(z.dmd, start, device='gate.zenoss.loc', eventClass=Status_Ping)
201 assert 0 <= float(a[0]) <= 1.
202 b = query(z.dmd, start, device='gate.zenoss.loc', eventClass=Status_Ping)
203 assert a == b
204 assert id(a) == id(b)
205 pprint.pprint(r.run(z.dmd))
206 r.component = 'httpd'
207 r.eventClass = Status_OSProcess
208 r.severity = 4
209 pprint.pprint(r.run(z.dmd))
210 r.device = 'gate.zenoss.loc'
211 r.component = ''
212 r.eventClass = Status_Ping
213 r.severity = 4
214 pprint.pprint(r.run(z.dmd))
215