PHP Classes
Icontem

File: as_dbserver_check.php


  Search   All class groups All class groups   Latest entries Latest entries   Top 10 charts Top 10 charts   Newsletter Newsletter   Blog Blog   Forums Forums   Help FAQ Help FAQ  
  Login   Register  
Recommend this page to a friend! ReTweet ReTweet Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Alexander Selifonov  >  Database servers down alarm  >  as_dbserver_check.php  
File: as_dbserver_check.php
Role: Class source
Content type: text/plain
Description: main class module
Class: Database servers down alarm
Send alarm messages when databases are down
 

Contents

Class file image Download
<?php
/**
* @package as_dbserver_check.php - checking DBMS server(s) live state
* @version 1.00.001
* first creation date: 17.06.2009 (dd.mm.yyyy)
* modified 23.06.2009
* @Author Alexander Selifonov,  <alex@selifan.ru>
* @link http://www.selifan.ru
**/
if(!defined('DBTYPE_MYSQL')) define('DBTYPE_MYSQL',1);
if(!
defined('DBTYPE_MSQL')) define('DBTYPE_MSQL',2);
if(!
defined('DBTYPE_POSTGRESQL')) define('DBTYPE_POSTGRESQL',3);
if(!
defined('DBTYPE_ORACLE')) define('DBTYPE_ORACLE',4);
if(!
defined('DBTYPE_MSSQL')) define('DBTYPE_MSSQL',5);
if(!
defined('DBTYPE_DB2')) define('DBTYPE_DB2',6);

