Wie logge ich Fehler und anderes in CGI?

Manchmal ist es nicht möglich, an das Fehlerlog des Webservers heranzukommen, um Fehler des Skriptes zu erkennen. Oder man will Ausgaben an eine Logdatei senden, um das Skript zu debuggen. Oder einfach nur ein paar Ausgaben mitloggen.

Das geht mit Modulen oder kann auch einfach gemacht werden wie ich es hier vorstellen möchte.
Das Skript hat auch den Vorteil, dass eine Rotation des Logfiles stattfindet, wenn es eine bestimmte Größe überschreitet; alte Einträge bleiben also gesichert.

Skript

Das Skript stellt nur ein anschauliches Beispiel dar.

#!/usr/bin/perl

use strict;
use warnings;

my $tmp_file; # Deklaration der Variablen

# falls Warnungen bei der Rotation auch in Logdatei sollen auf 1 setzen
my $DEBUG_ROTATE = 0; 

BEGIN {
    # Logdatei im Verzeichnis des Skripts
    $tmp_file = './myerror.log'; # bitte Pfad auf eigene Bedürfnisse anpassen
    
    # STDERR wird für die Laufzeit des Skripzts umgelenkt auf Logdatei
    open(STDERR,'>>', $tmp_file); 
    
    # Datei nur für Eigentümer beschreibar machen
    chmod (0644, $tmp_file);
}

# ----------------------------------------------

# Beispiel:
# fehlerhaftes Hauptprogramm !!!!!
# wirft ein paar Fehler in die Logdatei
sub main {
    open($fh, 'nichtexistente.datei') or die( "Datei $fh nicht gefunden!");
    if(
    }
    clos($fj);
}
main();


# -----------------------------------------------

sub RotateLog {
    my $filename = shift;
    my $MAXCYCLE = shift || 10; # maximale Anzahl der Logdateien pro Rotation

    if ( -e "$filename.$MAXCYCLE" ) {
        # Gzip in Standardpfaden suchen
        foreach 
            my $gz ( '/bin/gzip', '/usr/bin/gzip', '/usr/local/bin/gzip', undef )
        {
            last if ( not defined $gz ); 
            if ( -x $gz ) {
                # Datei als GZip komprimieren
                system("$gz -c $filename.$MAXCYCLE >> $filename.gz");
                last;
            }
        }
    }
    
    # Logdatei rotieren
    for ( my $s = $MAXCYCLE - 1 ; $s >= 0 ; $s-- ) {
        my $oldname = $s ? "$filename.$s" : $filename;
        my $newname = join( ".", $filename, $s + 1 );

        if ( -e $oldname ) {
            warn("RotateLog: $oldname--\>$newname\n") if $DEBUG_ROTATE;
            rename( $oldname, $newname )
              or warn("RotateLog: $oldname not renamed to $newname!\n");
        }
    }
    
    1;
}

END { 
    close(STDERR);
    
    # Größe der Logdatei abfragen
    my ($fsz) = (stat($tmp_file))[7];
    
    # Rotieren falls größer als 1 MByte
    RotateLog($tmp_file) if ( $fsz > 1024*1024 ); 
   
    1;
}

1;

Mir ist klar, dass dies nur ein einfaches Beispiel ist und die Umlenkung von STDERR auf eine Logdatei ohne jegliche Dateisperren so ihre Tücken haben kann.

Ergänzungen, Kommentare

-- GwenDragon - 27 Sep 2009 - Beitrag erstellt

Kommentare werden am besten in folgender Form vorgenommen, damit sie im Inhaltsverzeichnis angezeigt werden (natürlich ohne das <verbatim>):
---### Main.??? - 14 Jul 2003 - Betreff

UtilPerlSkripteSubForm edit

Titel Wie logge ich Fehler und anderes in CGI?
Autor GwenDragon
Bereich PerlSkripteCGI
Topic revision: 2009-09-27, GwenDragon
 
Bitte die NutzungsBedingungen beachten.
Bei Vorschlägen, Anfragen oder Problemen mit dem PerlCommunityWiki bitten wir um WebBottomBarExample">Rückmeldung.