Utilisation de l'interpréteur Perl
intégré
Introduction
Stephen Davies a créé du code permettant de compiler Nagios®
avec un interpréteur Perl intégré. Ceci peut être intéressant si
vous utilisez massivement des plugins écrits en Perl.
Stanley Hopcroft a beaucoup travaillé sur l'interpréteur Perl
intégré et a commenté les avantages et désavantages de son
utilisation. Il a également donné plusieurs indices utiles pour
écrire des plugins Perl qui fonctionnent correctement avec
l'interpréteur intégré. La majeure partie de cette documentation
provient de ses commentaires.
Notez que "ePN", tel qu'il est utilisé dans cette
documentation, fait référence à Perl intégré à Nagios® [embedded
Perl Nagios®], ou si vous préférez, Nagios® compilé avec un
interpréteur Perl intégré.
Avantages
Parmi les avantages de ePN [embedded Perl Nagios®] on compte
:
- Nagios® passera beaucoup moins de temps à exécuter vos
plugins Perl car il n'a plus besoin de créer un sous-processus
[fork] pour lancer le plugin (en chargeant à chaque fois
l'interpréteur Perl). Il exécute maintenant votre plugin grâce
à un appel de bibliothèque.
- Il réduit grandement l'impact sur le système des plugins
Perl et/ou vous permet de lancer plus de contrôles en plugin
Perl que ce dont vous seriez capables autrement. En d'autres
termes, vous êtes moins tenté d'écrire vos plugins en d'autres
langages comme C/C++, ou Expect/TCL, qui sont généralement
considérés comme ayant un cycle de développement plus long que
Perl (même s'ils tournent a peu près dix fois plus vite — TCL
étant une exception).
- Si vous n'êtes pas un développeur C, vous pouvez quand même
faire beaucoup de choses avec Nagios® en laissant Perl faire le
gros du travail, sans que Nagios® ne soit trop ralenti. Ceci
dit, notez que ePN n'accélèrera pas votre plugin (une fois ôté
le temps de chargement de l'interpréteur). Si vous voulez des
plugins plus rapides, alors tournez-vous vers les XSUB Perl
(XS), ou C après vous être assuré que votre Perl est
propre et que votre algorithme est correct (l'apport de
Benchmark.pm n'a pas de prix pour comparer les
performances des éléments de langage Perl).
- L'utilisation de ePN est un excellent moyen d'en apprendre
plus sur Perl.
Désavantages
Les désavantages de ePN [embedded Perl Nagios®] ressemblent
beaucoup à ceux du mod_perl d'Apache (i.e. Apache avec un
interpréteur Perl intégré) par rapport à l'Apache standard :
- Un programme Perl qui fonctionne parfaitement avec
Nagios® standard peut ne pas fonctionner avec ePN. Il
vous faudra peut-être modifier vos plugins pour qu'ils
tournent.
- Les plugins Perl sont plus difficiles à déboguer sous ePN
qu'avec un Nagios® standard.
- Votre ePN aura une plus grande taille (encombrement en
mémoire) qu'un Nagios® standard.
- Certaines constructions [constructs] Perl ne peuvent pas
être utilisées, ou peuvent se comporter différemment de ce à
quoi vous vous attendiez.
- Il vous faudra connaître "plus d'une façon de le faire", et
peut-être choisir celle qui semble la moins attirante ou
évidente.
- Il vous faudra une meilleure connaissance de Perl (mais
rien de bien ésotérique ou concernant la structure interne de
Perl — sauf si vous utilisez les XSUBS).
Public visé
- Les développeurs Perl moyens ; ceux qui connaissent la
puissance des fonctionnalités du langage sans en connaître les
rouages internes.
- Ceux qui ont un point de vue utilitaire plutôt qu'une
profonde compréhension [sic].
- Si vous aimez les objets Perl, la gestion de noms, les
structures de données, et le débogueur, cela suffit sans
doute.
Ce que vous devez faire quand vous écrivez
un plugin Perl (ePN ou pas)
- Générez toujours un affichage
- Utilisez "use utils" et importez ce qui en est exporté
($TIMEOUT %ERRORS &print_revision &support)
- Jetez un œil sur la façon dont sont écrits les plugins Perl
standard, comme par exemple :
- Quittez toujours avec une valeur $ERRORS{CRITICAL},
$ERRORS{OK}, etc.
- Utilisez getopt pour lire les paramètres de la ligne de
commande
- Gérez les dépassements de délai
- Appelez print_usage (que vous fournissez) quand il n'y
a pas de paramètres à la commande
- Utilisez des noms de paramètres standard (par exemple H
'host', V 'version')
Ce que vous devez faire quand vous écrivez
un plugin Perl pour ePN
- <DATA> ne peut pas être utilisé ; utilisez ici des
documents à la place, par exemple :
my $data = <<DATA;
portmapper 100000
portmap 100000
sunrpc 100000
rpcbind 100000
rstatd 100001
rstat 100001
rup 100001
..
DATA
%prognum = map { my($a, $b) = split; ($a, $b) } split(/\n/, $data) ;
- Les blocks BEGIN ne fonctionneront pas comme vous
l'attendez. Il vaut mieux les éviter.
- Assurez-vous de la parfaite propreté du code à la
compilation, i.e.
- utilisez use strict
- utilisez perl -w (les autres paramètres (notamment T)
ne sont d'aucune aide)
- utilisez perl -c
- Evitez les variables de portée lexicale (my) déclarées
globalement comme moyen de passer des variables aux fonctions. En fait ceci est
fatal si la fonction est appelée par le
plugin plus d'une fois lorsque le contrôle est exécuté. Ces
fonctions se comportent comme des encapsulations [closures] qui
verrouillent les variables lexicales globales sur leur première
valeur lors des appels suivants à la fonction. Si toutefois
votre variable globale est en lecture seule (une structure de
données complexe par exemple), ce n'est pas un problème. Ce que
Bekman recommande en
remplacement est une des solutions suivantes :
- Sachez où trouvez plus d'informations.
Vous pouvez obtenir des informations utiles des indices
habituels (les livres O'Reilly, plus "Object Oriented Perl"
de Damien Conways) mais pour les bonnes réponses dans ce
contexte commencez par le guide du mod_perl de Stas Bekman
sur http://perl.apache.org/guide/.
Ce document merveilleux au format livre n'a strictement
rien à voir avec Nagios®, mais tout à voir avec l'écriture
de programmes pour l'interpréteur Perl intégré à Apache
(i.e. le mod_perl de Doug MacEachern).
La page "man" perlembed est essentielle pour le contexte
et les encouragements.
Si l'on considère que Lincoln Stein et Doug MacEachern
savent deux-trois choses sur Perl et l'intégration de Perl,
leur livre "Writing Apache Modules with Perl and C" vaut
certainement d'être lu.
- Sachez que votre plugin peut retourner d'étranges valeurs
avec ePN, et que cela est probablement dû au point 4
ci-dessus.
- Soyez prêt à déboguer en :
- ayant un ePN de test
- ajoutant des instructions print à votre plugin pour
afficher la valeur des variables sur STDERR (STDOUT ne peut
pas être utilisé)
- ajoutant des instructions print à p1.pl pour afficher
ce qu'ePN pense qu'est votre plugin avant d'essayer de le
lancer (vi)
- lançant l'ePN en avant-plan (probablement en
conjonction avec les recommandations précédentes)
- utilisant le module "Deparse" sur votre plugin pour
voir comment l'analyseur syntaxique l'a optimisé, et ce que
l'interpréteur reçoit réellement (voir "Constants in Perl"
de Sean M. Burke, The Perl Journal, automne 2001)
perl -MO::Deparse <votre_programme>
- Sachez qu'ePN transforme votre plugin lui aussi, et si tout
le reste a échoué essayez de déboguer la version
transformée.
Comme vous pouvez le constater ci-dessous p1.pl réécrit
votre plugin comme une fonction appelé 'hndlr' dans le
paquetage nommé
"Embed::<quelque-chose-ayant-rapport-avec-le-nom-de-fichier-de-votre-plugin>".
Votre plugin attend peut-être des paramètres de la ligne
de commande dans @ARGV, donc pl.pl assigne également @_ à
@ARGV.
Ceci à son tour est évalué et si "eval" remonte une
erreur (qu'elle soit syntaxique ou d'exécution), le plugin
est jeté dehors.
La copie d'écran suivante montre comment un ePN de test
a transformé le plugin check_rpc avant d'essayer de
l'exécuter. Seule une petite partie du code du plugin est
montrée ici, car nous ne nous intéressons qu'aux
transformations que l'ePN lui fait subir). Les
transformations sont affichées en rouge :
package main;
use subs 'CORE::GLOBAL::exit';
sub CORE::GLOBAL::exit { die "ExitTrap: $_[0] (Embed::check_5frpc)"; }
package Embed::check_5frpc; sub hndlr { shift(@_);
@ARGV=@_;
#! /usr/bin/perl -w
#
# check_rpc plugin for nagios
#
# usage:
# check_rpc host service
#
# Check if an rpc serice is registered and running
# using rpcinfo - $proto $host $prognum 2>&1 |";
#
# Use these hosts.cfg entries as examples
#
# command[check_nfs]=/some/path/libexec/check_rpc $HOSTADDRESS$ nfs
# service[check_nfs]=NFS;24x7;3;5;5;unix-admin;60;24x7;1;1;1;;check_rpc
#
# initial version: 3 May 2000 by Truongchinh Nguyen and Karl DeBisschop
# current status: $Revision: 1.8.2.4
#
# Copyright Notice: GPL
#
… le reste du plugin ci-dessous …
- Ne pas utiliser "use diagnostics" dans un plugin lancé par
votre ePN de production. Je pense qu'il force la valeur de
retour à CRITICAL dans tous les plugins
Perl.
- Envisagez l'utilisation d'un mini Perl intégré pour
vérifier votre plugin. Cela ne suffit pas à valider votre
plugin avec l'ePN, mais si le plugin échoue à ce test il
échouera également avec l'ePN. Un exemple de
mini ePN est inclus dans le répertoire contrib/ de la
distribution de Nagios® à cette fin. Placez-vous dans le
répertoire contrib/ et tapez "make mini_epn" pour le compiler.
Il doit être exécuté depuis le répertoire où se trouve p1.pl
(ce fichier est distribué avec Nagios®).
Compilation de Nagios® avec l'interpréteur
Perl intégré
Bien, vous pouvez respirer maintenant. Alors, vous voulez
toujours compiler Nagios® avec l'interpréteur Perl intégré
? ;-)
Si vous voulez compiler Nagios® avec l'interpréteur Perl
intégré il vous faut relancer le script de configuration
(configure) avec le paramètre --enable-embedded-perl. Si vous voulez que
l'interpréteur Perl intégré utilise un cache interne pour les
scripts compilés, ajoutez également le paramètre --with-perlcache. Par exemple :
./configure --enable-embedded-perl --with-perlcache …autres paramètres…