Intro

Intro – Introduction to System::ProcWatch

What is System::ProcWatch?

System::ProcWatch is a small collection of classes to ease monitoring of system processes based on the Unix program procps (ps).

To use System::ProcWatch you simply have to define a ruleset on which based System::ProcWatch operates. A rule (or job, watch) defines what actions should happen if a condition evaluates to true.

To be continued...

Shell Scripts

You can use System::ProcWatch out of the box, by utilizing the shipped shell scripts procwatch and procwatch-lint.

procwatch

The procwatch command is meant to be used for system diagnosis - run as daemon or by cron.

The usage is best described by the output of procwatch -h:


USAGE:
$ procwatch (-x|-i) <file> [-d [-s <sec>]] [-a <args>] [-p <file>]

OPTIONS:
    -x | --xml=         path to XML configuration file
    -i | --ini=         path to INI configuration file

    -d | --daemon       run procwatch in daemon mode
    -s | --sleep=       seconds to sleep in daemon mode (default=1800)

    -a | --args=        arguments that should be passed to ps (default=aux)
    -p | --php=         php file that should be included

    -h | --help         this help message

EXAMPLE:
    $ procwatch -x /etc/procwatch.xml -d -s 3600

    This command will run procwatch in daemon mode with an interval
    of an hour using the configuration file '/etc/procwatch.xml'

procwatch-lint

The procwatch-lint is meant to validate procwatchs configurtation files written in XML by utilizing XML::DTD::XmlValidator.

Once again synopsis is best described by the output of procwatch-lint -h:


USAGE:
$ procwatch-lint -c <file> [-d <dtd>] [-v]

OPTIONS:
    -c | --conf=        path to XML configuration file
    -d | --dtd=         path to DTD
    
    -v | --verbose      verbose output on errors

    -h | --help         this help message

EXAMPLE:
    procwatch-lint -c /etc/procwatch.xml

    This command will validate the configuration file '/etc/procwatch.xml'
    using the DTD at '/usr/share/pear/data/System_ProcWatch/procwatch-1.0.dtd'

Configuration

There are three methods to configure your System::ProcWatch application:

  • XML string/file
  • INI file
  • PHP array

Xml string/file

Configuring System::ProcWatch by XML is the preferred way. It is as simple as powerful.

Ruleset: The Root Element

The root element of an XML configuration file/string is the procwatch element. It has one implicit attribute, the version attribute, set to "1.0".

The procwatch element symbolizes our ruleset, and the childs of the root are our rules.

Rules: The Childs of the Root

The direct descendants of the root element procwatch, are the watch elements, which can occur 1 time or more often.

The watch element has one required attribute, the name attribute, which gives the watch (or job, rule) a descriptive name like "httpd-count".

Each watch element symbolizes a single rule, containing a regular expression to search for, one or more conditions to evaluate and one or more actions to be taken.

A Rule

A rule consists of three child elements:

  • pattern
  • condition
  • execute

Rule Element: pattern

The pattern element describes the perl compatible regular expression which should be evaluated against a column of the output of ps.

There is one required attribute, the match attribute, defining the column name of the output of ps in lowercase like "command" or "vsz".

This makes System::ProcWatch highliy versatile and should make it usable with any platforms procps program.

The pattern elements content solely consists of the perl compatible regular expression to match against the column defined in the match attribute. The PCRE MUST contain the start and end delimiter and MAY contain any PCRE modifiers.

Example: <pattern match="command">/sbin\/httpd/</pattern>

Rule Element: condition

The condition element defines conditions that MUST evaluate to TRUE at all so that later defined actions will be executed.

The condition element has one required and one optional attribute, the required one being type, which MUST be one of "presence" or "attr", and the optional one being attr. However, if the type attribute equals to "attr" the attr attribute MUST be present.

The attr attribute represents a column of procps' output like "user" or "%mem".

Conditions

Dependent on the content of the type attribute, syntax and behavior of the condition element differ.

A condition with type "presence" MAY be empty, thus always evaluating to true.

Child Elements of condition may be:

  • min Found value MUST exceed defined value.
  • max Found value MUST NOT exceed defined value.
  • is Found value MUST be equal to defined value.
  • isnot Found value MUST NOT be equal to defined value.
  • sum The sum of found values MUST NOT exceed defined sum.

You may combine them to define for instance a range from min to max.

