My Addon (CHANGEME)

Author Bart Gillis
Compatibility Xymon 4.3.3 and up
Requirements Perl
Download None
Last Update 2012-01-20

This plugin gives you a Geographical map of system failures. As I like geographical mapping of systems and network failures I adapted the very popular plug-in (bb_geo_map.pl by Gary Broadwater) and rewrote the adjusted rewrite of Paul Ohashi so that it's compatible with Xymon, then, I renamed it to xymonmap.pl to avoid confusion. This addon will create an extra column on the server checks named “xymonmap”. Click on the icon and you will see a the map that will only show server failures.

  • Create the folder $XYMONSERVERROOT/server/ext/xymonmap on your xymon server.
  • Put the xymonmap.pl script in this folder.
  • Create a xml file named host_lat_long.xml in this folder.

host_lat_long.xml

<note><?xml version=“1.0” encoding=“utf-8”?> <!– #PO NOTE: Latitude and Longitude will be reversed depending on which hemisphere you're in.

Here's a web site to get lat/long coordinates: http://universimmedia.pagesperso-orange.fr/geo/loc.htm
Examples below:

–> <locales>

<locale>
  <!--Leuven-->
  <server1>
    <lat>4.726927924476203</lat>
    <long>50.84755415890105</long>
  </server1>
  <!--Hasselt-->
  <server2>
    <lat>5.3671013244578525</lat>
    <long>50.929928404650994</long>
  </server2>
  <!--Leuven-->
  <server3>
    <lat>4.726927924476203</lat>
    <long>50.84755415890105</long>
  </server3>
  <!-- Aliso Viejo, CA - Quest HQ -->
  <!--<win7-netbook-01.ohashisan.com><lat>-117.72460</lat><long>33.58488</long></win7-netbook-01.ohashisan.com>-->
  <!-- Ho Chi Minh, Vietnam -->
  <!--<alv209213.prod.quest.corp><lat>106.62913</lat><long>10.79306</long></alv209213.prod.quest.corp>-->
</locale>

</locales></note>

  • Now edit the tasks.cfg file in the $XYMONSERVERROOT/server/etc folder and add the extra task
  • Restart the xymon deamon.

tasks.cfg

Show Code ⇲

Hide Code ⇱

[xymonmap] 
	ENVFILE $XYMONHOME/etc/xymonserver.cfg
	CMD $XYMONHOME/ext/xymonmap/xymonmap.pl
	LOGFILE $XYMONSERVERLOGS/xymonmap.log 
	INTERVAL 1m

xymonmap.pl

Show Code ⇲

Hide Code ⇱

#!/usr/bin/perl
###################################################################
# Company: Quest Software
# Author: Gary Broadwater
# Purpose: Watch XYMON hist dir and gen a geo map dynamic with text.
###################################################################
#
# Modified a bit by Paul Ohashi - Quest Software
# Ported to Xymon by Bart Gillis - Bacaselo
#
# This external script should be executed on the 
# XYMONServer machine. The CONIFIG section below should be the only 
# thing that needs your attention. 
#
# $xymon_web_server - should be set to your XYMONDISPLAY server.
#
# $xymon_hist_path - should be equal to the "history Location" on the
# XYMONServer.
#
# $xymon_hist - is where the output goes and the filename (xymonmap) will 
# be the column name for this test on the XYMONDISPLAY.
#
# $lat_long_ref - is where the host_lat_long.xml file is.
#
###################################################################

use strict;
use XML::Simple;
$XML::Simple::PREFERRED_PARSER = 'XML::Parser';

my $XYMONHOME = "/opt/mms/server";
my $XYMON = "$XYMONHOME/bin/xymon";
my $localhost = "localhost.localdomain";
my $cgiloc = "mms-cgi";
#PO - More information for the status message
my $theEpoch	= time();
my $kaoDate	= localtime($theEpoch);
#PO -	Declare $machineName and $testName and concatenate them for the links on the pop-ups.
#	$XYMESSAGE is for UNIX/Linux
my ($machineName, $testName, $XYMESSAGE);

######################## START CONFIG
# Might need some debug
my $DEBUG	= 'N';

