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