Bah oui, il y a déjà plein d'autres solutions !
Certes, mais Munin n'a pas pour but de remplacer Nagios
Munin est plutôt un excellent complément à d'autres outils de supervision :
En supervision comme ailleurs, il vaut mieux privilégier le dicton
« À chaque besoin sa solution »
ou plutôt master/node
Il n'y a aucun problème pour installer un nœud et un maître sur la même machine qui du coup s'auto-supervise.
Le maître demande deux choses à la sonde (via le nœud) :
(et ça c'est bien cool)
La sonde dns_query_time mesure le temps de réponse à la question « IN NS . » avec la commande dig
$ ./dns_query_time config # renseignements sur le plugin
graph_title DNS query time # titre du graphe
graph_vlabel time in ms # label de l’axe des Y
time.label query time
$ ./dns_query_time # interrogation de la valeur
time.value 42
Code de base
#!/bin/bash
case $1 in
config)
cat <<EOF
graph_title DNS query time
graph_vlabel time in ms
time.label query time
EOF
exit 0;;
esac
printf "time.value "
dig IN NS . | grep '^;; Query time:' | cut -d' ' -f4
Pour activer la sonde, un simple lien symbolique dans /etc/munin/plugins suffit !
(avec un /etc/init.d/munin-node restart quand même)
On peut aussi tester la sonde avec munin-run avant de redémarrer le service :
munin-run dns_query_time
Le protocole de communication étant fort simple, on peut tester la sonde en conditions réélles avec telnet :
$ telnet localhost 4949
Trying 127.0.0.1...
Connected to localhost
Escape character is '^]'.
# munin node at localhost
list # liste des plugins activés
cpu if_eth0 load memory dns_query_time
config dns_query_time # vérification config
graph_title DNS query time
graph_vlabel time in ms
time.label query time
.
fetch dns_query_time # interrogation des données
time.value 6
Les sondes Munin sont extrêmement facile à développer !
On peut les faire dans son langage préféré (Perl, bien sûr) et profiter de ses bibliothèques.
Le module Munin::Plugin est là pour vous simplifier le travail.
(perldoc Munin::Plugin
)
Oui, oui, vous avez bien lu la cafetière !
On peut vraiment tout monitorer simplement avec Munin ☺
Surveiller le niveau de café dans la cafetière.
On va prendre des photos de la cafetière avec une webcam et voir où en est le niveau de café.
Mais ça va être vachti compliqué, non ?
On n'a besoin que de Munin::Plugin, Image::Magick, ffmpeg et zbar.
(Dingue, non ?)
(Ouais, nan, pas tant que ça, c'est du lourd quand même.)
ffmpeg servira à capter le flux vidéo de la webcam et à en faire une photo.
zbar servira à lire un QR code sur la photo.
Image::Magick servira à lire l'image et déterminer le niveau de café.
Munin::Plugin fournira quelques facilités d'écriture.
Un bon début.
use warnings;
use strict;
use Munin::Plugin;
use Image::Magick;
my $PICTURE = "$Munin::Plugin::pluginstatedir/picture.jpg";
my $START_X = $ENV{start_pixel_x};
my $START_Y = $ENV{start_pixel_y};
my $RMIN = $ENV{r_min} || 0;
my $RMAX = $ENV{r_max} || 0.2;
my $GMIN = $ENV{g_min} || 0;
my $GMAX = $ENV{g_max} || 0.2;
my $BMIN = $ENV{b_min} || 0;
my $BMAX = $ENV{b_max} || 0.2;
my $HEIGHT = $ENV{height} || 100;
my $DEVICE = (defined $ENV{device}) ? $ENV{device} : "/dev/video0";
On peut voir ici une utilisation de Munin::Plugin.
$Munin::Plugin::pluginstatedir
nous fournit un répertoire dans l'arborescence pour stocker des fichiers.
Quelques fonctions internes
sub _munin_exit_done {
_munin_exit(0);
} ## sub _munin_exit_done
sub _munin_exit_fail {
_munin_exit(1);
} ## sub _munin_exit_fail
sub _munin_exit {
my $exitcode = shift;
exit($exitcode) if(defined $exitcode);
exit(1);
} ## sub _munin_exit
(Rien d'intéressant ici)
Affichage de la configuration de la sonde.
if( (defined $ARGV[0]) && ($ARGV[0] eq "config") ) {
print "graph_title Coffee level\n";
print "graph_vlabel level of coffee in coffee pot\n";
print "graph_info How much coffee there is in the coffee pot\n";
print "graph_args -u 100 -l 0\n";
print "coffee.label coffee level\n";
print_thresholds('coffee');
print "coffee.draw AREA\n";
## Done !
_munin_exit_done();
}
Simple, non ?
Mais ! Qu'est-ce que c'est que ce print_thresholds('coffee')
?
Simplement une fonction de Munin::Plugin qui affiche les seuils d'alertes warning et critical s'ils existent dans la conf.
Allons-y Alonzo !
# take picture
if (!-e $DEVICE) {
print $Munin::Plugin::me." Can't see video device: $DEVICE\n";
_munin_exit_fail();
}
if (system("ffmpeg -y -f video4linux2 -i $DEVICE -vframes 1 $PICTURE")) {
print $Munin::Plugin::me." Error while taking photo from";
print "video device $DEVICE to $PICTURE\n";
_munin_exit_fail();
}
# check if the coffee pot is present with QRcode
_munin_exit_done() unless (`zbarimg $PICTURE` =~ m/QR-Code:present/m);
$Munin::Plugin::me
retourne le nom de la sonde.
C'est équivalent à basename $0
dans un script shell.
Plutôt utile pour les messages d'erreur !
Manipulons donc notre image…
# get the ruler pixels informations
my $image = new Image::Magick;
$image->Read($PICTURE);
my @pixels = $image->GetPixels(
x => $START_X,
y => $START_Y,
width => 1,
height => $HEIGHT,
normalize => 1
);
for (my $i = $START_Y; $i < $START_Y + $HEIGHT; $i++) {
$image->Set('pixel['.$START_X.','.$i.']' => 'red');
}
$image->Write('/tmp/coffee_check.png');
Ceci ne sert quasiment qu'à étalonner la sonde.
Mesurons le niveau de café.
my @cleaned;
while (scalar @pixels) {
push @cleaned, {
r => shift @pixels,
g => shift @pixels,
b => shift @pixels
};
}
# get the level
my $i = 0;
foreach my $pixel (@cleaned) {
if ($pixel->{r} >= $RMIN && $pixel->{r} < $RMAX &&
$pixel->{g} >= $GMIN && $pixel->{g} < $GMAX &&
$pixel->{b} >= $BMIN && $pixel->{b} < $BMAX ) {
my $level = 100 * ($HEIGHT - $i) / $HEIGHT;
printf "coffee.value %.2f\n", $level;
_munin_exit_done();
}
$i++;
}
printf "coffee.value 0\n";
_munin_exit_done();
Bilan :
Présentation adaptée de l'article et de la présentation des JRES 2013
« Munin : superviser simplement la machine à café… enfin une réalité ! »
http://github.com/ldidry
http://twitter.com/framasky
http://slides.fiat-tux.fr