1
2
3
4
5
6
7
8
9
10
11 from __future__ import division
12
13 __doc__="""ZenStatus
14
15 Track status information about some monitored object.
16 if status = -1 the object has not been tested
17 if status = -2 the object has failed a DNS lookup
18 if status = 0 the object has passed its test
19 if status > 0 the object has failed its test status times
20
21 This class should track availability as well!!!
22
23 $Id: ZenStatus.py,v 1.28 2004/05/11 22:59:23 edahl Exp $"""
24
25 import calendar
26
27 from Globals import Persistent
28 from DateTime import DateTime
29
30 defaultColor = "#d02090"
31
33
34 conversions = {
35 -2 : "No DNS",
36 -1 : "Not Tested",
37 0 : "Up",
38 }
39
42
44 """get objects current status this is the number of failure
45 increments that have been called"""
46 return self.status
47
48
53
54
57
59 """increment the failure status"""
60 self.status += 1
61
63 """reset status when failure is over"""
64 self.status = 0
65
67 """get the color to display in the gui"""
68 retval = defaultColor
69 if self.status == 0:
70 retval="#00ff00"
71 elif self.status == -2:
72 retval = "#ff9900"
73 elif self.status > 0:
74 retval = "#ff0000"
75 return retval
76
77
79
86
87
89 """increment the failure time of a monitored object
90 if we are in a new day since last failure move old
91 day data to yearly data and reset for todays availability
92 this must be called once a day to work correctly!!!"""
93 if self.failstart == 0:
94 self.failstart = self.failincr = DateTime()
95 if self.status < 0: self.status = 1
96 delta = long((DateTime() - self.failincr) * 86400)
97 if not self.failincr.isCurrentDay():
98 yavail = self._getYearlyData(self.failstart.year())
99 now = DateTime()
100 newdaydown = long((now.earliestTime() - now) * 86400)
101 yesterdaydown = self.todaydown + (delta - newdaydown)
102 yavail.addDaily(yesterdaydown)
103 self.todaydown = 0
104 delta = newdaydown
105 self.todaydown += delta
106 self.status += delta
107 self.failincr = DateTime()
108
109
111 """reset the objects failure status"""
112 self.status = 0
113 self.failstart = 0
114 self.failincr = 0
115
116
118 """current down time in days hours or seconds"""
119 status = self.getStatus()
120 if status in self.conversions:
121 return self.conversions[status]
122 dt = DateTime() - self.failstart
123 days = int(dt)
124 hours = int(dt * 24) % 24
125 mins = int(dt * 24*60) % 60
126 secs = round(dt * 86400) % 60
127 return "%dd:%02dh:%02dm:%02ds" % (days, hours, mins, secs)
128
129
131 """get current down time in seconds"""
132 if self.status < 0: return self.status
133 if self.failstart == 0: return 0
134 return int(round((DateTime() - self.failstart) * 86400))
135
136
138 """get availability for a date range as a float between 100.0 and 0.0"""
139 if self.status < 0: return -1
140 if not end: end = DateTime()
141 delta = long((end - start) * 86400.0)
142 dt = self.getDownTime(start,end)
143 if dt < 0: return dt
144 return 100.0 - ((self.getDownTime(start, end) / delta)*100)
145
146
152
153
155 """get the 30 day rolling availability of this object"""
156 return self.getAvailPercent(DateTime()-30)
157
158
160 """get the 30 day rolling availability of this object"""
161 return self.getAvailPercentString(DateTime()-30)
162
163
165 """calculate the down time in seconds using start and end DateTime
166 if no end is passed the current time is assumed"""
167 if not end: end = DateTime()
168 syear = start.year()
169 eyear = end.year()
170 dt = -1
171 if syear == eyear:
172 dt = self._getDownTime(syear, start, end)
173 else:
174 dt = self._getDownTime(syear, start=start)
175 for y in range(syear+1, eyear):
176 dt += self._getDownTime(y)
177 dt += self._getDownTime(eyear, end=end)
178 if end.isCurrentDay(): dt += self.todaydown
179 return dt
180
181
183 """check to see if we have year data for year and return it"""
184 dt = -1
185 if year in self.yearlydata:
186 dt = self.yearlydata[year].getDownTime(start, end)
187 return dt
188
189
191 """get or create a YearlyDownTime object"""
192 if not year in self.yearlydata:
193 self.yearlydata[year] = YearlyDownTime()
194 return self.yearlydata[year]
195
196
198 """this would take less space as a dict with but it would take longer
199 to query not sure which is better going with faster and bigger :)"""
200
202 days = 365
203 if calendar.isleap(DateTime().parts()[0]): days += 1
204 self.daysdown = map(lambda x: 0, range(days))
205
206
208 """add the daily down time for a day"""
209 self.daysdown.insert(DateTime().dayOfYear()-1, dailydown)
210 self._p_changed = 1
211
212
214 """get the down time in seconds over a date range, dates are DateTime"""
215 if end == None:
216 end = len(self.daysdown)
217 elif isinstance(end, DateTime):
218 end = end.dayOfYear()
219 if start == None:
220 start=1
221 elif isinstance(start, DateTime):
222 start = start.dayOfYear()
223 start -= 1
224 return sum(self.daysdown[start:end])
225