# You should use an FQDN or IP address of the XYMONServer
my $xymon_web_server =  "192.168.56.102";

# The top URL directory name for the Xymon webpages
my $xymon_web_folder = 'mms';

# This is the path to the XYMON 'history Location'
my $xymon_hist_path = '/opt/mms/data/hist/';

# This is the output
my $xymon_hist = '/opt/mms/data/hist/xymonmap';

# This is the xml config file for lat/long positions of your devices
my $lat_long_ref = XMLin("$XYMONHOME/ext/xymonmap/host_lat_long.xml");

#-------- Define the initial lat/long to display in the report
my $init_lat = '17.10430';		#
my $init_long = '45.34530';	# This configuration is for the Servië view
my $init_zoom_level = '4';		#

######################## END CONFIG

# Start out green, if anything is wrong we'll turn yellow because we don't 
# want to get paged for a yellow alarm, do we?
my $testFailed;
my $COLOR = '';
my $device = ' ';
my $sitecolor = "green";
my $pin_message;
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
$year = $year + 1900;

# Start a log file, if it's empty when the script ends we'll delete it - so if it's there you know something went wrong.
my $ERRORFILE = "/var/log/mms/xymon_geo_map.log";
open (STDERR, ">${ERRORFILE}");
open(OUT, "> $xymon_hist") or die "Can't open $xymon_hist\n";

#PO - I changed the order of things here. XYMON needs a status color in the first line of a status
#     report or things won't work right. So, I call html_start() in the process_data subroutine.
#html_start();
process_data();
html_end();
close(OUT);

###################################################################

sub process_data {

  opendir(DIN, $xymon_hist_path);
  my @xymon_hist_contents = sort    readdir (DIN);
  closedir(DIN);
#  sort(@xymon_hist_contents);
  my (@ary_alert_locales,$alert_locales);

  for my $lf (@xymon_hist_contents) {
#  my $lftest = "$lf\n";
#  print $lftest;
    my (@l1, @l1x, $color, $mpart1, $pin_message, $last_line);
    my @tmp = split(/\./,$lf);
    my $target_node = $tmp[0];
    #PO - substitute the commas for dots, but, this has to be converted back for the links to each status message on the pop-ups, PAINFUL!!!
    $target_node	=~ s/,/./g;
print "TARGET_NODE: $target_node\n" if ($DEBUG eq 'Y');
print "sitecolor:  $sitecolor\n" if ($DEBUG eq 'Y');
    open (IN, "< " . $xymon_hist_path . $lf);
    while (<IN>){
	  if (eof) {$last_line = $_;
      chomp $_;
        @l1= split(/$year/,$_);
        $mpart1 = $l1[0];	
        @l1x= split(/\s/,$l1[1]);
        $color = $l1x[1];
		$testFailed = 0;
		$testFailed = 1 if ($color eq 'red' || $color eq 'purple'|| $color eq 'yellow');
#		$testFailed = 1 if ($color eq 'red' || $color eq 'purple');
	#PO - change commas to dots in the log file name
	($machineName, $testName)	= split(/\./, $lf, 2);
	$lf =~ s/,/./g;
	#PO - DEBUG output
	print "Test Failed [$testFailed]: $lf - $mpart1 - $color\n\n" if ($color ne 'green' && $color ne 'clear' && $DEBUG eq 'Y');
      }
    }
    close(IN);        

    if ($testFailed == 1) {

#	$COLOR = 'yellow';
	$COLOR = 'green';

$machineName	=~ s/\.[A-z]+$//g;
$machineName	=~ s/\.//g;
	if ($device eq $machineName){
		if ($color eq 'red' || $sitecolor eq 'red') {
		$sitecolor = "red";
		}elsif ($color eq 'purple' && $sitecolor ne 'red'){
		$sitecolor = "purple";
		}elsif ($color eq 'yellow' && ($sitecolor ne 'red' || $sitecolor ne 'purple')){
		$sitecolor = "yellow";
		}else {$sitecolor = "green";
		}
	} else {$sitecolor = "green";
	}
$device = $machineName;
next if ($color eq 'green' || $color eq 'clear');
	# PO DEBUG output
	print "machineName: ${machineName} - Test: $testName - Color: $color\n" if ($DEBUG eq 'Y');
		$pin_message .= '<html><br><font color=' . $color . '><A HREF=\\"http://' . $xymon_web_server . '/' . $cgiloc . '/svcstatus.sh?HOST=' . ${machineName} . '&SERVICE=' . ${testName} . '\\">' . $lf . '<img src=\"/mms/gifs/' . $color . '.gif\">' . ' [ '. $color . ' ]' . '</A></font></html>';
	#PO DEBUG output
	print "<html><br><font color=' . $color . '><A HREF=\"http://' . $xymon_web_server . '/' . '$cgiloc/svcstatus.sh?HOST=' . $lf . '\">' . $lf . ' [ '. $color . ' ]' . '</A></font></html>" if ($DEBUG eq 'Y');
        $alert_locales->{$lat_long_ref->{locale}->{$target_node}->{lat}}->{$lat_long_ref->{locale}->{$target_node}->{long}}->{message} .= $pin_message;
        my $tmp_locale = $lat_long_ref->{locale}->{$target_node}->{lat} . ',' . $lat_long_ref->{locale}->{$target_node}->{long};
        unless ($tmp_locale eq ',') {
	  push(@ary_alert_locales, $tmp_locale); 
        }
    }
print "sitecolor-last:  $sitecolor\n" if ($DEBUG eq 'Y');	
  }

  my %seen;
  my @pin_it = sort grep(!$seen{$_}++, @ary_alert_locales);

  html_start();

  for my $pinpoint (@pin_it) {
    my @ptmp = split(/,/,$pinpoint);
    print (OUT 'AddPin(' . $ptmp[1] . ',' . $ptmp[0] . ',"Active XYMON Alerts","' . $alert_locales->{$ptmp[0]}->{$ptmp[1]}->{message} . '");');
  }

}

