Eigene Fehlermeldungen und was man mit ihnen anfangen kann II

von Thomas Salvador.

Einführung

Im Artikel "Eigene Fehlermeldungen und was man mit ihnen anfangen kann" hatte Friedemann Lindenthal gezeigt, wie man die Standardfehlermeldungen des Servers durch beliebig designte Dateien ersetzen kann.

Damit war es nicht nur möglich, weitere Erklärungen zu liefern, sondern insbesondere die Seiten auch völlig an das eigene Sitedesign anzupassen.

Friedemann ließ blanke HTML-Dateien darstellen, wies jedoch bereits darauf hin, dass dies keineswegs notwendig oder irgendwie erforderlich sei.

Wir verfolgen im zweiten Teil daher den anderen Ansatz und lassen bei Fehlern ein Programm ausführen.

Arbeitet man mit HTML-Dateien, so hat das Vor- und Nachteile. Der klare Vorteil sind eigene Dateien. Der Nachteil ist, dass es keinen Status 404 "Datei nicht gefunden" mehr gibt, da nunmehr immer eine Datei geliefert werden kann, entweder die angeforderte oder aber die Fehlerdatei.

Dies führt dazu, dass die übliche Übersicht der Dateien, die angefordert wurden, aber nicht lieferbar waren, verschwindet. Siteanalysen werden dadurch erschwert.

Erste Lösung

Man kann mit der HTML-Variante arbeiten, benötigt dann aber einen Logfile-Analysator, der einem die Frage "Woher kamen die Links auf meine Fehlerdatei?" vernünftig beantworten kann.

Diese Antwort besteht aus Dateien mit vielleicht einem (oder mehreren) ungültigen Link(s). Zumindest vielleicht. Technische Störungen oder Überlastung lassen auch vorhandene Seiten 404 melden, so dass der einfache Neuversuch die gewünschte Seite manchmal erscheinen lässt.

Zweite Lösung

Man verwendet statt der HTML-Variante ein Programm, welches die Fehlerdaten in einem separaten LogFile protokolliert. Diesen Ansatz werden wir verfolgen.

Das Programm

wird in Perl formuliert und kommuniziert über das CGI. Zunächst der Source:

#!/usr/bin/perl

## konfiguration ------------------------------------------

$mailerror=1; # soll der fehler gemailt werden?
              # 0 - nein, 1 - ja
$mailaddy="ihremail\@example.org";

$logerror=1;  # soll der fehler gelogged werden?
              # 0 - nein, 1 - ja
$logfile="./errors.log";

## das mailprogram ----------------------------------------

$MAILPROG="/usr/lib/sendmail";

## die antwortseiten --------------------------------------

$response="//www.example.org/fehler/";
$fileext=".html";

##################################################################
## nichts mehr zu aendern.

$fehlerno = $ENV{'QUERY_STRING'};
$referer  = $ENV{'HTTP_REFERER'};
$requested= $ENV{'REQUEST_URI'};

if (!($referer eq "")) {
  if ($mailerror==1) {
    &mailit();
  }

  if ($logerror==1) {
    &logit();
  }
}

print "Location: $response$fehlerno$fileext\n\n";

sub mailit() {
  open (SM, "| $MAILPROG -t")|| die ("kann $MAILPROG nicht oeffnen");

  print SM "From: $mailaddy\n";
  print SM "To: $mailaddy\n";
  print SM "Subject: Fehler $fehlerno auf Site\n\n";

  print SM "Fehler: $fehlerno\n";
  print SM "   von: $referer\n";
  print SM "  nach: $requested\n";

  close (SM);
}

sub logit() {
  open (F, ">>$logfile") || return;

  print F "$fehlerno|$referer|$requested\n";
  close (F);
}

Die Dokumentation

Das Programm erhält die relevanten Daten über Umgebungsvariablen:

  • HTTP_REFERER besagt, woher der Zugriff erfolgt ist oder ist leer, wenn der URL direkt eingegeben wurde. Im ersten Falle handelt es sich um einen fehlerhaften Link, im zweiten ist ein Tippfehler oder ein Link in Email o.ä.
  • REQUEST_URI liefert das Dokument, welches angefordert wurde.
  • QUERY_STRING wird in unserem Fall die Fehlernummer enthalten. Wir schreiben ein Programm für alle Fehler.

