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

# Source Code for Module Products.ZenStatus.PingJob

      1  ###########################################################################
      2  #
      3  # This program is part of Zenoss Core, an open source monitoring platform.
      4  # Copyright (C) 2011, 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 or (at your
      8  # option) any later version as published by the Free Software Foundation.
      9  #
     10  # For complete information please visit: http://www.zenoss.com/oss/
     11  #
     12  ###########################################################################
     13
     14  __doc__ = """PingJob
     15  Class that contains the information about pinging an individual IP address.
     16  """
     17
     18  from math import fsum, sqrt, pow
     19  import logging
     20  log = logging.getLogger("zen.PingJob")
     21  import socket
     22
     23  from twisted.internet import defer
     24
     25
     26 -class PingJob(object):
     27      """
     28      Class representing a single target to be pinged.
     29      """
     30 -    def __init__(self, ipaddr, hostname="", status=0,
     31                   ttl=60, maxtries=2, sampleSize=1,
     32                   iface=''):
     33          self.ipaddr = ipaddr
     34          self.iface = iface
     35          self.hostname = hostname
     36          self._ttl = ttl
     37          self.status = status
     38          self.maxtries = maxtries
     39          self.sampleSize = sampleSize
     40          self.points = []  # For storing datapoints
     41
     42          self.family, self._sockaddr = self._getaddrinfo()
     43          self.address = self._sockaddr[0]
     44          self.ipVersion = 4 if self.family == socket.AF_INET else 6
     45          self.data_size = 56
     46
     47          self.reset()
     48
     49 -    def _getaddrinfo(self):
     50          family = socket.AF_UNSPEC
     51          for info in socket.getaddrinfo(self.ipaddr, None, socket.AF_UNSPEC):
     52              family = info[0]
     53              sockaddr = info[-1]
     54              if family in (socket.AF_INET, socket.AF_INET6):
     55                  return family, sockaddr
     56
     57          raise StandardError("Could not resolve IP address '%s' on %s for family %s" % (
     58                              self.ipaddr, self.hostname, family))
     59
     60 -    def reset(self):
     61          self.deferred = defer.Deferred()
     62          self.start = 0
     63          self.sent = 0
     64          self.rcvCount = 0
     65          self.loss = 0
     66          self.message = ""
     67          self.severity = 5
     68          self.inprocess = False
     69
     70          self.results = []
     71          self.rtt = 0
     72          self.rtt_max = 0.0
     73          self.rtt_min = 0.0
     74          self.rtt_avg = 0.0
     75          self.rtt_stddev = 0.0
     76          self.rtt_losspct = 0.0
     77
     78          self._lastSequenceNumber = 0
     79
     80 -    def calculateStatistics(self):
     81          n = len(self.results)
     82          if n == 0:
     83              return
     84
     85          elif n == 1:
     86              self.rtt_avg = self.rtt
     87              self.rtt_max = self.rtt
     88              self.rtt_min = self.rtt
     89              self.rtt_stddev = 0.0
     90              return
     91
     92          total = fsum(self.results)
     93          self.rtt_avg = total / n
     94          self.rtt_stddev = self.stdDev(self.rtt_avg)
     95
     96          self.rtt_min = min(self.results)
     97          self.rtt_max = max(self.results)
     98
     99          self.rtt_losspct = ((self.sent - self.loss) / self.sent) * 100
    100
    101 -    def stdDev(self, avg):
    102          """
    103          Calculate the sample standard deviation.
    104          """
    105          n = len(self.results)
    106          if n < 1:
    107              return 0
    108          # sum of squared differences from the average
    109          total = fsum( map(lambda x: pow(x - avg, 2), self.results) )
    110          # Bessel's correction uses n - 1 rather than n
    111          return sqrt( total / (n - 1) )
    112
    113 -    def pingArgs(self):
    114          self._lastSequenceNumber += 1
    115          echo_kwargs = dict(
    116                             sequence=self._lastSequenceNumber,
    117                             data_size=self.data_size,
    118                             )
    119          socket_kwargs = dict(ttl=self._ttl,)
    120          return self.family, self._sockaddr, echo_kwargs, socket_kwargs
    121
    122 -    def __str__(self):
    123          return "%s %s" % (self.hostname, self.ipaddr)
    124