class 
CDbChecker {
  var 
$title '';
  var 
$servers = array();
  var 
$ajaxflags = array();
  var 
$homefolder './'# here all 'flag' files for last fb state will be auto-created.
  
var $adminemail ''# primary Admin email(s), all alarms will be sent to this addr.
  
var $ispemail ''# email of your ISP support, to notify them about DB problems
  
var $isptext ''# if message is sent to ISP, Here must be Your text containing client name and/or ID
  
var $emailcharset '';
  var 
$sms_engine ''# sending SMS engine can be attached (external function name !)
  
var $b_errors false;
  var 
$othereason 0# 1 if connect failked due to other reason (wrong login/pass etc) but server is online
  
function CDbChecker($title=''$homefolder=''$isptext='') {
    
$this->title=$title;
    if(
$homefolder!=''$this->homefolder $homefolder;
    
$this->isptext $isptext;
  }
  
/**
  * adds server description to check state
  *
  * @param integer $dbtype (see DBTYPE_xxx constants)
  * @param string $address hostname, connection string (depends on db type)
  * @param string $login
  * @param string $passwd
  * @param string $connfunc explicit function that tries to connect to DB server (used if dbtype undefined)
  * @param string $downtime "hh:mm-hh:mm" - known time interval for database maintenance, when it CAN be down
  */
  
function AddServer($dbtype,$address,$login='',$passwd='',$connfunc=false,$downtime='') {
    
$this->servers[] = array('dbtype'=>$dbtype'address'=>$address,'login'=>$login,'password'=>$passwd'connfunc'=>$connfunc,'downtime'=>$downtime);
  }
  function 
SetEmails($adminemail,$ispemail=''$emailcset='') {
    
$this->adminemail=$adminemail;
    
$this->ispemail=$ispemail;
    if(!empty(
$emailcset)) $this->emailcharset=$emailcset;
  }
  function 
SetSMSEngine($smsfunc='') { $this->sms_engine $smsfunc; }
  
/**
  * main method, it checks all DB servers for 'alive' state and sends alarm merssage if anyone is down.
  *
  */
  
function CheckDbState() { #<2>
    
$alarmtext '';
    
$oktext '';
    
$dbtypestr 'undefined type';
    foreach(
$this->servers as $no=>$srv) { #<3-foreach>
      
$address $srv['address'];
      
$downtime $srv['downtime'];
      
$this->othereason false;
      if(!empty(
$downtime)) {
        
$allow_arr is_array($downtime)? $downtimesplit('-',$downtime);
        
$now date('H:i');
        if(
count($allow_arr)>&& $now>=$allow_arr[0] && $now<=$allow_arr[1])
          echo 
"Database [$address] can be in maintenance mode ({$allow_arr[0]}-$allow_arr[1]), checking skipped...<br />\n";
          continue; 
# registered down time. Don't check
      
}
      
$login $srv['login'];
      
$lnk false;
      
$dberr '';
      switch(
$srv['dbtype']) {

        case 
DBTYPE_MYSQL:
          
$dbtypestr='MySQL';
          
$lnk = @mysql_connect($address$srv['login'],$srv['password']);
          if(
is_resource($lnk)) mysql_close($lnk);
          else 
$dberr = @mysql_error();
          if(
strpos(strtolower($dberr),"can't connect to")===false$this->othereason=true;
          break;

        case 
DBTYPE_MSQL:
          
$dbtypestr='MSQL';
          
$lnk = @msql_connect($address$srv['login'],$srv['password']);
          if(
is_resource($lnk)) msql_close($lnk);
          else 
$dberr = @msql_error();
          
# TODO: define sql errors that not related to server down, an so make $this->othereason=true
          
break;

        case 
DBTYPE_MSSQL:
          
$dbtypestr='MS SQL';
          if(
function_exists('mssql_connect')) {
            
$lnk=mssql_connect($address$srv['login'],$srv['password']);
            if(
is_resource($lnk)) mssql_close($lnk);
          }
          elseif(!empty(
$srv['connfunc']) && function_exists($srv['connfunc'])) {
            
$lnk = @call_user_func($srv['connfunc'], $address,$srv['login'],$srv['password']);
          }
          else continue; 
# extension not loaded, just skip this check
          
break;

        case 
DBTYPE_DB2:
          
$dbtypestr='DB2';
          
$lnk = @db2_connect($address$srv['login'],$srv['password']);
          if(
is_resource($lnk)) db2_close($lnk);
          break;

        case 
DBTYPE_ORACLE:
          
$dbtypestr='Oracle';
          if(
function_exists('oci_connect')) {
            
$lnk= @oci_connect $srv['login'],$srv['password'],$address);
            if(
is_resource($lnk)) oci_close($lnk);
          }
          elseif(
function_exists('ocilogon')) {
            
$lnk= @ocilogon$srv['login'],$srv['password'],$address);
            if(
is_resource($lnk)) ocilogoff($lnk);
          }
          elseif(!empty(
$srv['connfunc']) && function_exists($srv['connfunc'])) {
            
$lnk = @call_user_func($srv['connfunc'], $address,$srv['login'],$srv['password']);
          }
          else continue;
          break;

        case 
DBTYPE_POSTGRESQL:
          
$dbtypestr='PostgreSQL';
          if(
strpos($address,'=')) $addrstrk $address# user passed full connect string: host=XXX user=xxx ..."
          
else {
            
$addrstk '';
            if(
$address$addrstrk.=" host=$address";
            if(!empty(
$srv['login'])) $addrstrk.= ' user='.$srv['login'];
            if(!empty(
$srv['password'])) $addrstrk.= ' password='.$srv['password'];
          }
          
$lnk = @pg_connect($addrstk);
          if(
is_resource($lnk)) pg_close($lnk);
           break;

        default: 
# other DB types must have user defined function for making connect
          
if(!empty($srv['connfunc']) && function_exists($srv['connfunc'])) {
            
$lnk = @call_user_func($srv['connfunc'], $address,$srv['login'],$srv['password']);
          }
          break;
      }
      
$flagfile $this->homefolder."dbserver-down-$no.log";
      
$laststate = !file_exists($flagfile); # true if last state was 'alive', and false if it was dead
      
if($laststate) {
        if(empty(
$lnk)) { # DB server state changed from "alive" to "dead", alarm it !
          
$this->b_errors=true;
          
$fout fopen($flagfile,'w');
          if(
$fout) {
            
fwrite($fout"Server [$address] inaccessible, ".date('Y-m-d H:i'));
            
fclose($fout);
          }
          
$eventxt = ($this->othereason)? 'inaccessible with current credencials':'DOWN';
          
$alarmtext .= "Database Server [$address] is $eventxt, detected time: ".date('Y-m-d H:i').",\n  reason: ($dberr).\n";
        }
      }
      else { 
# previous state - "DEAD",
        
if($lnk) { # DB server state changed from "dead" to "alive"
          
@unlink($flagfile);
          
$oktext .= "Database Server [$address] become alive, detected time: ".date('Y-m-d H:i')."\n";
        }
        else 
$this->b_errors=true;
      }
    } 
#<3-foreach>

    
if(!empty($alarmtext)) { #<3>
      
$headers "Priority:High\r\nX-Mailer: as_dbserver_check";
      if(!empty(
$this->emailcharset)) $headers.="\r\nContent-Type:text/plain; charset=\"{$this->emailcharset}\"";
      
$res1 $res2 'xx';
      if(
$this->adminemail$res1=@mail($this->adminemail,'DB server(s) down/inaccessible !',($this->title."\n".$alarmtext),$headers);
      if(
$this->ispemail && !$this->othereason$res2=@mail($this->ispemail,'DB server(s) down !',($this->isptext."\n".$alarmtext),$headers);
      echo 
"$alarmtext<br />\nemail sending result: {$this->adminemail}: ($res1) {$this->ispemail}:($res2)";

      
# call SMS sending function :
      
if(!empty($this->sms_engine) && function_exists($this->sms_engine)) call_user_func($this->sms_engine,$alarmtext);
    } 
#<3>

    
if(!empty($oktext) ) { #<3>
      
if(!empty($this->adminemail)) $res = @mail($this->adminemail,'DB server(s) up',$oktext,$headers);
      echo 
"$oktext<br />\nemail sending result: {$this->adminemail}: ($res)";

      
# call SMS sending function :
      
if(!empty($this->sms_engine) && function_exists($this->sms_engine)) call_user_func($this->sms_engine,$oktext);
    } 
#<3>

    
if(empty($alarmtext) && empty($oktext))
      echo 
"No changes in servers state, ".($this->b_errors?'Some servers are DOWN':'Everything is OK')."<br />\n";

    return 
$this->b_errors;
  } 
#<2>
# CDbChecker class end
?>

 
  Advertise on this site Advertise on this site   Site map Site map   Statistics Statistics   Site tips Site tips   Privacy policy Privacy policy   Contact Contact  

For more information send a message to :
info at phpclasses dot org.
Copyright (c) Icontem 1999-2009 PHP Classes - PHP Class Scripts
  PHP Book Reviews - Reviews of books and other products