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.

Nagios map

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);
}

Comments

blog comments powered by Disqus