###################################################################

sub html_start() {
  $COLOR = 'yellow' if ($testFailed == 1);
  print (OUT '<img src=/mms/gifs/' . $sitecolor . '.gif> ' . "${kaoDate}\n<strong>We have 1 datacenters in Hasselt and 1 in Leuven</strong>.\n");        
  print (OUT '     <script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.3"></script>' . "\n");
      
  print (OUT '    <script>' . "\n");
  print (OUT '    var map = null;' . "\n");
  print (OUT '    var pinID = 1;' . "\n");
  print (OUT '    var g_DeviceLocales;        ' . "\n");
            
  print (OUT '	function GetMap()' . "\n");
  print (OUT '  {' . "\n");
  print (OUT '     	map = new VEMap("XYMONMap");         ' . "\n");
  print (OUT '		map.LoadMap(new VELatLong(' . $init_long . ', ' . $init_lat . '), ' . $init_zoom_level . ' ,"h" , false);' . "\n");
  print (OUT '		PushPins();' . "\n");
  print (OUT '	}' . "\n");
      
  print (OUT '    function ShowControl()' . "\n");
  print (OUT '  {' . "\n");
  print (OUT '  	map.ShowDashboard();' . "\n");
  print (OUT '  }' . "\n");
    
  print (OUT '  function HideControl()' . "\n");
  print (OUT '  {' . "\n");
  print (OUT '  	map.HideDashboard();' . "\n");
  print (OUT '  }' . "\n");
  print (OUT '  function AddPin(long_in,lat_in,device_in,alert_in)' . "\n");
  print (OUT '  {   ' . "\n");
  print (OUT '  	var pin = new VEPushpin(' . "\n");
  print (OUT '      pinID, ' . "\n");
  print (OUT '      new VELatLong(long_in, lat_in), ' . "\n");

#  print (OUT '      "/mms/gifs/red.gif", ' . "\n");
  print (OUT '      "/mms/gifs/' . $sitecolor . '-recent.gif", ' . "\n");
#  print (OUT '      \'<img src="/mms/gifs/yellow.gif"> \' + device_in,' . "\n");
  print (OUT '      \'<img src="/mms/gifs/' . $sitecolor . '.gif"> \' + device_in,' . "\n");
  print (OUT '      alert_in,' . "\n");
  print (OUT '      "iconStyle",' . "\n");
  print (OUT '      "titleSytle",' . "\n");
  print (OUT '      "detailsStyle"' . "\n");
  print (OUT '      );' . "\n");
            
  print (OUT '      map.AddPushpin(pin);' . "\n");
  print (OUT '      pinID++;' . "\n");
  print (OUT '  }' . "\n");

  print (OUT '  function PushPins()' . "\n");
  print (OUT '  {   ' . "\n");

}

