Hello,

I've created a small perl script that gets zimbra's status using the zmcontrol status command and checks whether the named process is running and then outputs this data into an xml file that can be read by pingdom for custom http checks.

This script is based off of Claude Brassel's "check_zimbra.pl" script which can be found here, and without his help I couldn't have achieved this.

Code:
#!/usr/bin/perl

# This script is based off of Claude Brassel's check_zimbra.pl script which can be found here: 
# http://exchange.nagios.org/directory/Plugins/Email-and-Groupware/check_zimbra-2Epl/details
# This script was created by Arthur Fabre, for any suggestions please send me an email at: [myfirstname][at][myfirstname][mylastname][dot][com]

# This script will issue the zmcontrol status command, analyze the output and also check that named is running.
# This script will directly output the status of zimbra and named. 

# OK means everything is running. 

# If everything is not OK this script will print the status of named (either down or running) followed by the 
# status of zimbra (Running, Critical (if a daemon is no longer running), Warning (if a service has stopped), 
# or ZimbraUnknown.

# This script was designed to be used alongside the "exec" function of a php script in order to generate an xml file to be used
# with pingdom's http custom check. 
# Here is a sample php script that serves this purpose:
# You should replace "path to script" with the path to this script in the "$status = exec('path to script', $output);" line.

# <?PHP
# // Get start time for the execution timer
# $mtime = microtime();
# $mtime = explode(" ",$mtime);
# $mtime = $mtime[1] + $mtime[0];
# $starttime = $mtime;
# 
# // Get end time and calculate execution time
# $mtime = microtime();
# $mtime = explode(" ",$mtime);
# $mtime = $mtime[1] + $mtime[0];
# $endtime = $mtime;
# $totaltime = round(($endtime - $starttime) * 1000, 3); // Time in milliseconds
#
# //Run this script
# $status = exec('path to script', $output);
#
# // Print the XML response
# echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
# <pingdom_http_custom_check>
# 	<status>$status</status>
# 	<response_time>$totaltime</response_time>
# </pingdom_http_custom_check>"
# ?>


############
# Settings #
############

# Set command used to access zimbra status:
$zimbra_status_command='sudo -u zimbra /opt/zimbra/bin/zmcontrol status';

# Set process name of additional process you wish to check:
my @services = ( 'named' );


#############################################################################
# End of configuration, nothing below this line should need to be modified. #
#############################################################################

# Set faulty service and daemon variables to 0, this is needed as the script adds 1 to these values for every script/daemon 
# that isn't running.

$faulty_service=0;
$faulty_daemon=0;


# Execute zmcontrol command and split output on a per service/daemon basis.
# Add 1 to respective faulty service/daemon variables if one is found not to be running.

open (ZMSTATUS, "$zimbra_status_command |");
while (<ZMSTATUS>){
	if (/^Host/){
		my ($tmp, $hostname)=split();
	} else {
		($service, $state)=split();    
	}

	if ( $state eq "Stopped" ){
		$faulty_service++;
	} elsif ( $state eq "is" ){
		$faulty_daemon++;
	}
}
close (ZMSTATUS);


# Compare amount of faulty variables and services. A faulty service will return Warning while a faulty daemon 
# will return Critical.

	if ( $faulty_service >= 0 && $faulty_daemon > 0){
		$zimbra=2;
		$zimbrastatus="Critical";

	} elsif ( $faulty_service > 0 && $faulty_daemon == 0){
		$zimbra=1;
		$zimbrastatus="Warning";

	} elsif ( $faulty_service == 0 && $faulty_daemon == 0){
		$zimbra=0;
		$zimbrastatus="Running";

	} else {
		$zimbra=3;
		$zimbrastatus="Unknown";

	}


# Get status of named.

foreach my $service (@services) {
my $procstatus = `/bin/ps cax | /bin/grep $service`;


# Set variables depending or not on whether named process exists.

	if (!$procstatus) {
		$bind=20;
		$bindstatus="Down";

	} else {
		$bind=10;
		$bindstatus="Running";

	}
}


# Set total status to sum of numerical status' of bind and zimbra and compare this value in order to generate OK message or to 
# print the respective status of bind and zimbra if one of them isn't running properly.

$status = $bind + $zimbra;

	if ($status == 10){
		print "OK";

	} elsif ($status != 10){
		print "Bind " .$bindstatus. ", Zimbra " .$zimbrastatus;

	} else {
		print "Status Unavailable";

	}

exit;
Feel free to post any comments or suggestions to improve this script, I am planning on adding support to check if multiple services other than zimbra are running in the future!

Arthur Fabre