Package Products :: Package ZenUtils :: Module DaemonStats |
[hide private]
[frames] | no frames]

# Source Code for Module Products.ZenUtils.DaemonStats

      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  import Globals
     14  from Products.ZenUtils.Utils import zenPath
     15
     16  # FIXME dependency from Utils to Thresholds
     17  from Products.ZenRRD.Thresholds import Thresholds
     18
     19  import rrdtool
     20  import os
     21  import time
     22
     23  import logging
     24  log = logging.getLogger("zen.DaemonStats")
     25
     26 -def fullname(partial):
     27      return zenPath('perf', partial + '.rrd')
     28
     29 -class DaemonStats:
     30      "Utility for a daemon to write out internal performance statistics"
     31
     32      name = ""
     33      monitor = ""
     34      rrdCreateCommand = ""
     35
     36 -    def __init__(self):
     37          self.thresholds = Thresholds()
     38
     39
     40 -    def config(self, name, monitor, thresholds, rrdCreateCommand = None):
     41          """Initialize the object.  We could do this in __init__, but
     42          that would delay creation to after configuration time, which
     43          may run asynchronously with collection or heartbeats.  By
     44          deferring initialization, this object implements the Null
     45          Object pattern until the application is ready to start writing
     46          real statistics.
     47          """
     48          self.name = name
     49          self.monitor = monitor
     50          if not rrdCreateCommand:
     51              from Products.ZenModel.PerformanceConf import PerformanceConf
     52              rrdCreateCommand = PerformanceConf.defaultRRDCreateCommand
     53          if type(rrdCreateCommand) != type(''):
     54              self.createCommand = rrdCreateCommand
     55          else:
     56              self.createCommand = rrdCreateCommand.split('\n')
     57          self.thresholds = Thresholds()
     58          self.thresholds.updateList(thresholds)
     59
     60
     61 -    def rrdFile(self, type, cycleTime, name, minVal = 'U', maxVal = 'U'):
     62          """Create an RRD file if it does not exist.
     63          Returns the basename of the rrdFile, suitable for checking thresholds.
     64          """
     65          if not self.name: return None
     66          base = os.path.join('Daemons', self.name)
     67          directory = zenPath('perf', base)
     68          if not os.path.exists(directory):
     69              os.makedirs(directory)
     70          base = os.path.join(base, '%s_%s' % (self.monitor, name))
     71          fileName = fullname(base)
     72          if not os.path.exists(fileName):
     73              rrdtool.create(fileName,
     74                             'DS:ds0:%s:%s:%s:%s' % (type,
     75                                                     cycleTime * 3,
     76                                                     minVal,
     77                                                     maxVal),
     78                             *self.createCommand)
     79          return base
     80
     81
     82 -    def derive(self, name, cycleTime, value):
     83          "Write a DERIVE value, return threshold events"
     84          return self.counter(name, cycleTime, value)
     85
     86 -    def counter(self, name, cycleTime, value):
     87          "Write a DERIVE(! NOT COUNTER!) value, return threshold events"
     88          fileName = self.rrdFile('DERIVE', cycleTime, name, 0)
     89          if fileName:
     90              full = fullname(fileName)
     91              try:
     92                  rrdtool.update(full, 'N:%s' % int(value))
     93                  startStop, names, values = \
     94                      rrdtool.fetch(full, 'AVERAGE',
     95                          '-s', 'now-%d' % (cycleTime*2),
     96                          '-e', 'now')
     97                  value = values[0][0]
     98                  if value is not None:
     99                      return self.thresholds.check(fileName, time.time(), value)
    100              except rrdtool.error, err:
    101                  log.error('rrdtool reported error %s %s', err, full)
    102          return []
    103
    104
    105 -    def gauge(self, name, cycleTime, value):
    106          "Write a gauge value, return threshold events"
    107          fileName = self.rrdFile('GAUGE', cycleTime, name)
    108          if fileName:
    109              full = fullname(fileName)
    110              try:
    111                  rrdtool.update(full, 'N:%s' % value)
    112              except rrdtool.error, err:
    113                  log.error('rrdtool reported error %s %s', err, full)
    114          if value is not None:
    115              return self.thresholds.check(fileName, time.time(), value)
    116          return []
    117