PHP
  Home arrow PHP arrow Page 4 - A Basic Monitoring Engine in PHP
Dev Shed Forums  
Administration  
AJAX  
Apache  
BrainDump  
DHTML  
Flash  
Java  
JavaScript  
Multimedia  
MySQL  
Oracle  
Perl  
PHP  
Practices  
Python  
Reviews  
Security  
Smartphone Development  
Style-Sheets  
Web Services  
XML  
Zend  
Zope  
Mobile Linux  
App Generation ROI  
IBM® developerWorks  
Forums Sitemap  
E-Commerce Hosting  
Linux Web Hosting  
Managed Hosting  
Small Business Hosting  
VPS Hosting  
Weekly Newsletter

 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid  
Request Media Kit
Contact Us  
Site Map  
Privacy Policy  
Support  
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
Google.com  
PHP

A Basic Monitoring Engine in PHP
By: Sams Publishing
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: starstarstarstarstar / 5
    2006-09-14


    Table of Contents:
  • A Basic Monitoring Engine in PHP
  • Giving Up Privileges
  • Combining What You've Learned: Monitoring Services
  • Sample ServiceLogger Process

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      error-file:tidyout.log Del.ici.ous error-file:tidyout.log Digg
      error-file:tidyout.log Blink error-file:tidyout.log Simpy
      error-file:tidyout.log Google error-file:tidyout.log Spurl
      error-file:tidyout.log Y! MyWeb error-file:tidyout.log Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article

     
     
    ADVERTISEMENT


    A Basic Monitoring Engine in PHP - Sample ServiceLogger Process
    ( Page 4 of 4 )

    Here is a sample ServiceLogger process that sends an email to an on-call person when a service goes down:

    class EmailMe_ServiceLogger implements
    ServiceLogger { public function log_service_event(ServiceCheck
    $service) { if($service->current_status ==
    ServiceCheck::FAILURE) { $message = "Problem with
    {$service->description()}\r\n"; mail('oncall@example.com', 'Service Event',
    $message); if($service->consecutive_failures() > 5) { mail('oncall_backup@example.com', 'Service
    Event', $message); } } } public function log_current_status(ServiceCheck
    $service) { return; } }

    If the failure persists beyond the fifth time, the process also sends a message to a backup address. It does not implement a meaningful log_current_status() method.

    You implement a ServiceLogger process that writes to the PHP error log whenever a service changes status as follows:

    class ErrorLog_ServiceLogger implements
    ServiceLogger { public function log_service_event(ServiceCheck
    $service) { if($service->current_status() !==
    $service->previous_status()) { if($service->current_status() ===
    ServiceCheck::FAILURE) { $status = 'DOWN'; } else { $status = 'UP'; } error_log("{$service->description()} changed
    status to $status"); } } public function log_current_status(ServiceCheck
    $service) { error_log("{$service->description()}: $status"); } }

    The log_current_status() method means that if the process is sent a SIGUSR1 signal, it dumps the complete current status to your PHP error log.

    The engine takes a configuration file like the following:

    <config>
     <loggers>
      <logger>
       <id>errorlog</id>
       <class>ErrorLog_ServiceLogger</class>
      </logger>
      <logger>
       <id>emailme</id>
       <class>EmailMe_ServiceLogger</class>
      </logger>
     </loggers>
     <services>
      <service>
       <class>HTTP_ServiceCheck</class>
       <params>
        <description>OmniTI HTTP Check</description>
        <url>http://www.omniti.com</url>
        <timeout>30</timeout>
        <frequency>900</frequency>
       </params>
       <loggers>
        <logger>errorlog</logger>
        <logger>emailme</logger>
       </loggers>
      </service>
      <service>
       <class>HTTP_ServiceCheck</class>
       <params>
        <description>Home Page HTTP Check</description>
        <url>http://www.schlossnagle.org/~george</url>
        <timeout>30</timeout>
        <frequency>3600</frequency>
       </params>
       <loggers>
        <logger>errorlog</logger>
       </loggers>
      </service>
     </services>
    </config>

    When passed this XML file, the ServiceCheckRunner constructor instantiates a logger for each specified logger. Then it instantiates a ServiceCheck object for each specified service.


    Note - The constructor uses the Reflection_Class class to introspect the service and logger classes before you try to instantiate them. This is not necessary, but it is a nice demonstration of the new Reflection API in PHP 5. In addition to classes, the Reflection API provides classes for introspecting almost any internal entity (class, method, or function) in PHP.


    To use the engine you've built, you still need some wrapper code. The monitor should prohibit you from starting it twice—you don't need double messages for every event. It should also accept some options, including the following:

    Option

    Description

    [-f]

    A location for the engine's configuration file, which defaults to monitor.xml.

    [-n]

    The size of the child process pool the engine will allow, which defaults to 5.

    [-d]

    A flag to disable the engine from daemonizing. This is useful if you write a debugging ServiceLogger process that outputs information to stdout or stderr.


    Here is the finalized monitor script, which parses options, guarantees exclusivity, and runs the service checks:

    require_once "Service.inc";
    require_once "Console/Getopt.php";
    
    $shortoptions = "n:f:d";
    $default_opts = array('n' => 5, 'f' =>
    'monitor.xml'); $args = getOptions($default_opts, $shortoptions,
    null); $fp = fopen("/tmp/.lockfile", "a"); if(!$fp || !flock($fp, LOCK_EX | LOCK_NB)) { fputs($stderr, "Failed to acquire lock\n"); exit; } if(!$args['d']) { if(pcntl_fork()) { exit; } posix_setsid(); if(pcntl_fork()) { exit; } } fwrite($fp, getmypid()); fflush($fp); $engine = new ServiceCheckRunner($args['f'],
    $args['n']); $engine->loop();

    Notice that this example uses the custom getOptions() function defined earlier in this chapter to make life simpler regarding parsing options.

    After writing an appropriate configuration file, you can start the script as follows:

    > ./monitor.php -f /etc/monitor.xml 

    This daemonizes and continues monitoring until the machine is shut down or the script is killed.

    This script is fairly complex, but there are still some easy improvements that are left as an exercise to the reader:

    • Add a SIGHUP handler that reparses the configuration file so that you can change the configuration without restarting the server.

    • Write a ServiceLogger that logs to a database for persistent data that can be queried.

    • Write a Web front end to provide a nice GUI to the whole monitoring system.

    Further Reading

    There are not many resources for shell scripting in PHP. Perl has a much longer heritage of being a useful language for administrative tasks. Perl for Systems Administration by David N. Blank-Edelman is a nice text, and the syntax and feature similarity between Perl and PHP make it easy to port the book's Perl examples to PHP.

    php|architect, an electronic (and now print as well) periodical, has a good article by Marco Tabini on building interactive terminal-based applications with PHP and the ncurses extension in Volume 1, Issue 12. php|architect is available online at http://www.phparch.com.

    Although there is not space to cover it here, PHP-GTK is an interesting project aimed at writing GUI desktop applications in PHP, using the GTK graphics toolkit. Information on PHP-GTK is available at http://gtk.php.net.

    A good open-source resource monitoring system is Nagios, available at http://nagios.org. The monitoring script presented in this chapter was inspired by Nagios and designed to allow authoring of all your tests in PHP in an integrated fashion. Also, having your core engine in PHP makes it easy to customize your front end. (Nagios is written in C and is CGI based, making customization difficult.)



     
     
    >>> More PHP Articles          >>> More By Sams Publishing
     

       

    PHP ARTICLES

    - Implementing Factory Methods in PHP 5
    - Merging a File Split for FTP Upload using PHP
    - Getting Data from Yahoo Site Explorer Inboun...
    - Method Chaining: Adding More Selecting Metho...
    - How to Split a File During an FTP Upload Usi...
    - Expanding a Custom CodeIgniter Library with ...
    - Using the Yahoo Site Explorer Inbound Links ...
    - Building a CodeIgniter Custom Library with M...
    - Building an E-mini Trading System Using PHP ...
    - Completing the MySQL Class with Method Chain...
    - Building Dynamic Queries with Chainable Meth...
    - PHP Encryption and Decryption Methods
    - Building a MySQL Abstraction Class with Meth...
    - Completing a Sample String Processor with Me...
    - Mastering WHILE Loops for PHP and MySQL





    © 2003-2009 by Developer Shed. All rights reserved. DS Cluster 5 Hosted by Hostway
    For more Enterprise Application Development news, visit eWeek