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

Source Code for Module ZenModel.ZenStatus

  1  ########################################################################### 
  2  # 
  3  # This program is part of Zenoss Core, an open source monitoring platform. 
  4  # Copyright (C) 2007, Zenoss Inc. 
  5  # 
  6  # This program is free software; you can redistribute it and/or modify it 
  7  # under the terms of the GNU General Public License version 2 as published by 
  8  # the Free Software Foundation. 
  9  # 
 10  # For complete information please visit: http://www.zenoss.com/oss/ 
 11  # 
 12  ########################################################################### 
 13   
 14  from __future__ import division 
 15   
 16  __doc__="""ZenStatus 
 17   
 18  Track status information about some monitored object. 
 19  if status = -1 the object has not been tested 
 20  if status = -2 the object has failed a DNS lookup 
 21  if status = 0 the object has passed its test 
 22  if status > 0 the object has failed its test status times 
 23   
 24  This class should track availability as well!!! 
 25   
 26  $Id: ZenStatus.py,v 1.28 2004/05/11 22:59:23 edahl Exp $""" 
 27   
 28  import calendar 
 29   
 30  from Globals import Persistent 
 31  from DateTime import DateTime 
 32   
 33  defaultColor = "#d02090" 
 34   
35 -class ZenStatus(Persistent):
36 37 conversions = { 38 -2 : "No DNS", 39 -1 : "Not Tested", 40 0 : "Up", 41 } 42
43 - def __init__(self, status=-1):
44 self.status = status
45
46 - def getStatus(self):
47 """get objects current status this is the number of failure 48 increments that have been called""" 49 return self.status
50 51
52 - def getStatusString(self):
53 """get status as a string will convert as per converstions""" 54 return (self.conversions.has_key(self.status) 55 and self.conversions[self.status] or self.status)
56 57
58 - def setStatus(self, status):
59 self.status = int(status)
60
61 - def incr(self):
62 """increment the failure status""" 63 self.status += 1
64
65 - def reset(self):
66 """reset status when failure is over""" 67 self.status = 0
68
69 - def color(self):
70 """get the color to display in the gui""" 71 retval = defaultColor 72 if self.status == 0: 73 retval="#00ff00" 74 elif self.status == -2: 75 retval = "#ff9900" 76 elif self.status > 0: 77 retval = "#ff0000" 78 return retval
79 80
81 -class ZenAvailability(ZenStatus):
82
83 - def __init__(self, status=-1):
84 ZenStatus.__init__(self, status) 85 self.failstart = 0 # start of current failure as DateTime 86 self.failincr = 0 # DateTime of last failure increment call 87 self.todaydown = 0 # total downtime today in seconds 88 self.yearlydata = {DateTime().year() : YearlyDownTime()}
89 90
91 - def incr(self):
92 """increment the failure time of a monitored object 93 if we are in a new day since last failure move old 94 day data to yearly data and reset for todays availability 95 this must be called once a day to work correctly!!!""" 96 if self.failstart == 0: 97 self.failstart = self.failincr = DateTime() 98 if self.status < 0: self.status = 1 99 delta = long((DateTime() - self.failincr) * 86400) 100 if not self.failincr.isCurrentDay(): 101 yavail = self._getYearlyData(self.failstart.year()) 102 now = DateTime() 103 newdaydown = long((now.earliestTime() - now) * 86400) 104 yesterdaydown = self.todaydown + (delta - newdaydown) 105 yavail.addDaily(yesterdaydown) 106 self.todaydown = 0 107 delta = newdaydown 108 self.todaydown += delta 109 self.status += delta 110 self.failincr = DateTime()
111 112
113 - def reset(self):
114 """reset the objects failure status""" 115 self.status = 0 116 self.failstart = 0 117 self.failincr = 0
118 119
120 - def getStatusString(self):
121 """current down time in days hours or seconds""" 122 status = self.getStatus() 123 if self.conversions.has_key(status): 124 return self.conversions[status] 125 dt = DateTime() - self.failstart 126 days = int(dt) 127 hours = int(dt * 24) % 24 128 mins = int(dt * 24*60) % 60 129 secs = round(dt * 86400) % 60 130 return "%dd:%02dh:%02dm:%02ds" % (days, hours, mins, secs)
131 132
133 - def getStatus(self):
134 """get current down time in seconds""" 135 if self.status < 0: return self.status 136 if self.failstart == 0: return 0 137 return round((DateTime() - self.failstart) * 86400)
138 139
140 - def getAvailPercent(self, start, end=None):
141 """get availability for a date range as a float between 100.0 and 0.0""" 142 if self.status < 0: return -1 143 if not end: end = DateTime() 144 delta = long((end - start) * 86400.0) 145 dt = self.getDownTime(start,end) 146 if dt < 0: return dt 147 return 100.0 - ((self.getDownTime(start, end) / delta)*100)
148 149
150 - def getAvailPercentString(self, start, end=None):
151 """get availability for a date range as a string for display""" 152 avail = self.getAvailPercent(start, end) 153 if avail < 0: return "Unknown" 154 return "%.3f%%" % self.getAvailPercent(start, end)
155 156
157 - def getAvail30(self):
158 """get the 30 day rolling availability of this object""" 159 return self.getAvailPercent(DateTime()-30)
160 161
162 - def getAvail30String(self):
163 """get the 30 day rolling availability of this object""" 164 return self.getAvailPercentString(DateTime()-30)
165 166
167 - def getDownTime(self, start, end=None):
168 """calculate the down time in seconds using start and end DateTime 169 if no end is passed the current time is assumed""" 170 if not end: end = DateTime() 171 syear = start.year() 172 eyear = end.year() 173 dt = -1 174 if syear == eyear: 175 dt = self._getDownTime(syear, start, end) 176 else: 177 dt = self._getDownTime(syear, start=start) 178 for y in range(syear+1, eyear): 179 dt += self._getDownTime(y) 180 dt += self._getDownTime(eyear, end=end) 181 if end.isCurrentDay(): dt += self.todaydown 182 return dt
183 184
185 - def _getDownTime(self, year, start=None, end=None):
186 """check to see if we have year data for year and return it""" 187 dt = -1 188 if self.yearlydata.has_key(year): 189 dt = self.yearlydata[year].getDownTime(start, end) 190 return dt
191 192
193 - def _getYearlyData(self, year):
194 """get or create a YearlyDownTime object""" 195 if not self.yearlydata.has_key(year): 196 self.yearlydata[year] = YearlyDownTime() 197 return self.yearlydata[year]
198 199
200 -class YearlyDownTime(Persistent):
201 """this would take less space as a dict with but it would take longer 202 to query not sure which is better going with faster and bigger :)""" 203
204 - def __init__(self):
205 days = 365 206 if calendar.isleap(DateTime().parts()[0]): days += 1 207 self.daysdown = map(lambda x: 0, range(days))
208 209
210 - def addDaily(self, dailydown):
211 """add the daily down time for a day""" 212 self.daysdown.insert(DateTime().dayOfYear()-1, dailydown) 213 self._p_changed = 1
214 215
216 - def getDownTime(self, start=None, end=None):
217 """get the down time in seconds over a date range, dates are DateTime""" 218 if end == None: 219 end = len(self.daysdown) 220 elif isinstance(end, DateTime): 221 end = end.dayOfYear() 222 if start == None: 223 start=1 224 elif isinstance(start, DateTime): 225 start = start.dayOfYear() 226 start -= 1 227 return sum(self.daysdown[start:end])
228