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

Source Code for Module Products.ZenStatus.zenstatus

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