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

Revision as of 21:28, 5 April 2010 by Cfremon (talk | contribs) (Adding headings, article footer, and categories)

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.

Steps to create an external monitor server to monitor Zimbra service status

Install and Configure Apache

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

Create 3 files.

Config file

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 = "";
?>

Status page

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


?>

Layout page

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'/>


<!-- param values may be changed during the XSL Transformation -->
<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[
      <!--
        caption { font-weight: bold; }
        TH {      font-family: MS Sans Serif; font-size: 10pt;background-color: #CCCCCC;border-left: solid 1 #000000;
            border-top: solid 1 #000000;border-bottom: solid 1 #000000;border-right: none;padding-left: 5px;padding-right: 5px;padding-top: 2px;padding-bottom: 2px;}
        .footer { font-family: MS Sans Serif; font-size: 10pt;background-color: #CCCCCC;border-left: solid 1 #000000;
            border-top: solid 1 #000000;border-bottom: solid 1 #000000;border-right: none;padding-left: 5px;padding-right: 5px;padding-top: 2px;padding-bottom: 2px;}
        tr.odd {  background: #eeeeee; }
        tr.even { background: #dddddd; }
        .center { text-align: center; }
      -->
      ]]>
    </style>

</head>

<body>

<table border="1">
<caption><xsl:value-of select="$title"/></caption>
<thead>
<tr>
<th>Server.Service.Status</th>
<th>Time</th>
</tr>
</thead>
    <tbody>
          <xsl:apply-templates select="service_status">
            <xsl:sort select="server" />
            <xsl:sort select="service" />
          </xsl:apply-templates>
        <tr>
        <td colspan="2" class="footer">
        Status of 1 eq Running<br/>
        Status of 0 eq Not Running</td>
        </tr>
    </tbody>
</table>
</body>
</html>

</xsl:template>
<xsl:template match="service_status">
  <tr>
        <xsl:attribute name="class">
      <xsl:choose>
        <xsl:when test="position()mod 2">odd</xsl:when>
        <xsl:otherwise>even</xsl:otherwise>
      </xsl:choose>
    </xsl:attribute>
    <td><xsl:value-of select="server"/>.<xsl:value-of select="service"/>.<xsl:value-of select="status"/></td>
    <td><xsl:value-of select="time"/></td>
  </tr>
</xsl:template>
</xsl:stylesheet>

Start Monitoring Server

Now, just startup apache, and visit the new page you have created: You should get a table like this: (although it is actually in a real html table based on xsl above, but i couldn't figure that out in this wiki)

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!

Back to Monitoring_Tools_Articles


Verified Against: unknown Date Created: 4/2/2010
Article ID: https://wiki.zimbra.com/index.php?title=Alternative_Way_to_monitor_Zimbra_service_status_from_an_external_%22monitor%22_server Date Modified: 2010-04-05



Try Zimbra

Try Zimbra Collaboration with a 60-day free trial.
Get it now »

Want to get involved?

You can contribute in the Community, Wiki, Code, or development of Zimlets.
Find out more. »

Looking for a Video?

Visit our YouTube channel to get the latest webinars, technology news, product overviews, and so much more.
Go to the YouTube channel »

Jump to: navigation, search