We’ve created a map which visualizes Nagios statii on a map. The idea was born a month ago, and it was completed after about three weeks.
Database
I store a code into a MySQL database table:
mysql> SELECT host,stat,led FROM hosttable;
+-------------+------+-----+
| host | stat | led |
+-------------+------+-----+
| host1 | 0 | 0 |
| host2 | 1 | 1 |
...
| host16 | 0 | 16 |
+-------------+------+-----+
PHP
Because the machine with the database table is in our DMZ, I need to access the statii of the individual hosts via HTTP. A simple PHP script does that for me.
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header ('Content-type: text/plain');
if (!($link = mysql_connect('localhost', 'moni', 'phone'))) {
die('Not connected : ' . mysql_error());
}
mysql_select_db('dbname', $link);
$leds = array();
$result = mysql_query("SELECT host,led,stat FROM hosttable");
if ($result) {
while ($row = mysql_fetch_assoc($result)) {
$led = $row['led'];
$host = $row['host'];
$stat = $row['stat']; # Nagios status: 0=OK
$leds[ $led ] = ($stat) ? 0 : 1;
}
}
mysql_free_result($result);
for ($i = 0; $i < 16; $i++) {
print (isset($leds[$i]) ? $leds[$i] : 0) . " ";
}
print "\n";
?>
A test with php -f blinken.php
should output a single line of ones and zeroes
depending on the status column of the database table.
1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Shell
A simple shell script will retrieve the statii from our web server and pass those as arguments to the blinken program.
#!/bin/sh
leds=`curl -s http://web.example.com/blinken.php`
echo $leds
./blinken $leds
The leds on the map should light accordingly. (With a bit more time, and some more inclination, I’d have used curl embedded in the C program to retrieve the leds.)
blinken.c
The blinken program is quite simple:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/io.h>
#define base 0x378 /* Printer port base address */
#define NLEDS 16
#define GREEN 192
#define RED 144
void green(int led)
{
outb(led + GREEN, base);
outb(led + 0, base);
}
void red(int led)
{
outb(led + RED, base);
outb(led + 16, base);
}
int main(int argc, char **argv)
{
int led;
if (ioperm(base, 1, 1) < 0) {
fprintf(stderr, "%s: Couldn't get the port at %X\n", *argv, base);
exit(1);
}
for (led = 0; led < NLEDS; led++) // set all to red
red(led);
for (led = 0; (led < (argc-1)) && (led < NLEDS); led++) {
if (atoi(argv[led + 1]))
red(led);
else green(led);
}
return (0);
}