Die Benutzung des Embedded Perl Interpreters


Einleitung

Stephen Davies hat für Nagios Code beigesteuert, der es ermöglicht Nagios mit der Unterstützung für einen embedded Perl Interpreter zu kompilieren. Dies ist vor allem für die User interessant, die sehr stark Perl-basierte Plugins einsetzen.

Stanley Hopcroft hat einige Zeit mit dem embedded Perl Interpreter gearbeitet und hat nun die Vor- und Nachteile seiner Benutzung zusammengefassst. Er gibt auch einige hilfreiche Hinweise dazu, wie man Perl-basierte Plugins so entwickelt, dass diese richtig mit dem embedded Perl Interpreter zusammenarbeiten. Der Grossteil dieser Dokumentation basiert auf seinen Kommentaren.

Es sollte darauf hingewiesen werden, das mit "ePN" Nagios mit der Unterstützung des embedded Perl gemeint ist (embedded Perl Nagios).

Vorteile

Einige Vorteile von ePN (embedded Perl Nagios) sind:

Nachteile

The disadvantages of ePN (embedded Perl Nagios) are much the same as Apache mod_perl (i.e. Apache with an embedded interpreter) compared to a plain Apache:

Zeilgruppe

Dinge die man tun sollte, wenn man ein Perl Plugin entwickelt (egal ob mit ePN oder ohne)

Dinge die beachtet werden müssen, wenn man Perl Plugins für ePN entwickelt

  1. <DATA> kann nicht benutzt werden; benutze hier stattdessen z.B. documents

    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) ;
    
  2. BEGIN Blöcke werden nicht funktioneren wie erwartet. Man sollte diese möglichst vermeiden.

  3. Man sollte sicherstellen, das Perl absolut sauber ist zum Zeitpunkt der Kompilierung



  4. Verhindere lexical Variablen (my) mit globalem Gültigkeitsbereich um __variable__ Daten an Sub-Routine zu übergeben. Dies ist __fatal__ wenn die Sub-Routine mehr als einmal aufgerufen wird, wenn die Überprüfung läuft. Solche Sub-Routinen agieren als 'closures' die den ersten Wert von globalen Lexikalen in subsequenten Ausführungen von Sub-Routinen locken. Falls die globale allerdings schreibgeschützt ist (eine komplizierte Struktur z.B.), sollte dies kein Problem sein. Was Bekman in diesem Fall rät, ist folgendes:


  5. Man achte darauf wo man Informationen herbekommt.

    Nützliche Informationen erhält man bei den üblichen Verdächtigen (die O'Reilly books, plus Damien Conways "Object Oriented Perl") aber für die wirklich wichtigen Dinge im richtigen Kontext sollte man mit Stas Bekman's mod_perl guide unter http://perl.apache.org/guide/ anfangen.

    Dieses wundervolle Buch enthält zwar nichts über Nagios, dafür aber alles über die Entwicklung von Perl Programmen für den embedded Perl Interpreter in Apache (z.B. Doug MacEacherns mod_perl).

    Die perlembed manpage ist essentiell für Kontext und Unterstützung.

    Da Lincoln Stein und Doug MacEachern ein oder zwei Dinge über Perl und embedded Perl wissen, sollte man auch einen Blick auf deren Buch 'Writing Apache Modules with Perl and C' werfen.

  6. Sollte das Plugin mit ePN seltsame Werte zurückliefern, liegt der Grund bestimmt in einem der zuvor genannten Punkte.

  7. Man sollte vorbereitet sein den Code mit den folgenden Dingen zu debuggen:


    perl -MO::Deparse <dein_programm>
  8. Man sei sich aber bewusst in was ePN das Plugin verändert damit man, falls alles andere scheitert, den transformierten Code debuggen kann.

    Wie man unten sehen kann schreibt p1.pl das Plugin als eine Subroutine mit dem Namen 'hndlr' in dem Paket mit dem Namen 'Embed::<something_related_to_your_plugin_file_name>' neu.

    Das Plugin erwartet u.U. Kommandozeilen-Argumente in @ARGV, deshalb ordnet pl.pl auch @_ dem @ARGV zu.

    In der Umkehrung wird 'eval' ed und falls die eval einen Fehler hervorruft (irgendein parse oder run Fehler), wird das Plugin ausgeworfen.

    Der folgende Output zeigt, wie ein Tets-ePN das check_rpc-Plugin umschreibt, bevor dieses ausgeführt wird. Das meiste des Codes des eigentlichen Plugins wird nicht gezeigt, da uns hier nur die Transformierung durch das ePN interessiert). Zur Klarheit wurden die Transformierungen rot eingefärbt:

    
                    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 netsaint
    #
    # 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.12 $
    #
    # Copyright Notice: GPL
    #
    ... der Rest des Plugin-Code kommt hier (wurde wegen der Lesbarkeit entfernt) ...
    }
    


  9. Man sollte nie 'use diagnostics' in einem Plugin verwenden, das von einer produktiven ePN-Installation benutzt wird. Hierdurch werden nämlich __alle__ Perl Plugins CRITICAL zurückgeben.

  10. Benutze ein mini embedded Perl C-Programm um das Plugin zu überprüfen. Dies garantiert zwar nicht, dass das Plugin gut mit ePN zusammenfunktioniert, falls das Plugin aber diesen Test nicht erfolgreich meistert, wird es definitiv nicht mit ePN funktionieren. [ Ein Beispiel-Mini-ePN ist in dem contrib/-Verzeichnis der Nagios-Distribution zum testen von Perl Plugins enthalten. Man muss nur in das contrib/-Verzeichnis wechseln und 'make mini_epn' eingeben um es zu kompilieren. Es muss aus dem gleichen Verzeichnis heraus ausgeführt werden, indem die p1.pl-Datei liegt (auch diese Datei wird mit Nagios geliefert). ]

Nagios mit der Unterstützung für den embedded Perl Interpreter kompilieren

Okay, nun kann wieder geatmet werden. Du willst also immernoch Nagios mit der Unterstützung für den embedded Perl Interpreter kompilieren? ;-)

Um Nagios mit dem embedded Perl Interpreter zu kompilieren, muss man das configure-Skript zusätzlich mit der --enable-embedded-perl-Option erneut laufen lassen. Falls man den embedded Interpreter intern die kompilierten Skripte cachen lassen will, muss man ausserdem --with-perlcache-Option angeben. Beispiel:

	./configure --enable-embedded-perl --with-perlcache ...andere Optionen...

Hat man das configure-Skript mit den neuen Optionen laufen lassen, muss man Nagios erneut kompilieren. Um sicherzustellen, das Nagios erfolgreich mit dem embedded Perl Interpreter kompilierte wurde, muss man das Programm nur mit dem -m-Argument aus der Kommandozeile heraus ausrufen. Die Ausgabe des Befehls wird ungefähr wie dieses aussehen (man beachte dass der embedded Perl Interpreter in dem options-Bereich aufgelistet wird:

	[nagios@firestore ]# ./nagios -m

	Nagios 1.0a0
	Copyright (c) 1999-2001 Ethan Galstad (nagios@nagios.org)
	Last Modified: 07-03-2001
	License: GPL

	External Data I/O
	-----------------
	Object Data:      DEFAULT
	Status Data:      DEFAULT
	Retention Data:   DEFAULT
	Comment Data:     DEFAULT
	Downtime Data:    DEFAULT
	Performance Data: DEFAULT


	Options
	-------
	* Embedded Perl compiler (With caching)