Rule Element: execute

The execute element defines actions that should be taken if the condition applies.

It has one required attribute, the type attribute, which MUST equal to one of "shell" or "php".

Obviously the content of the execute element is executed either on the shell through shell_exec() or directly in PHP through eval().

The execute element MAY occur any times.

There are some special variables that will automagically be available in execute statements:

  • $msg This contains a general message, what has happened. It is quoted in single quotes for save usage and is available in shell and php executes.
  • $pids This contains all PIDs of the processes that have been found. They are enclosed by single quotes and parenthesis. Example: '(433, 444, 455, 466)'
  • $procs This is a serialized php array in string format containing all information gained from ps and looks like: array(array('pid' => 344, 'command' => '/usr/sbin/httpd' ...)) It is only available in php executes and can easily be used in function callbacks: <execute type="php">get_procs($procs);</execute>

Example XML configuration file

XML configuration file

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE procwatch SYSTEM "/usr/share/pear/data/System_ProcWatch/procwatch-1_0.dtd">
<procwatch>
<!--

    SOME EXAMPLE CONFIGURATIONS
    ===========================

    This job looks for the count of running httpd processes by
    matching the PCRE "/httpd/" against the COMMAND column of ps.

    If there are less than 10 or more than 30 httpd processes found
    the speicified string is executed on the shell.
-->
  <watch name="httpd-count">
    <pattern match="command">/httpd/</pattern>
    <condition type="presence">
      <min>10</min>
      <max>30</max>
    </condition>
    <execute type="shell">echo $msg $pids &gt;&gt; /var/log/procwatch</execute>
  </watch>

<!--
  This job looks for the amount of physical memory all httpd processes use
  together by matching the PCRE "/httpd/" against the COMMAND column of ps.

  It adds all %MEM columns of ps that match the pattern together and compares
  the reslut to the specified sum. If the result exceeds the sum the specified
  string is executet on the shell.
-->
  <watch name="httpd-usage">
    <pattern match="command">/httpd/</pattern>
    <condition type="attr" attr="%mem">
      <sum>5</sum>
    </condition>
    <execute type="shell">echo $msg $pids &gt;&gt; /var/log/procwatch</execute>
  </watch>

<!--
  This job looks for zombie processes.

  It matches the PCRE "/Z/" against the STAT column of ps and executes the
  specified string on the shell if more than 0 zombies have been found.
-->
  <watch name="ZOMBIES">
    <pattern match="stat">/Z/</pattern>
    <condition type="presence">
      <max>0</max>
    </condition>
    <execute type="shell">echo $msg $pids &gt;&gt; /var/log/procwatch</execute>
  </watch>

<!--
  This job looks for running processes.

  It matches the PCRE pattern "/R/" against the STAT column of ps and executes
  the specified string on the shell if any running processes have been found.
-->
  <watch name="running">
    <pattern match="stat">/R/</pattern>
    <condition type="presence" />
    <execute type="shell">echo $msg $pids &gt;&gt; /var/log/procwatch</execute>
  </watch>

</procwatch>

INI file

Configuring by INI file is effectively the same except that only executes of type "shell" can be defined.

Example INI configuration file

INI configuration file


;
; Example INI file to configure System::ProcWatch
;
; Be aware that you only can define shell executes!
; For better configurability use XML configuration files.
;
[httpd]
pattern=/httpd/
match=command
condition=presence
min=10
max=50
execute="echo $msg >> /var/log/procwatch"

[zombies]
pattern=/Z/
match=stat
condition=presence
max=0
execute="kill -9 `echo $pids | sed s/[,\(\)]//g`"

[mysqld-mem]
pattern=/mysqld/
match=command
condition=attr
attr=%mem
sum=10
execute="echo $msg >> /var/log/procwatch"

PHP array

A valid array to configure System::ProcWatch may look similar to the following example.

Example PHP configuration array

PHP configuration array

<?php
$watches 
= array();

$watches['job1'] = array();
$watches['job1']['pattern'] = array();
$watches['job1']['condition'] = array();
$watches['job1']['execute'] = array();

$watches['job1']['pattern']['command'] = '/httpd/';
$watches['job1']['condition']['presence'] = array('min' => 10'max' => 100);
$watches['job1']['execute']['shell'] = array('/usr/bin/mail2admin $msg');

$watches['job2'] = array();
// ...
?>