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