Package Products :: Package ZenRRD :: Package parsers :: Module ps |
[hide private]
[frames] | no frames]

# Source Code for Module Products.ZenRRD.parsers.ps

      1  ###########################################################################
      2  #
      3  # This program is part of Zenoss Core, an open source monitoring platform.
      4  # Copyright (C) 2009, 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
     14  import Globals
     15  from Products.ZenRRD.CommandParser import CommandParser
     16  from Products.ZenEvents.ZenEventClasses import Status_OSProcess
     17
     18  AllPids = {}
     19
     20  emptySet = set()
     21
     22 -class ps(CommandParser):
     23
     24 -    def dataForParser(self, context, datapoint):
     25          id, name, ignoreParams, alertOnRestart, failSeverity = \
     26              context.getOSProcessConf()
     27          return dict(processName=name,
     28                      ignoreParams=ignoreParams,
     29                      alertOnRestart=alertOnRestart,
     30                      failSeverity=failSeverity)
     31
     32 -    def processResults(self, cmd, results):
     33
     34          # map data points by procesName
     35          dps = {}
     36          for dp in cmd.points:
     37              dps.setdefault(dp.data['processName'], []).append(dp)
     38
     39          # group running processes by name (with and without args)
     40          running = {}
     41          for line in cmd.result.output.split('\n')[1:]:
     42              if not line: continue
     43              try:
     44                  pid, rss, cpu, args = line.split(None, 3)
     45                  days = 0
     46                  if cpu.find('-') > -1:
     47                      days, cpu = cpu.split('-')
     48                      days = int(days)
     49                  cpu = map(int, cpu.split(':'))
     50                  if len(cpu) == 3:
     51                      cpu = (days * 24 * 60 * 60 +
     52                         cpu[0] * 60 * 60 +
     53                         cpu[1] * 60 +
     54                         cpu[2])
     55                  elif len(cpu) == 2:
     56                      cpu = (days * 24 * 60 * 60 +
     57                         cpu[0] * 60 +
     58                         cpu[1])
     59                  rss = int(rss)
     60                  pid = int(pid)
     61                  lst = running.setdefault(args, [])
     62                  lst.append( (pid, rss, cpu) )
     63                  lst = running.setdefault(args.split()[0], [])
     64                  lst.append( (pid, rss, cpu) )
     65              except ValueError:
     66                  continue
     67          # report any processes that are missing, and post perf data
     68          for process, points in dps.items():
     69              match = running.get(process, [])
     70              if not match:
     71                  results.events.append(dict(
     72                      summary='Process not running: ' + process,
     73                      eventClass=Status_OSProcess,
     74                      eventGroup='Process',
     75                      component=process,
     76                      severity=points[0].data['failSeverity']
     77                      ))
     78              else:
     79                  totalRss = sum([rss for pid, rss, cpu in match])
     80                  totalCpu = sum([cpu for pid, rss, cpu in match])
     81                  for dp in points:
     82                      if 'cpu' in dp.id:
     83                          results.values.append( (dp, totalCpu) )
     84                      if 'mem' in dp.id:
     85                          results.values.append( (dp, totalRss) )
     86                      if 'count' in dp.id:
     87                          results.values.append( (dp, len(match)) )
     88
     89              # report process changes
     90              device = cmd.deviceConfig.device
     91              before = AllPids.get( (device, process), emptySet)
     92              after = set([pid for pid, rss, cpu in match])
     93              alertOnRestart = points[0].data['alertOnRestart']
     94              if before != after:
     95                  if len(before) > len(after) and alertOnRestart:
     96                      pids = ', '.join(map(str, before - after))
     97                      results.events.append(dict(
     98                          summary='Pid(s) %s stopped: %s' % (pids, process),
     99                          eventClass=Status_OSProcess,
    100                          eventGroup='Process',
    101                          component=process,
    102                          severity=points[0].data['failSeverity']
    103                          ))
    104                  if len(before) == len(after) and alertOnRestart:
    105                      # process restarted
    106                      pids = ', '.join(map(str, before - after))
    107                      results.events.append(dict(
    108                          summary='Pid(s) %s restarted: %s' % (pids, process),
    109                          eventClass=Status_OSProcess,
    110                          eventGroup='Process',
    111                          component=process,
    112                          severity=points[0].data['failSeverity']
    113                          ))
    114                  if len(before) < len(after):
    115                      if len(before) == 0:
    116                          results.events.append(dict(
    117                              summary='Process running: %s' % process,
    118                              eventClass=Status_OSProcess,
    119                              eventGroup='Process',
    120                              component=process,
    121                              severity=0
    122                              ))
    123
    124              AllPids[device, process] = after
    125