###################################################################

sub html_end() {

 print (OUT '  }' . "\n");
 print (OUT '</script>' . "\n");
 print (OUT '  <body onload="GetMap();">  ' . "\n");
 print (OUT '    <div id="XYMONLabel" align="center"><!--font size=2 color="FFFFFF">XYMON Geo Map</font-->' . "\n");
 print (OUT '   </div>' . "\n");
 print (OUT '   <div id="XYMONMap" style="position:relative; width:900px; height:450px;"></div><br>' . "\n");

}

close (STDERR);
if(-z $ERRORFILE) { unlink $ERRORFILE; }

#my $cmd = "$XYMON localhost \"status $localhost.xymonmap $COLOR `date`: XYMON map\n<iframe src=\"http://$xymon_web_server/$xymon_web_folder/html/xymonmap.html\" width=\"930\" height=\"522\" align=\"center\"></iframe>\"";
my $cmd = "$XYMON localhost \"status $localhost.xymonmap $COLOR `date`: XYMON map\n<object data=\"http://$xymon_web_server/$xymon_web_folder/html/xymonmap.html\" width=\"930\" height=\"522\"> <embed src=http://$xymon_web_server/$xymon_web_folder/html/xymonmap.html width=\"900\" height=\"522\"> </embed> Error: Embedded data could not be displayed. </object>\"";

#print "$cmd\n";
system ($cmd);

`mv $xymon_hist $XYMONHOME/www/html/xymonmap.html`;

###################################################################
=begin README

The xymon_geo_map.pl script is AS IS.  
Use it as you wish and at your own risk.

If you dont have the Perl modules installed or ppm cant find them, 
you can get them from cpan OR google them and find the ppd.

What does it do?  It will read in the 
big brother logs directory for alert color items and pinpoint
then on a map driven by Microsoft Virtual Earth Framework. You can
run this at the command line , so you can use the windows
task scheduler to run it as often as you wish, or some
other scheduling mechanism, add some code to cycle using
sleep and encpsulating it in a subroutine, or get fancy
and gen a service out of the script.  It does the baseline
stuff for you.  Note that if you do not specify the nodes you
want to map in teh host_lat_long.xml, then they will not 
pinpoint on the map when they are in a n alert state.

ENJOY!!

=end README
=cut
###################################################################
#
#PO - Added for perldoc:
#
=head1 DESCRIPTION

The xymon_geo_map.pl script is AS IS.  
Use it as you wish and at your own risk.

If you dont have the Perl modules installed or ppm cant find them, 
you can get them from cpan OR google them and find the ppd.

What does it do?  It will read in the 
xymon hist directory for alert color items and pinpoint
then on a map driven by Microsoft Virtual Earth Framework. You can
run this at the command line , so you can use the cron
task scheduler to run it as often as you wish, or some
other scheduling mechanism, add some code to cycle using
sleep and encpsulating it in a subroutine, or get fancy
and gen a service out of the script.  It does the baseline
stuff for you.  Note that if you do not specify the nodes you
want to map in teh host_lat_long.xml, then they will not 
pinpoint on the map when they are in a n alert state.

ENJOY!!

=head1 NOTE

#PO - This plug-in does not display with more than 3 devices listed in host_lat_long.xml, investigating...

=head1 AUTHOR

Gary Broadwater - Modified by Paul Ohashi to work as a plug-in for Big Brother.
		- Modified by Bart Gillis to work as a plug-in for XYMON.
  • 2012-01-20
    • Initial release
  • 2016-09-20
    • Added alert color code onto the failing site.
    • Changed webpage embedding in the Xymon page from iFrame to HTML5 embed TAG.
  • addons/xymonmap.txt
  • Last modified: 2016/09/20 12:01
  • by b-art