Alternative Way to monitor Zimbra service status from an external "monitor" server

Revision as of 05:52, 3 April 2010 by Richardteachout (talk | contribs) (Simple way to create a page that can be monitored by an external monitoring system, and check the status of all the zimbra services running and logging to a zimbra_logger)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

I needed a way to monitor a cluster of Zimbra servers (in our case, we are running the OSS edition, but this would work for NE as well) from a remote monitor server. We didn't need details, disk space, just "were the services fully up and running" for the entire cluster. So we found a "poor mans" way to do it, which has worked fantastic for us, so I thought I would share.

First, install Apache (and php is needed for this example), and configure it to run on an alternate port (it is also suggested you firewall this to only be allowed from authorized hosts, but that is beyond this concept page) We have a dedicated server running a mailbox store, with NO users on it, and running logger with centralized syslog from all the server in our cluster of 10 machines, so we did this on that server, as it makes the most sense. You could do this on every/any server running logger however..

Then add something like: <Virtualhost 12.34.yourip.here:81>

       ServerAdmin     support@yourdomain.com
       DocumentRoot    /opt/zimbra/customstat/www
       ServerName      stat01.yourdomain.com
       ErrorLog        /opt/zimbra/customstat/logs/error_log
       CustomLog       /opt/zimbra/customstat/logs/access_log common
      DirectoryIndex index.php

</VirtualHost>

Then make the directory /opt/zimbra/customstat/ (owned by zimbra is OK, just be sure you have a chmod 744 on the directory and a chmod 755 on the files you are about to run) Create 3 files.

The first is a small config file, so name it "config.php"

<?php //Zimbra Logger Service mySQL Connection Information $host = "127.0.0.1:7307"; $mysqluser = "zimbra"; //Change this to call the zimbra function to get the password.. maybe //to get the password, run "/opt/zimbra/bin/zmlocalconfig -s -m nokey zimbra_logger_mysql_password" and put it below $password = ""; ?>

The second is the actual status page. name it "status.php"

<?php

include 'config.php';

if(!$dbconnect = mysql_connect("$host", "$mysqluser", "$password")) {

  print "Connection failed to the host 'localhost'.";
  exit;

} // if if (!mysql_select_db('zimbra_logger')) {

  print "Cannot connect to database 'zimbra_logger'";
  exit;

} // if

$table_id = 'service_status'; $query = "SELECT * FROM $table_id";

$dbresult = mysql_query($query, $dbconnect);

// create a new XML document $doc = new DomDocument('1.0');

// create root node $root = $doc->createElement('root'); $root = $doc->appendChild($root);

// process one row at a time while($row = mysql_fetch_assoc($dbresult)) {

// add node for each row
 $occ = $doc->createElement($table_id);
 $occ = $root->appendChild($occ);
// add a child node for each field
 foreach ($row as $fieldname => $fieldvalue) {
 $child = $doc->createElement($fieldname);
   $child = $occ->appendChild($child);
  $value = $doc->createTextNode($fieldvalue);
   $value = $child->appendChild($value);
 } // foreach

} // while // get completed xml document $xml_string = $doc->saveXML();

// Uncomment below if you are going to use this interface as an XML report //if($_GET['raw']==1){ // print $xml_string; // exit; //}


//print $xml_string; //exit; $xml_doc = new DomDocument; $xml_doc->loadXML($xml_string);

$xp = new XsltProcessor(); // create a DOM document and load the XSL stylesheet

 $xsl = new DomDocument;
 $xsl->load('status.xsl');
 // import the XSL styelsheet into the XSLT process
 $xp->importStylesheet($xsl);
// transform the XML into HTML using the XSL file
 if ($html = $xp->transformToXML($xml_doc)) {
     echo $html;
 } else {
     trigger_error('XSL transformation failed.', E_USER_ERROR);
 } // if


?>

The third is the layout page, name it status.xsl

<?xml version='1.0'?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:output method='html'/>


<xsl:param name="title">Server Status for IPmonitor</xsl:param> <xsl:param name="script">test2.php</xsl:param> <xsl:param name="numrows">0</xsl:param> <xsl:param name="curpage">1</xsl:param> <xsl:param name="lastpage">2</xsl:param> <xsl:param name="script_time">0.2744</xsl:param>

<xsl:template match="root">

<html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/> <title><xsl:value-of select="$title"/></title>

   <style type="text/css">
     <![CDATA[
     ]]>
   </style>

</head>

<body>

<thead> </thead> <tbody> <xsl:apply-templates select="service_status"> <xsl:sort select="server" /> <xsl:sort select="service" /> </xsl:apply-templates> </tbody>
<xsl:value-of select="$title"/>
Server.Service.Status Time

</body> </html>

</xsl:template> <xsl:template match="service_status">

<xsl:attribute name="class"> <xsl:choose> <xsl:when test="position()mod 2">odd</xsl:when> <xsl:otherwise>even</xsl:otherwise> </xsl:choose> </xsl:attribute> <xsl:value-of select="server"/>.<xsl:value-of select="service"/>.<xsl:value-of select="status"/> <xsl:value-of select="time"/> </xsl:template> </xsl:stylesheet> Now, just startup apache, and visit the new page you have: You should get a table Server Status for IPmonitor Server.Service.Status Time ldap01.domain.com.ldap.1 2010-04-03 00:44:01 ldap01.domain.com.snmp.1 2010-04-03 00:44:01 ldap01.domain.com.stats.1 2010-04-03 00:44:01 ldap02.domain.com.ldap.1 2010-04-03 00:44:01 ldap02.domain.com.snmp.1 2010-04-03 00:44:01 For every server logging to this logger, you should see a row with the servername.service.0/1 (0=not running, 1=running) and the date of last update Now, you can use just about any monitoring system to do a GET on the /status.php page, and check for existence of (for example) "ldap01.domain.com.ldap.1" if it doesn't exist or is .0, your monitor wouldn't match, and hence the service is down, so set-off the appropriate alerts to notify your Support team. Yes, all of this could be done using SNMP, but the OSS version doesn't include SNMP natively, and we didn't want to configure it on these servers, so this was a quick way to get the data we needed, without much of any overhead on the server itself, as it was just a sql query, that looked up data that was already being populated. Enjoy!

Jump to: navigation, search