Logging oder Mailing geschieht nur dann, wenn es sich um einen Fehler auf der Site handelt. Tippfehler im URL u.ä. werden also nicht protokolliert, da Sie für den Master unerheblich sind.

Handelt es sich um einen zu bearbeitenden Fehler (Ist der Referer nicht-leer), so wird je nach Konfiguration mailit() und/oder logit() aufgerufen.

mailit() generiert eine Mail an $mailaddy, die Kurz und knapp die Daten enthält.

logit() hängt die Zeile $fehlerno|$referer|$requested an das LogFile an, wobei man sich natürlich klarmachen muss, dass die $... die Variablen mit den entsprechenden Werten sind. Der vertikale strich ist oft ein ideales Trennnzeichen, da er in Werten selten vorkommt. So auch hier. Prinzipiell kann man natürlich auch etwas anderes wählen.

Beispiel:

404|/test.html|/verzeichnis/gibesnicht.html

würde einen Fehler 404 zeigen. Der Link von test.html auf gibesnicht.html im Verzeichnis verzeichnis ist ungültig.

Nunja, die Dateien gibt es allesamt nicht.

Was auch immer gemacht oder nicht gemacht wurde, das Programm endet damit, dass es zur entsprechenden Fehlerdatei verweist, die wir schon für den ersten Teil der Serie der Serie erstellt hatten.

Um ein Programm für alle Fehler zu haben und gleichzeitig die Konfiguration zu minimieren, benutzt das Programm ein fixes Namensmuster für die Dateien.

  • $response verweist auf das Verzeichnis, in dem die Dateien liegen (z.B. //www.irgendwas.erde/fehler/mit Schrägstrich am Ende).
  • $fileext gibt die verwendete Dateerweiterung an. Beispiele sind ".html", ".shtml" oder auch ".php3" oder was Sie gerade benutzen.

Daraus ermittelt das Programm:

$response$fehlerno$fileext

also z.B.

//www.irgendwas.erde/fehler/404.html
//www.irgendwas.erde/fehler/403.shtml
//www.irgendwas.erde/fehler/500.php3

Je nachdem, was Sie eingestellt haben und welche Fehlernummer gerade vorliegt.

Die Einbindung

Um das Programm zu benutzen, installieren Sie es zunächst, wie Sie jedes CGI installieren. Passen Sie dazu den oberen Bereich des Programms entsprechend an (Pfad zu Perl, Pfad zu Sendmail, sonstige Konfiguration).

Achten Sie darauf, dass der Upload im ASCII-Modus geschieht, da es sonst nicht funktionieren wird. Ich gehe davon aus, dass Sie dass Script logerr.pl genannt haben. Ansonsten müssen Sie die Installation Ihrer Namenwahl entsprechend anpassen. Die Rechte des Scriptes müssen 755 sein.

Nun muss die Datei .htaccess im Hauptverzeichnis Ihres Servers (analog zum ersten Teil) angepasst werden.

Für jeden Fehler, für die Sie eine Fehlerseite angefertigt haben, fügen Sie die Zeile

ErrorDocument xyz /cgi-bin/logerr.pl?xyz

in .htaccess ein, wobei xyz die Fehlernummer ist. Zum Beispiel

ErrorDocument 401 /cgi-bin/logerr.pl?401
ErrorDocument 402 /cgi-bin/logerr.pl?402
ErrorDocument 403 /cgi-bin/logerr.pl?403
ErrorDocument 404 /cgi-bin/logerr.pl?404
ErrorDocument 500 /cgi-bin/logerr.pl?500

Für jeden Fehler xyz kann es natürlich nur einen ErrorDocument-Eintrag geben.

Das können Sie so ausprobieren. Bei einem direkten Aufruf einer nichtexistierenden Datei, sollte die 404er Fehlerdatei kommen. Über einen Link aufgerufen, sollte es Mail und/oder Logeintrag geben.

Fehlt der gewünschte Logeintrag, uploaden Sie eine leere LogDatei an ihre Stelle und setzen Sie ihre Rechte auf 666. (Manche Server erzeugen nicht vorhandene Dateien, wenn man Sie mit >> öffnet, andere eben nicht.)