Livestatus avec Nagios
Introduction
Dans le monde de la supervision Nagios a été très largement adopté de part sa gratuité et sa licence Opensource. Malgrè un moteur efficace, Nagios dispose d’une interface plus ou moins intuitive et réactive suivant les usages.
Toutefois, il est possible d’ajouter des “broker” au moteur Nagios afin d’accèder à la base de données via une autre application et traiter ces informations de manière intuitive et en temps réel.
Parmi ces broker, celui qui nous interesse aujourd’hui est “MK Livestatus”. Ce module, à l’inverse de son confrère ndo2db qui synchronise la base de données Nagios dans une base SQL, ouvre un socket unix et nous permet d’accèder via LQL (langage créé pour cet usage) à un ensemble d’information du moteur Nagios sans générer d’accès disque.
Module mklivestatus
A ce jour, la version distribuée est la 1.2.4p5 et s’installe en toute simplicité grâce à la procédure fournie sur le site de l’éditeur [3].
L’idée première de ce module est de d’obtenir l’état des indicateurs d’un moteur Nagios grâce à un langage de type base de données. L’accès à ces données permet ensuite de venir recolter les données de plusieurs collecteurs sur une seule et unique console de gestion (mk_multisite).
Cependant, d’autres éditeurs ont profité d’avoir un accès efficace et temps réel à l’état des indicateurs de Nagios pour developpé des interfaces intuitives et pertinentes.
Parmi ces outils nous pouvons citer POM [6], Nagvis [7], Thruk [8], …
Quelques exemples d’utilisation
Une autre utilisation est de générer des rapports et effectuer des synthèses très simplement grâce à LQL qui permet de sélectionner de mannière précise les informations qui nous interesse.
Le lien [4] liste les champs interrogeables/filtrables ainsi que les valeurs possibles pour chacun d’eux. (Note : La version de livestatus décrite sur ce lien est légerement différente. Certains champs n’existe pas (ou pas encore) dans la version officielle.)
Exemple de requête :
GET hosts Columns: host_name state last_hard_state_change acknowledged Filter: state != 0 Filter: state_type = 1
Cette requête permet d’obtenir le statut des hosts en récuréperant :
- host_name : Le nom
- state : L’état
- last_hard_state_change : La date du dernier changement d’état
- acknowledged : Si l’état est acquité
Cependant les filtres nous permettent de séléctionner uniquement les résultats avec :
- state != 0 : Uniquement les hosts avec un état non OK
- state_type = 1 : Uniquement si l’état non OK est de type “HARD STATE”
Voici par exemple l’ensemble des éléments permettant d’obtenir cette sythèse quotidienne de l’état de Nagios le matin à 7h.
crontab :
0 7 * * * /root/rapports/send_report.sh hosts_request.live : GET hosts Columns: host_name state last_hard_state_change acknowledged Filter: state != 0 Filter: state_type = 1
synthese_request.live :
GET services Columns: host_name description state last_hard_state_change acknowledged Filter: state != 0 Filter: state_type = 1
header.mail :
MIME-Version: 1.0 Content-Type: text/html; boundary='nagios/nagios@domain' <html> <head> <title>HTML E-mail</title> </head> <body style=\"font-family: "Open Sans";\">
footer.mail :
</p> </body> </html>
send_report.sh :
#!/bin/bash hosts_request="/root/rapports/hosts_request.live" services_request="/root/rapports/services_request.live" hosts_result="/root/rapports/hosts_request.db" services_result="/root/rapports/services_request.db" livestatus_socket="/usr/lib/nagios/mk-livestatus/live" hosts_down="/root/rapports/hosts_down.db" hosts_unreach="/root/rapports/hosts_unreach.db" services_crit="/root/rapports/services_crit.db" services_warn="/root/rapports/services_warn.db" services_unkn="/root/rapports/services_unkn.db" mail_dest="/root/rapports/dest.mail" mail_important=0 mail_header="/root/rapports/header.mail" mail_body="/root/rapports/body.mail" mail_footer="/root/rapports/footer.mail" emetteur="From: rapport-nagios@domain.com" destinataire="Bcc: dest1@domain.com, dest2@domain.com" host_problem=0 service_problem=0 stats_down=0 stats_unreachable=0 stats_critical=0 stats_warning=0 stats_unknown=0 echo "" > $hosts_down echo "" > $hosts_unreach echo "" > $services_crit echo "" > $services_warn echo "" > $services_unkn cat "$hosts_request" | /usr/local/bin/unixcat "$livestatus_socket" > "$hosts_result" cat "$services_request" | /usr/local/bin/unixcat "$livestatus_socket" > "$services_result" # Process Hosts while IFS=';' read -r host_name state time ack do host_problem=$(( $host_problem +1 )) time=$(date -d @$time +"%a %d/%m/%y - %H:%I") if (test $state -eq 1); then stats_down=$(( $stats_down+1 )) if (test $ack -eq 1); then echo "<tr><td style=\"border: 1px solid black;\">$host_name</td><td style=\"color: white; background: red; border: 1px solid black;\">DOWN</td><td style=\"border: 1px solid black;\">$time</td><td style=\"border: 1px solid black;\">YES</td></tr>" >> $hosts_down else mail_important=1 echo "<tr style=\"background: #F66;\"><td style=\"border: 1px solid black;\">$host_name</td><td style=\"color: white; background: red; border: 1px solid black;\">DOWN</td><td style=\"border: 1px solid black;\">$time</td><td style=\"border: 1px solid black;\">NO</td></tr>" >> $hosts_down fi else stats_unreachable=$(( $stats_unreachable+1 )) if (test $ack -eq 1); then echo "<tr><td style=\"border: 1px solid black;\">$host_name</td><td style=\"color: white; background: #A06; border: 1px solid black;\">UNREACHABLE</td><td style=\"border: 1px solid black;\">$time</td><td style=\"border: 1px solid black;\">YES</td></tr>" >> $hosts_unreach else echo "<tr style=\"background: #A48;\"><td style=\"border: 1px solid black;\">$host_name</td><td style=\"color: white; background: #A06; border: 1px solid black;\">UNREACHABLE</td><td style=\"border: 1px solid black;\">$time</td><td style=\"border: 1px solid black;\">NO</td></tr>" >> $hosts_unreach fi fi done < "$hosts_result" # Process Services while IFS=';' read -r host_name service_name state time ack do service_problem=$(( $service_problem +1 )) time=$(date -d @$time +"%a %d/%m/%y - %H:%I") if (test $state -eq 2); then stats_critical=$(( $stats_critical +1 )) if (test $ack -eq 1); then echo "<tr><td style=\"border: 1px solid black;\">$service_name</td><td style=\"border: 1px solid black;\">$host_name</td><td style=\"color: white; background: red; border: 1px solid black;\">CRITICAL</td><td style=\"border: 1px solid black;\">$time</td><td style=\"border: 1px solid black;\">YES</td></tr>" >> $services_crit else mail_important=1 echo "<tr style=\"background: #F66;\"><td style=\"border: 1px solid black;\">$service_name</td><td style=\"border: 1px solid black;\">$host_name</td><td style=\"color: white; background: red; border: 1px solid black;\">CRITICAL</td><td style=\"border: 1px solid black;\">$time</td><td style=\"border: 1px solid black;\">NO</td></tr>" >> $services_crit fi elif (test $state -eq 1); then stats_warning=$(( $stats_warning+1 )) if (test $ack -eq 1); then echo "<tr><td style=\"border: 1px solid black;\">$service_name</td><td style=\"border: 1px solid black;\">$host_name</td><td style=\"color: white; background: #FA0; border: 1px solid black;\">WARNING</td><td style=\"border: 1px solid black;\">$time</td><td style=\"border: 1px solid black;\">YES</td></tr>" >> $services_warn else echo "<tr style=\"background: #FC6;\"><td style=\"border: 1px solid black;\">$service_name</td><td style=\"border: 1px solid black;\">$host_name</td><td style=\"color: white; background: #FA0; border: 1px solid black;\">WARNING</td><td style=\"border: 1px solid black;\">$time</td><td style=\"border: 1px solid black;\">NO</td></tr>" >> $services_warn fi else stats_unknown=$(( $stats_unknown+1 )) if (test $ack -eq 1); then echo "<tr><td style=\"border: 1px solid black;\">$service_name</td><td style=\"border: 1px solid black;\">$host_name</td><td style\"color: white; background: #A06;\">UNKNOWN</td><td style=\"border: 1px solid black; border: 1px solid black;\">$time</td><td style=\"border: 1px solid black;\">YES</td></tr>" >> $services_unkn else echo "<tr style=\"background: #A48;\"><td style=\"border: 1px solid black;\">$service_name</td><td style=\"border: 1px solid black;\">$host_name</td><td style=\"color: white; background: #A06; border: 1px solid black;\">UNKNOWN</td><td style=\"border: 1px solid black;\">$time</td><td style=\"border: 1px solid black;\">NO</td></tr>" >> $services_unkn fi fi done < "$services_result" echo "" > $mail_body if test $host_problem -ne 0; then echo -n "<h3>Host(s) Problem(s) :</h3>" >> $mail_body echo -n "<table style=\"border-collapse: collapse; text-align: center;\"><tr><th>Host</th><th>State</th><th>Since</th><th>ACK</th></tr>" >> $mail_body cat $hosts_down >> $mail_body cat $hosts_unreach >> $mail_body echo -n "</table><br /><br />" >> $mail_body else echo "<h3>No host problem was listed</h3>" >> $mail_body fi if test $service_problem -ne 0; then echo -n "<hr /><h3>Service(s) Problem(s) :</h3>" >> $mail_body echo -n "<table style=\"border-collapse: collapse; text-align: center;\"><tr><th>Service</th><th>Host</th><th>State</th><th>Since</th><th>ACK</th></tr>" >> $mail_body cat $services_crit >> $mail_body cat $services_warn >> $mail_body cat $services_unkn >> $mail_body echo -n "</table>" >> $mail_body else echo "<hr /><h3>No service problem was listed</h3>" >> $mail_body fi echo $emetteur > $mail_dest echo $destinataire >> $mail_dest echo "Subject: Nagios - Hosts: $stats_down/$stats_unreachable - Services: $stats_critical/$stats_warning/$stats_unknown - $(date "+%Y-%m-%d %H:%M")" >> $mail_dest echo "MIME-Version: 1.0" >> $mail_dest echo "Content-Type: text/html; boundary='nagios/nagios@domain'" >> $mail_dest if test $mail_important -eq 1; then echo "X-Priority: 1 (Highest)" >> $mail_dest echo "X-MSMail-Priority: High" >> $mail_dest echo "Importance: High" >> $mail_dest fi cat $mail_dest $mail_header $mail_body $mail_footer | /usr/sbin/sendmail -t
Bibliographie
[1] http://fr.wikipedia.org/wiki/Nagios
[2] http://mathias-kettner.com/index.html
[3] https://mathias-kettner.de/checkmk_livestatus.html
[4] http://www.naemon.org/documentation/usersguide/livestatus.html
[5] https://mathias-kettner.de/checkmk_multisite.html
[6] http://www.pom-monitoring.com/
Poster un commentaire