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

# Source Code for Module Products.ZenStatus.zenstatus

      1  #! /usr/bin/env python
      2  ##############################################################################
      3  #
      4  # Copyright (C) Zenoss, Inc. 2010, all rights reserved.
      5  #
      6  # This content is made available according to terms specified in
      7  # License.zenoss under the directory where your Zenoss product is installed.
      8  #
      9  ##############################################################################
     10
     11
     12  __doc__ = """zenstatus
     13
     14  Check the TCP/IP connectivity of IP services.
     15  UDP is specifically not supported.
     16  """
     17
     18  import logging
     19
     20  from twisted.internet import defer
     21
     22  import Globals
     23  import zope.component
     24  import zope.interface
     25  from Products.ZenStatus.ZenTcpClient import ZenTcpClient
     26  from Products.ZenCollector.daemon import CollectorDaemon
     27  from Products.ZenCollector.interfaces import ICollectorPreferences,\
     28                                               IEventService,\
     29                                               IScheduledTask
     30  from Products.ZenCollector.tasks import SimpleTaskFactory,\
     31                                          SubConfigurationTaskSplitter,\
     32                                          TaskStates, \
     33                                          BaseTask
     34
     35
     36  # We retrieve our configuration data remotely via a Twisted PerspectiveBroker
     37  # connection. To do so, we need to import the class that will be used by the
     38  # configuration service to send the data over, i.e. DeviceProxy.
     39  from Products.ZenUtils.Utils import unused
     40  from Products.ZenCollector.services.config import DeviceProxy
     41  from Products.ZenHub.services.ZenStatusConfig import ServiceProxy
     42  unused(ServiceProxy)
     43  unused(DeviceProxy)
     44
     45  #
     46  # creating a logging context for this module to use
     47  #
     48  log = logging.getLogger("zen.zenstatus")
     49
     50
     51 -class ServiceTaskSplitter(SubConfigurationTaskSplitter):
     52      subconfigName = 'components'
     53 -    def makeConfigKey(self, config, subconfig):
     54          return (config.id, config.configCycleInterval, subconfig.component)
     55
     56
     57  # Create an implementation of the ICollectorPreferences interface so that the
     58  # ZenCollector framework can configure itself from our preferences.
     59 -class ZenStatusPreferences(object):
     60      zope.interface.implements(ICollectorPreferences)
     61
     62 -    def __init__(self):
     63          """
     64          Construct a new ZenStatusPreferences instance and provide default
     65          values for needed attributes.
     66          """
     67          self.collectorName = "zenstatus"
     68          self.defaultRRDCreateCommand = None
     69          self.cycleInterval = 60  # seconds
     70          self.configCycleInterval = 20  # minutes
     71          self.statusCycleInterval = 60
     72          self.options = None
     73
     74          # the configurationService attribute is the fully qualified class-name
     75          # of our configuration service that runs within ZenHub
     76          self.configurationService = 'Products.ZenHub.services.ZenStatusConfig'
     77
     78 -    def buildOptions(self, parser):
     79          """
     80          add any zenstatus specific command line options here
     81          """
     82          pass
     83
     84 -    def postStartup(self):
     85          """
     86          process any zenstatus specific command line options here
     87          """
     88          pass
     89
     90
     91 -class ZenStatusTask(BaseTask):
     92      zope.interface.implements(IScheduledTask)
     93
     94 -    def __init__(self,
     95                   name,
     96                   configId,
     97                   scheduleIntervalSeconds,
     98                   taskConfig):
     99          """
    100          Construct a new task for checking the status
    101
    102          @param deviceId: the Zenoss deviceId to watch
    103          @type deviceId: string
    104          @param taskName: the unique identifier for this task
    105          @type taskName: string
    106          @param scheduleIntervalSeconds: the interval at which this task will be
    107                 collected
    108          @type scheduleIntervalSeconds: int
    109          @param taskConfig: the configuration for this task
    110          """
    111          super(ZenStatusTask, self).__init__(
    112                   name, configId,
    113                   scheduleIntervalSeconds, taskConfig
    114                 )
    115
    116          self.name = name
    117          self.configId = configId
    118          self.interval = scheduleIntervalSeconds
    119          self.state = TaskStates.STATE_IDLE
    120          self.log = log
    121          self.cfg = taskConfig.components[0]
    122          self._devId = self.cfg.device
    123          self._eventService = zope.component.queryUtility(IEventService)
    124          self._preferences = zope.component.queryUtility(ICollectorPreferences,
    125                                                          "zenstatus")
    126
    127 -    def _scan_device(self, ip_address):
    128          log.debug("Scanning device %s (%s) port %s",
    129                    self._devId, ip_address, self.cfg.port)
    130          job = ZenTcpClient(self.cfg, self.cfg.status)
    131          return job.start(ip_address)
    132
    133 -    def doTask(self):
    134          d = self._scan_device(self.cfg.ip)
    135          if self.cfg.ip != self.cfg.deviceManageIp:
    136              d.addCallbacks(self.processTestWithRetry, self.handleExceptions)
    137          else:
    138              d.addCallback(self.processTest)
    139              d.addErrback(self.handleExceptions)
    140          return d
    141
    142 -    def processTestWithRetry(self, result):
    143          """
    144          Test a connection to a device.
    145
    146          @parameter result: device and TCP service to test
    147          @type result: ZenTcpClient object
    148          """
    149          evt = result.getEvent()
    150          if evt:
    151              if evt['severity'] != 0:
    152                  d = self._scan_device(self.cfg.deviceManageIp)
    153                  d.addCallback(self.processTest)
    154                  d.addErrback(self.handleExceptions)
    155                  return d
    156              self._eventService.sendEvent(evt)
    157          return defer.succeed("Connected")
    158
    159 -    def processTest(self, result):
    160          evt = result.getEvent()
    161          if evt:
    162              self._eventService.sendEvent(evt)
    163              if evt['severity'] != 0:
    164                  return defer.succeed("Failed")
    165
    166          return defer.succeed("Connected")
    167
    168 -    def handleExceptions(self, reason):
    169          """
    170          Log internal exceptions that have occurred
    171          from testing TCP services
    172
    173          @param reason: error message
    174          @type reason: Twisted error instance
    175          """
    176          msg = reason.getErrorMessage()
    177          evt = dict(device=self._preferences.options.monitor,
    178                     summary=msg,
    179                     severity=4,  # error
    180                     component='zenstatus',
    181                     traceback=reason.getTraceback())
    182          self._eventService.sendEvent(evt)
    183          return defer.succeed("Failed due to internal error")
    184
    185 -    def cleanup(self):
    186          pass
    187
    188
    189  #
    190  # Collector Daemon Main entry point
    191  #
    192  if __name__ == '__main__':
    193      myPreferences = ZenStatusPreferences()
    194      myTaskFactory = SimpleTaskFactory(ZenStatusTask)
    195      myTaskSplitter = ServiceTaskSplitter(myTaskFactory)
    196      daemon = CollectorDaemon(myPreferences, myTaskSplitter)
    197      daemon.run()
    198