Documentation is available at monitor-defs.php
- <?php
- /* ******************************************************************** */
- /* CATALYST PHP Source Code */
- /* -------------------------------------------------------------------- */
- /* This program is free software; you can redistribute it and/or modify */
- /* it under the terms of the GNU General Public License as published by */
- /* the Free Software Foundation; either version 2 of the License, or */
- /* (at your option) any later version. */
- /* */
- /* This program is distributed in the hope that it will be useful, */
- /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
- /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
- /* GNU General Public License for more details. */
- /* */
- /* You should have received a copy of the GNU General Public License */
- /* along with this program; if not, write to: */
- /* The Free Software Foundation, Inc., 59 Temple Place, Suite 330, */
- /* Boston, MA 02111-1307 USA */
- /* -------------------------------------------------------------------- */
- /* */
- /* Filename: monitor-defs.php */
- /* Author: Paul Waite */
- /* Description: A generic set of monitor classes to enable convenient */
- /* checking of systems and services. */
- /* */
- /* ******************************************************************** */
- /** @package monitor */
- include_once("datetime-defs.php");
- /** Lockfile manager */
- ("lockfile-defs.php");
- // ----------------------------------------------------------------------
- // DEFINITIONS & CONSTANTS
- // Condition types..
- /** Aggregate: all conditions */
- ("COND_ALL", -1);
- /** Condition for a passed test */
- ("COND_OK", 0);
- /** Warning condition */
- ("COND_WARNING", 1);
- /** Error condition */
- ("COND_ERROR", 2);
- /** Fatal error condition */
- ("COND_FATAL", 3);
- /** Aggregate: no conditions */
- ("COND_NONE", 100);
- /** Condition is undefined */
- ("COND_UNKNOWN", 101);
- /** Array of condition descriptions */
- = array(
- COND_UNKNOWN => "UNKNOWN",
- COND_OK => "OK",
- COND_WARNING => "WARNING",
- COND_ERROR => "ERROR",
- COND_FATAL => "FATAL"
- );
- // ----------------------------------------------------------------------
- /**
- * A generic monitor class which is used to derive the specific classes
- * which deal with monitoring particular things, such as Postgres,
- * Lucene, file space, file activity etc. Apart from a few utility methods
- * this is mainly a container for messages, and the current condition
- * level of the monitor.
- * @package monitor
- * @access private
- */
- class generic_monitor {
- /** Type of monitor this is */
- var $type = "unspec";
- /** Current condition of this monitor */
- var $condition = COND_UNKNOWN;
- /** Error condition to set, on failure. */
- var $fail_condition = COND_ERROR;
- /** Set of messages for email, per condition */
- var $report_msgs = array();
- /** Set of messages for SMS, per condition */
- var $smstxt_msgs = array();
- /** Conditions which we should ignore */
- var $suppressed_conditions = array();
- // ....................................................................
- /** Define a new generic monitor object. */
- function generic_monitor($type="") {
- if ($type != "") {
- $this->type = $type;
- }
- }
- // ....................................................................
- /** Set the error condition messages for email and SMS.
- * @param integer $condition Condition messages are to be set for
- * @param string $report Report text if error raised
- * @param string $smstxt SMS txt if error raised
- */
- function set_messages($condition, $report, $smstxt="") {
- $this->report_msgs[$condition] = $report;
- $this->smstxt_msgs[$condition] = $smstxt;
- } // set_default_messages
- // ....................................................................
- /** Set the default error condition messages for email and SMS. We
- * only set these messages if there are none already set.
- * @param integer $condition Condition messages are to be set for
- * @param string $report Report text if error raised
- * @param string $smstxt SMS txt if error raised
- */
- function set_default_messages($condition, $report, $smstxt="") {
- if (!isset($this->report_msgs[$condition]) || $this->report_msgs[$condition] == "") {
- $this->report_msgs[$condition] = $report;
- }
- if (!isset($this->smstxt_msgs[$condition]) || $this->smstxt_msgs[$condition] == "") {
- $this->smstxt_msgs[$condition] = $smstxt;
- }
- } // set_default_messages
- // ....................................................................
- /** Suppress the given condition, so it won't be notified */
- function suppress_condition($condition) {
- if (!in_array($condition, $this->suppressed_conditions)) {
- $this->suppressed_conditions[] = $condition;
- }
- } // suppress_condition
- // ....................................................................
- /** Append the given addendum to the end of all the messages
- * that are stored. Used to append dynamic values to the ends
- * of static message content.
- * @param string $addendum String to append to all monitor messages.
- */
- function all_messages_append($addendum) {
- $newmsgs = array();
- foreach ($this->report_msgs as $cond => $msg) {
- $newmsgs[$cond] = $msg . $addendum;
- }
- $this->report_msgs = $newmsgs;
- $newmsgs = array();
- foreach ($this->smstxt_msgs as $cond => $msg) {
- $newmsgs[$cond] = $msg . $addendum;
- }
- $this->smstxt_msgs = $newmsgs;
- } // all_messages_append
- // ....................................................................
- /** Set the monitor condition.
- * @param integer $condition Condition to set the monitor to.
- */
- function set_condition($condition) {
- $this->condition = $condition;
- } // set_condition
- // ....................................................................
- /** Set the monitor condition value to use for 'failed' status. This
- * can be set for certain monitors, such as the 'postgres_monitor' which
- * basically returns a boolean status of Ok/Failed. For more complex
- * multi-condition monitors it is not used. Allows you to be more flexible
- * in what gets returned.
- * @param integer $condition Condition to set the monitor to on failure
- */
- function set_fail_condition($condition) {
- $this->fail_condition = $condition;
- } // set_fail_condition
- // ....................................................................
- /** Return condition message for current condition
- * @return string The monitor message which is to be reported via email
- */
- function reportmsg() {
- return $this->report_msgs[$this->condition];
- } // reportmsg
- // ....................................................................
- /** Return the sms text message for current condition
- * @return string The monitor message which is to be reported via SMS
- */
- function smstxtmsg() {
- return $this->smstxt_msgs[$this->condition];
- } // smstxtmsg
- // ....................................................................
- /** Make the check.
- * @return integer The condition level determined by the checking process.
- */
- function check() {
- // Return condition..
- return $this->condition;
- } // check
- } // generic_monitor class
- // ----------------------------------------------------------------------
- /**
- * A monitor class to exec a script/program on the OS. This allows you
- * to hook up an external script or program to the monitoring system
- * with the flexibility to determine success/failure by return code,
- * or by comparing output with an expected (regex) pattern. The default
- * test is to test the return code of the script/program and if it is
- * zero (0), then the check is deemed to be successful, otherwise not.
- * There is also a flag, in the constructor ($publish_output) which,
- * if true, directs the monitor to include any output lines returned
- * from the script in the email/SMS messages. This can sometimes be
- * useful for providing extra information in error reports.
- * @package monitor
- */
- class exec_monitor extends generic_monitor {
- var $execpath = "";
- var $execparms = "";
- var $success_code = 0;
- var $success_regex = "";
- var $publish_output = false;
- // ....................................................................
- /**
- * Define a new exec check object.
- * @param string $exec Script/program to execute, including any parameters
- * @param string $success_regex Regex to match on output of script/program
- * @param boolean $publish_output Publish script/program output in all messages
- */
- function exec_monitor($exec, $success_regex="", $publish_output=false) {
- $this->generic_monitor("exec");
- $bits = explode(" ", $exec);
- $this->execpath = array_shift($bits);
- $this->execparms = implode(" ", $bits);
- $this->success_regex = $success_regex;
- $this->publish_output = $publish_output;
- // Set the fail condition to COND_ERROR as a default..
- $this->set_fail_condition(COND_ERROR);
- } // exec_monitor
- // ....................................................................
- /**
- * Allows you to specify an integer code which, if returned by the
- * called script/program, will designate success.
- * NOTES:
- * 1) The default code for success is already zero (0), so no need to
- * specify it in that particular case.
- * 2) This code will be over-ridden if you specify a regular expression
- * with the set_success_pattern() method.
- * @param integer $code Return code indicating success
- */
- function set_success_code($code=0) {
- $this->success_code = $code;
- } // set_success_code
- // ....................................................................
- /**
- * Allows you to specify a regular expression which will be applied to
- * the output of the executed script/program and if matched will be
- * taken to mean the check was successful. If specified, this takes
- * the place of the default behaviour of checking the return code.
- * @param string $regex Regular expression to match on output for success
- */
- function set_success_regex($success_regex) {
- $this->success_regex = $success_regex;
- } // set_success_regex
- // ....................................................................
- /** Make the check by executing the script/program which has been
- * specified. We check that this exists and is executable, and raise
- * warnings if not. The success/failure of the check is determined
- * by the settings, but is either done via return code or by returned
- * output matching.
- * @return integer Condition determined by this check
- */
- function check() {
- if (file_exists($this->execpath)) {
- if (is_executable($this->execpath)) {
- $prog = $this->execpath;
- if ($this->execparms != "") {
- $prog .= " $this->execparms";
- }
- // Execute it..
- exec($prog, $outputlines, $returnvar);
- // Check for success or failure..
- if ($this->success_regex != "") {
- $success = (preg_match("/$this->success_regex/", $output, $matches) == 1);
- }
- else {
- $success = ($this->success_code == $returnvar);
- }
- if (!$success) {
- $this->set_condition($this->fail_condition);
- $this->set_default_messages(
- $this->fail_condition,
- "$this->execpath failed",
- "$this->execpath FAILED"
- );
- }
- else {
- $this->set_condition(COND_OK);
- $this->set_default_messages(
- COND_OK,
- "$this->execpath succeeded",
- "$this->execpath OK"
- );
- }
- if ($this->publish_output && count($outputlines) > 0) {
- $this->all_messages_append( " " . implode(" ", $outputlines) );
- }
- }
- else {
- $this->set_condition(COND_WARNING);
- $this->set_default_messages(
- COND_WARNING,
- "$this->execpath not executable"
- );
- }
- }
- else {
- $this->set_condition(COND_WARNING);
- $this->set_default_messages(
- COND_WARNING,
- "$this->execpath not found"
- );
- }
- // Return condition..
- return $this->condition;
- } // check
- } // exec_monitor class
- // ----------------------------------------------------------------------
- /**
- * A monitor class to check when files/directories were last modified.
- * This is a general class which can be used to set limits on how long
- * a file or directory can remain un-modified before warnings and/or
- * errors are issued.
- * @package monitor
- */
- class file_monitor extends generic_monitor {
- // Public
- // Private
- /** Path to the file to monitor
- @access private */
- var $filepath = "";
- /** Seconds before warning message
- @access private */
- var $warnsecs = 0;
- /** Seconds before error condition
- @access private */
- var $errsecs = 0;
- // ....................................................................
- /**
- * Define a new file check object.
- * @param string $filepath Path to file or directory to check
- * @param integer $warnmins Minutes file can be idle before warning issued
- * @param integer $errmins Minutes file can be idle before error raised
- */
- function file_monitor($filepath, $warnmins, $errmins) {
- $this->generic_monitor("file");
- $this->filepath = $filepath;
- $this->warnsecs = $warnmins * 60;
- $this->errsecs = $errmins * 60;
- // Set the fail condition to COND_ERROR as a default..
- $this->set_fail_condition(COND_ERROR);
- } // file_monitor
- // ....................................................................
- /** Make the check on the time the file was last modified and if this
- * is longer than this->warnsecs ago but less than this->errsecs then
- * issue a warning. Otherwise if it is longer than this->errsecs ago
- * then we issue an error message.
- * @return integer Condition determined by this check
- */
- function check() {
- if (file_exists($this->filepath)) {
- $idlesecs = time() - filemtime($this->filepath);
- $hours = floor($idlesecs / 3600);
- $mins = floor(($idlesecs % 3600) / 60);
- $idletime = $hours . "hrs $mins" . "mins";
- if ($idlesecs >= $this->warnsecs && $idlesecs < $this->errsecs) {
- $this->set_condition(COND_WARNING);
- $this->set_default_messages(
- COND_WARNING,
- "$this->filepath idle for",
- "$this->filepath IDLE"
- );
- }
- elseif ($idlesecs > $this->errsecs) {
- $this->set_condition($this->fail_condition);
- $this->set_default_messages(
- $this->fail_condition,
- "$this->filepath idle for",
- "$this->filepath IDLE"
- );
- }
- else {
- $this->set_condition(COND_OK);
- $this->set_default_messages(
- COND_OK,
- "$this->filepath modified at",
- "$this->filepath MOD AT"
- );
- }
- $this->all_messages_append(" $idletime");
- }
- else {
- $this->set_condition(COND_WARNING);
- $this->set_default_messages(
- COND_WARNING,
- "$this->filepath not found"
- );
- }
- // Return condition..
- return $this->condition;
- } // check
- } // file_monitor class
- // ----------------------------------------------------------------------
- /**
- * A monitor class to check if Postgres is up and about. You need to
- * specify a database and a user (and if required, a password) which can
- * be use to test-connect to Postgres. Optionally you can specify the
- * host and port number if connection is over TCP.
- *
- * NOTE: The 'monitor' class which uses this class implements a rule
- * which says that when a monitor (such as this one) returns a
- * FATAL condition, then the checking process will die, having
- * sent notifications out. If you don't want this to return the
- * COND_FATAL condition on failure use the 'set_fail_condition()'
- * method to set it to COND_ERROR.
- * @package monitor
- */
- class postgres_monitor extends generic_monitor {
- // Public
- // Private
- /** Database connection resource ID
- @access private */
- var $dbid = false;
- /** Name of the database to connect to
- @access private */
- var $dbname = "";
- /** Username to connect as
- @access private */
- var $user = "";
- /** Password of username to connect as
- @access private */
- var $password = "";
- /** For TCP connections: hostname to connect to
- @access private */
- var $host = "";
- /** For TCP connections: port to connect to
- @access private */
- var $port = "";
- // ....................................................................
- /**
- * Define a new Postgres monitor object.
- * @param string $dbname Name of the Postgres database
- * @param string $user Username to connect as
- * @param string $password User password, if required
- * @param string $host Hostname for TCP connections
- * @param string $port Port number for TCP connections
- */
- function postgres_monitor($dbname, $user, $password="", $host="", $port="") {
- $this->generic_monitor("postgres");
- $this->dbname = $dbname;
- $this->user = $user;
- $this->password = $password;
- $this->host = $host;
- $this->port = $port;
- // Set the error condition for failure to be fatal, since by
- // default we consider a non-working database to be just that!
- $this->set_fail_condition(COND_FATAL);
- } // postgres_monitor
- // ....................................................................
- /** Make the check, as to whether we can connect to the Postgres DB.
- * If not then return false, else return true.
- * @return boolean True if Postgres could be connected to.
- */
- function check() {
- if ($this->connect()) {
- $this->disconnect();
- $this->set_condition(COND_OK);
- $this->set_default_messages(
- COND_OK,
- "Postgres ($this->dbname) connection success.",
- "POSTGRES ($this->dbname) OK"
- );
- }
- else {
- $this->set_condition($this->fail_condition);
- $this->set_default_messages(
- $this->fail_condition,
- "Postgres ($this->dbname) connection failed.",
- "POSTGRES ($this->dbname) FAILED"
- );
- }
- // Return condition..
- return $this->condition;
- } // check
- // ....................................................................
- /** Connect to the DB. If we succeed, return true, else false.
- * @access private
- */
- function connect() {
- $connstr = "";
- if ($this->host != "") $connstr .= " host=" . $this->host;
- if ($this->port != 0 ) $connstr .= " port=" . $this->port;
- $connstr .= " dbname=" . $this->dbname;
- $connstr .= " user=" . $this->user;
- if ($this->password != "") $connstr .= " password=" . $this->password;
- $connstr = trim($connstr);
- $this->dbid = pg_connect("$connstr");
- return ($this->dbid !== false);
- } // connect
- // ....................................................................
- /** Disconnect from the DB.
- * @access private
- */
- function disconnect() {
- if ($this->dbid !== false) {
- pg_close($this->dbid);
- $this->dbid = false;
- }
- } // diconnect
- } // postgres_monitor class
- // ----------------------------------------------------------------------
- /** A monitor class to check if Lucene is up and about
- * @package monitor
- */
- class lucene_monitor extends generic_monitor {
- // Public
- // Private
- /** The lucene search object
- @access private */
- var $lusearch;
- /** Expected no. of hits
- @access private */
- var $luhits = 0;
- /** Lucene host
- @access private */
- var $luhost = "";
- /** Lucene port
- @access private */
- var $luport = "";
- /** Lucene host abbreviation
- @access private */
- var $luhost_abbrev = "";
- // ....................................................................
- /**
- * Define a new Lucene monitor object. We register the Lucene query to use
- * and the number of hits we expect. You can also specify the hostname
- * and port of the Lucene server here, although Axyl users can leave these
- * out (blank) if they have configured them with setup-system.php.
- * @param string $lusearch Lucene search object, ready to execute
- * @param integer $luhits No of results expected back from Lucene
- * @param string $luhost Hostname of the Lucene server
- * @param string $luport Port number of the Lucene server
- */
- function lucene_monitor($lusearch, $luhits, $luhost="", $luport="") {
- $this->generic_monitor("lucene");
- $this->lusearch = $lusearch;
- $this->luhits = $luhits;
- // Retreive Axyl Lucene connection information if available..
- if ($luhost == "" && class_exists("configuration")) {
- $config = new configuration("sys_control");
- $luhost = $config->value("Lucene Host");
- $luport = $config->value("Lucene Port");
- }
- $this->luhost = $luhost;
- $this->luport = $luport;
- // Abbreviated version of hostname for messages..
- $bits = explode(".", $this->luhost);
- $this->luhost_abbrev = $bits[0];
- // Set the fail condition to COND_ERROR as a default..
- $this->set_fail_condition(COND_ERROR);
- } // lucene_monitor
- // ....................................................................
- /** Make the check on Lucene by firing the query off and checking for
- * the expected number of hits coming back.
- * @return boolean True if Lucene delivered correct number of hits.
- */
- function check() {
- $res = false;
- if (is_object($this->lusearch) && method_exists($this->lusearch, "execute")) {
- $this->lusearch->execute();
- // VALID LUCENE RESPONSE..
- if ($this->lusearch->response->valid) {
- if ($this->lusearch->hitcount == $this->luhits) {
- $res = true;
- $this->set_condition(COND_OK);
- $this->set_default_messages(
- COND_OK,
- "Lucene ($this->luhost_abbrev:$this->luport) hits: " . $this->lusearch->hitcount . "/" . $this->luhits,
- "LUCENE $this->luhost_abbrev HITS: " . $this->lusearch->hitcount . "/" . $this->luhits
- );
- }
- else {
- $this->set_condition($this->fail_condition);
- $this->set_default_messages(
- $this->fail_condition,
- "Lucene ($this->luhost_abbrev:$this->luport) hits: " . $this->lusearch->hitcount . "/" . $this->luhits,
- "LUCENE $this->luhost_abbrev HITS: " . $this->lusearch->hitcount . "/" . $this->luhits
- );
- }
- }
- // INVALID LUCENE RESPONSES..
- else {
- if ($this->lusearch->response->error_message != "") {
- $this->set_condition($this->fail_condition);
- $this->set_default_messages(
- $this->fail_condition,
- "Lucene ($this->luhost_abbrev:$this->luport) error: " . $this->lusearch->response->error_message,
- "LUCENE $this->luhost_abbrev ERROR: " . $this->lusearch->response->error_message
- );
- }
- else {
- $this->set_condition($this->fail_condition);
- $this->set_default_messages(
- $this->fail_condition,
- "Lucene ($this->luhost_abbrev:$this->luport) failed. Luceneserver/network problems?",
- "LUCENE $this->luhost_abbrev UNKNOWN FAILURE."
- );
- }
- }
- }
- // Return condition..
- return $this->condition;
- } // check
- } // lucene_monitor class
- // ----------------------------------------------------------------------
- /**
- * Class which checks for a disk free space condition.
- * @package monitor
- */
- class diskspace_monitor extends generic_monitor {
- // Public
- // Private
- /** Directory to check
- @access private */
- var $fsdir = "";
- /** Threshold (bytes) before warning condition
- @access private */
- var $warnspace = 0;
- /** Threshold (bytes) before error condition
- @access private */
- var $minspace = 0;
- // ....................................................................
- /**
- * @param integer $fsdir A directory on the filesystem to check
- * @param integer $warnspace The threshold to warn of low space (bytes)
- * @param integer $minspace The threshold for critical errors (bytes)
- */
- function diskspace_monitor($fsdir, $warnspace, $minspace) {
- $this->generic_monitor("diskspace");
- $this->fsdir = $fsdir;
- $this->warnspace = $warnspace;
- $this->minspace = $minspace;
- // Set the fail condition to COND_ERROR as a default..
- $this->set_fail_condition(COND_ERROR);
- }
- // ....................................................................
- /**
- * Check the space on the filesystem of the directory specified.
- * @return object The report generated by the checking process.
- */
- function check() {
- if (file_exists($this->fsdir)) {
- $df = disk_free_space($this->fsdir);
- $MB = floor($df / MEGABYTE) . "MB";
- if ($df < $this->warnspace) {
- $this->set_condition(COND_WARNING);
- $this->set_default_messages(
- COND_WARNING,
- "Filesystem of $this->fsdir low on space",
- "FILESYS OF $this->fsdir LOW"
- );
- }
- elseif ($df < $this->minspace) {
- $this->set_condition($this->fail_condition);
- $this->set_default_messages(
- $this->fail_condition,
- "Filesystem of $this->fsdir critical!",
- "FILESYS OF $this->fsdir CRIT!"
- );
- }
- else {
- $this->set_condition(COND_OK);
- $this->set_default_messages(
- COND_OK,
- "Filesystem of $this->fsdir ok",
- "FILESYS OF $this->fsdir OK"
- );
- }
- $this->all_messages_append(" $MB");
- }
- else {
- $this->set_condition(COND_WARNING);
- $this->set_default_messages(
- COND_WARNING,
- "$this->fsdir not found.",
- "$this->fsdir NOT FOUND"
- );
- }
- // Return condition..
- return $this->condition;
- } // check
- } // diskspace_monitor class
- // ----------------------------------------------------------------------
- /** The monitor class. This is the entity which contains the details
- * of what is to be monitored, how it is to be monitored and what to
- * do if a given condition arises.
- * @package monitor
- */
- class monitor {
- // Public
- /** The name of this monitor instance */
- var $name = "";
- /** Address to email monitor messages */
- var $emailto = "";
- /** Address monitor messages come from */
- var $emailfrom = "";
- /** Address to email SMS txt messages */
- var $emailpager = "";
- /** Monitor lockfile path */
- var $lockfilepath = "";
- // Private
- /** Local hostname we are running monitor on
- @access private */
- var $hostname = "";
- /** Whether to use a lockfile
- @access private */
- var $use_lockfile = true;
- /** Monitor lockfile object
- @access private */
- var $lockfile;
- /** True if we are locked via lockfile
- @access private */
- var $locked = false;
- /** Monitor worst case condition
- @access private */
- var $condition = COND_OK;
- /** Report staging for email
- @access private */
- var $reportmsg = "";
- /** Report staging for SMS txt
- @access private */
- var $smstxtmsg = "";
- /** Threshold condition for emailing
- @access private */
- var $email_condition_threshold = COND_WARNING;
- /** Threshold condition for paging
- @access private */
- var $pager_condition_threshold = COND_ERROR;
- /** The current Unix timestamp
- @access private */
- var $tinow;
- /** Schedule of named timeslots for this monitor
- @access private */
- var $schedule;
- /** Array of monitors which do the work
- @access private */
- var $monitors = array();
- // ....................................................................
- /**
- * Create a new monitor object.
- * @param string $name Name of this monitor instance (message prefix)
- * @param string $emailto Email address to send monitor messages to
- * @param string $emailfrom Email from-address for monitor messages
- * @param string $emailpager Email address for pager TXT messages
- * @param string $lockfilepath Path to lockfile (optional)
- */
- function monitor($name="", $emailto="", $emailfrom="", $emailpager="", $lockfilepath="") {
- // Determine hostname..
- exec("hostname", $returnlines);
- if (isset($returnlines[0]) && $returnlines[0] != "") {
- $this->hostname = $returnlines[0];
- }
- // Deal with parameters..
- if ($name == "") {
- $name = "Monitor";
- }
- if ($emailto == "") {
- if (defined("WEBMASTER_EMAIL")) {
- $emailto = WEBMASTER_EMAIL;
- if (defined("APP_NAME")) {
- $emailto = "\"" . APP_NAME . "\" <$emailto>";
- }
- }
- }
- if ($emailfrom == "") {
- if (defined("WEBMASTER_EMAIL")) {
- $emailfrom = WEBMASTER_EMAIL;
- if (defined("APP_NAME")) {
- $emailfrom = "\"" . APP_NAME . "\" <$emailfrom>";
- }
- }
- }
- // Set lockfile path. We also interpret the value 'nolockfile'
- // for this parameter as disabling the locking feature..
- if ($lockfilepath == "") {
- $lockfilepath = str_replace(" ", "_", $name);
- if ($lockfilepath == "") {
- $lockfilepath = "monitor";
- if ( defined("APP_PREFIX")) {
- $lockfilepath .= "_" . APP_PREFIX;
- }
- }
- $lockfilepath .= ".LCK";
- }
- elseif ($lockfilepath == "nolockfile") {
- $this->use_lockfile = false;
- }
- // Store all the parameters..
- $this->name = $name;
- $this->lockfilepath = $lockfilepath;
- $this->emailto = $emailto;
- $this->emailfrom = $emailfrom;
- $this->emailpager = $emailpager;
- // Other settings..
- $this->tinow = time();
- $this->schedule = new schedule();
- } // monitor
- // ....................................................................
- /** Clear all the monitors. */
- function clear() {
- $this->monitors = array();
- $this->reportmsg = "";
- $this->smstxtmsg = "";
- $this->condition = COND_OK;
- } // clear
- // ....................................................................
- /**
- * Lock the monitor. This is a private method which tries to lock the
- * monitor using the lockfile assigned to it.
- * @return boolean True if lock was obtained.
- * @access private
- */
- function lock() {
- global $_ENV;
- $LCK = new lockfile($this->lockfilepath);
- $LCK->set_timelimits(5, 15);
- if ($LCK->create()) {
- $this->locked = true;
- $this->lockfile = $LCK;
- }
- else {
- $lockmon = new generic_monitor();
- switch ($LCK->errorcode) {
- case LCK_E_CREFAIL:
- case LCK_E_FROZEN:
- case LCK_E_READFAIL:
- $lockmon->set_condition(COND_ERROR);
- $lockmon->set_default_messages(
- COND_ERROR,
- $LCK->errormsg(),
- $LCK->errormsg()
- );
- $this->raise_condition($lockmon);
- break;
- case LCK_E_KILLED:
- case LCK_E_KILLED9:
- case LCK_E_IMMORTAL:
- case LCK_E_ORPHAN:
- $lockmon->set_condition(COND_WARNING);
- $lockmon->set_default_messages(
- COND_WARNING,
- $LCK->errormsg(),
- $LCK->errormsg()
- );
- $this->raise_condition($lockmon);
- break;
- }
- }
- return $this->locked;
- } // lock
- // ....................................................................
- /**
- * Unlock the monitor. This is a private method which deletes the
- * lockfile which was being used to block multiple instances.
- * @access private
- */
- function unlock() {
- $res = true;
- if ($this->locked) {
- if ($this->lockfile->remove()) {
- $this->locked = false;
- }
- }
- return $res;
- } // unlock
- // ....................................................................
- /**
- * Sets the threshold at which we will send messages to email & pager.
- * Any conditions equal or worse than the threshold will be sent if
- * the message is not nullstring.
- * @param integer $email_cond Conditions >= this will be reported via email
- * @param integer $pager_cond Conditions >= this will be reported via pager
- */
- function set_condition_thresholds($email_cond, $pager_cond) {
- $this->email_condition_threshold = $email_cond;
- $this->pager_condition_threshold = $pager_cond;
- }
- // ....................................................................
- /**
- * Raise a condition. The single parameter to this method is a monitor
- * object which will have had its check() method called. This contains the
- * resulting condition and any messages to notify.
- * @param object $monitor Monitor object which has had its check() method run
- */
- function raise_condition($monitor) {
- global $condition_desc;
- // Set overall condition, if escalated..
- if ($monitor->condition > $this->condition) {
- $this->condition = $monitor->condition;
- }
- // Report content..
- if ($monitor->reportmsg() != ""
- && $monitor->condition >= $this->email_condition_threshold) {
- $this->reportmsg .= "\r\n" . $condition_desc[$monitor->condition] . ": " . $monitor->reportmsg() . "\r\n";
- }
- // SMS message content..
- if ($monitor->smstxtmsg() != ""
- && $monitor->condition >= $this->pager_condition_threshold) {
- if ($this->smstxtmsg != "") $this->smstxtmsg .= " ";
- $this->smstxtmsg .= $monitor->smstxtmsg();
- }
- } // raise_condition
- // ....................................................................
- /** Method to send notification(s).. */
- function notify() {
- global $condition_desc;
- // Send to mailbox if above email threshold, and we have someone to
- // email to, and we have something to say..
- if ($this->condition >= $this->email_condition_threshold
- && $this->emailto != ""
- && $this->reportmsg != "") {
- $subject = "$this->name ($this->hostname): Monitor Status: " . $condition_desc[$this->condition];
- $headers = "From: $this->emailfrom\n";
- $headers .= "Reply-To: $this->emailfrom\n";
- $headers .= "Errors-To: $this->emailfrom\n";
- $headers .= "Content-Type: text/plain\n";
- $headers .= "X-Mailer: PHP/" . phpversion();
- mail($this->emailto, $subject, $this->reportmsg, $headers);
- }
- // Send to pager if above pager threshold, and we have someone to
- // email-page, and we have something to TXT..
- if ($this->condition >= $this->pager_condition_threshold
- && $this->emailpager != ""
- && $this->smstxtmsg != "") {
- $subject = "$this->name ($this->hostname): " . $condition_desc[$this->condition];
- $headers = "From: $this->emailfrom\n";
- mail($this->emailpager, $subject, $this->smstxtmsg, $headers);
- }
- } // notify
- // ....................................................................
- /** Iterate through all our monitors, checking in each case. Each
- * monitor will implement its own kind of checking and set its
- * condition afterward.
- */
- function check_all_monitors() {
- // Iterate through our monitors..
- foreach ($this->monitors as $mon) {
- $mon->check();
- if (!in_array($mon->condition, $mon->suppressed_conditions)) {
- $this->raise_condition( $mon );
- // Deal with fatal conditions in the time-honoured way..
- if ($mon->condition == COND_FATAL) {
- $this->notify();
- die;
- }
- }
- }
- } // check_all_monitors
- // ....................................................................
- /**
- * Check all monitors. Just iterate through them and raise the conditions
- * contained in the reports each one returns. After collecting the
- * details, we notify anyone which needs to know. If any condition
- * returned from a check is FATAL, then the rule is we stop processing
- * any further checks. Processing is done in order of definition of the
- * monitors added, so put your critical ones first.
- * NOTE: This method always performs a lock() before processing all the
- * monitors, then performs an unlock() at the end.
- */
- function check() {
- // Process if we are not in a 'skip' timeslot..
- $timeslot = $this->schedule->timeslot($this->tinow);
- switch ($timeslot) {
- case "skip":
- return RET_OK;
- break;
- case "warnings":
- $this->set_condition_thresholds(COND_WARN, COND_WARN);
- break;
- case "errors":
- $this->set_condition_thresholds(COND_ERROR, COND_ERROR);
- break;
- case "fatal":
- $this->set_condition_thresholds(COND_FATAL, COND_FATAL);
- break;
- case "verbose":
- $this->set_condition_thresholds(COND_ALL, COND_ERROR);
- break;
- case "testing":
- $this->set_condition_thresholds(COND_ALL, COND_ALL);
- break;
- } // switch
- // Lock the monitor, if we are using a lockfile. If this
- // fails then it is regarded as a fatal error..
- if ($this->use_lockfile) {
- if ($this->lock()) {
- $this->check_all_monitors();
- // Unlock monitor now..
- $this->unlock();
- }
- else {
- // Lock failed, notify them & die..
- $this->notify();
- die;
- }
- }
- // If no lockfile, just do it..
- else {
- $this->check_all_monitors();
- }
- // Notify people who want it..
- $this->notify();
- // Provide return code for caller..
- return $this->condition;
- } // check
- // ....................................................................
- /**
- * Add a time slot to the schedule. This requires two times as per 24hr
- * clock which define a time interval during the day, and gives it a
- * name. You can define any number of these. Timeslots have to be in HH:MM
- * format, separated by a dash "-", eg: '07:30-11:45'.
- * @param mixed $start Start time for timeslot, string datetime or Unix timestamp
- * @param mixed $end End time for timeslot, string datetime or Unix timestamp
- * @param string $name The name or ID associated with this timeslot.
- */
- function add_timeslot($start, $end, $name) {
- $this->schedule->add_timeslot($start, $end, $name);
- } // add_timeslot
- // ....................................................................
- /**
- * Add a new monitor. Eg. file_monitor, postgres_monitor etc. This just
- * stuffs the object in an array ready to be checked.
- * @param object $monitor New monitor object to add to our list
- */
- function add_monitor($monitor) {
- $this->monitors[] = $monitor;
- } // add_monitor
- } // monitor class
- // ----------------------------------------------------------------------
- ?>
Documentation generated by phpDocumentor 1.3.0RC3