Package Products :: Package ZenModel :: Module ZenStatus
[hide private]
[frames] | no frames]

Source Code for Module Products.ZenModel.ZenStatus

  1  ############################################################################## 
  2  #  
  3  # Copyright (C) Zenoss, Inc. 2007, all rights reserved. 
  4  #  
  5  # This content is made available according to terms specified in 
  6  # License.zenoss under the directory where your Zenoss product is installed. 
  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   
32 -class ZenStatus(Persistent):
33 34 conversions = { 35 -2 : "No DNS", 36 -1 : "Not Tested", 37 0 : "Up", 38 } 39
40 - def __init__(self, status=-1):
41 self.status = status
42
43 - def getStatus(self):
44 """get objects current status this is the number of failure 45 increments that have been called""" 46 return self.status
47 48
49 - def getStatusString(self):
50 """get status as a string will convert as per converstions""" 51 return (self.conversions[self.status] 52 if self.status in self.conversions else self.status)
53 54
55 - def setStatus(self, status):
56 self.status = int(status)
57
58 - def incr(self):
59 """increment the failure status""" 60 self.status += 1
61
62 - def reset(self):
63 """reset status when failure is over""" 64 self.status = 0
65
66 - def color(self):
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
78 -class ZenAvailability(ZenStatus):
79
80 - def __init__(self, status=-1):
81 ZenStatus.__init__(self, status) 82 self.failstart = 0 # start of current failure as DateTime 83 self.failincr = 0 # DateTime of last failure increment call 84 self.todaydown = 0 # total downtime today in seconds 85 self.yearlydata = {DateTime().year() : YearlyDownTime()}
86 87
88 - def incr(self):
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
110 - def reset(self):
111 """reset the objects failure status""" 112 self.status = 0 113 self.failstart = 0 114 self.failincr = 0
115 116
117 - def getStatusString(self):
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
130 - def getStatus(self):
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
137 - def getAvailPercent(self, start, end=None):
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
147 - def getAvailPercentString(self, start, end=None):
148 """get availability for a date range as a string for display""" 149 avail = self.getAvailPercent(start, end) 150 if avail < 0: return "Unknown" 151 return "%.3f%%" % self.getAvailPercent(start, end)
152 153
154 - def getAvail30(self):
155 """get the 30 day rolling availability of this object""" 156 return self.getAvailPercent(DateTime()-30)
157 158
159 - def getAvail30String(self):
160 """get the 30 day rolling availability of this object""" 161 return self.getAvailPercentString(DateTime()-30)
162 163
164 - def getDownTime(self, start, end=None):
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
182 - def _getDownTime(self, year, start=None, end=None):
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
190 - def _getYearlyData(self, year):
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
197 -class YearlyDownTime(Persistent):
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
201 - def __init__(self):
202 days = 365 203 if calendar.isleap(DateTime().parts()[0]): days += 1 204 self.daysdown = map(lambda x: 0, range(days))
205 206
207 - def addDaily(self, dailydown):
208 """add the daily down time for a day""" 209 self.daysdown.insert(DateTime().dayOfYear()-1, dailydown) 210 self._p_changed = 1
211 212
213 - def getDownTime(self, start=None, end=None):
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