In diesem zweiten Beispiel werden wir Ihnen ein einfaches Beispiel aus der Arbeit eines Webadministrators zeigen. Stellen Sie sich vor, Sie stünden vor der Frage, wie Sie auf einfache Weise Zeilen aus dem apache access.log anpassen und diese Einträge in eine Datenbank auf Ihrem Server übertragen könnten. Dies ist ein kurzer Schnipsel aus unserem Zugriffsprotokoll, das von unserem Server erfasst wurde und das wir als Beispielinhalt verwenden werden:
70.242.222.162 - - [01/Jan/2005:21:57:28 +0100] "GET /unitminer/ HTTP/1.1" 200 26080 "http://www.webradev.com/?p=CustomDev" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; YPC 3.0.1; .NET CLR 1.1.4322; yplus 4.1.00b)"
70.242.222.162 - - [01/Jan/2005:21:57:29 +0100] "GET /css/test.css HTTP/1.1" 200 5651 "http://www.unitminer.com/unitminer/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; YPC 3.0.1; .NET CLR 1.1.4322; yplus 4.1.00b)"
70.242.222.162 - - [01/Jan/2005:21:57:33 +0100] "GET /img/qu_logo.png HTTP/1.1" 200 3731 "http://www.unitminer.com/unitminer/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; YPC 3.0.1; .NET CLR 1.1.4322; yplus 4.1.00b)"
Als ersten Schritt sollten wir den Zeilen in der Datei die gleiche Struktur geben. Sie können das Protokollformat in der Apache-Hilfe finden:
%h %l %u %t "%r" %>s %b "%{Referrer}i" "%{User-agent}i"
Wo:
%h – IP-Adresse des Client
%l - Der "Bindestrich" im Output gibt an, dass die gewünschte Information nicht verfügbar ist.
%u - Dies ist die Benutzer-ID der Person, die das Dokument verlangt, wie sie von der HTTP-Authentifizierung bestimmt wurde.
%t - Die Zeit, in der der Server die Verarbeitung der Anfrage abgeschlossen hat
%r - Die Anfragezeile des Client
%>s - Dies ist der Statuscode, den der Server zurück zum Client sendet
%b - Der letzte Eintrag gibt die Größe des an den Client zurückgesandten Objekts an, ohne den Antwortheader
%{Referrer}i – HTTP-Referrer
%{User-agent}i - Dies ist die identifizierende Information, die der Client-Browser über sich selbst angibt.
Wir werden die Struktur <Section While> verwenden, die die Ausführung von Unterelementen in dem Bereich wiederholt, bis jedes als wahr bewertet wird. Lassen Sie uns ein kleines Framework für unser Script schreiben (der beste Ansatz besteht normalerweise darin, es aus einem bestehenden Script zu kopieren).
#Hauptbereich des Scripts definieren
<Section>
#Name des Bereichs definieren
Name AccessLog
# Inhalt aus Datei auf Festplatte laden
<Action ContentFile>
#Inhalt aus der folgenden Datei laden
FileName c:/temp/access.log
</Action>
<Section While>
#später werden wir Code hinzufügen, der die Protokollzeile hier anpasst und verarbeitet
</Section>
</Section>
#Ausführung des Bereich mit dem Namen AccessLog beginnen
Main AccessLog
Die Hauptstory ist im Quellcode der Seite hervorgehoben:
Nun werden wir ein Muster hinzufügen, das mit einer Zeile innerhalb des Zugriffsprotokolls übereinstimmt. Wir setzen dieses Muster in einen <Section While>-Zyklus.
Wir möchten nur den Titel der Hauptstory und den kurzen Text unter dem Bild verwenden.
Wie Sie sehen, ist der Titel von Tags <div class="cnnMainT1Hd"> … </div> umrahmt und der kurze Text steht innerhalb der Tags <div class="cnnMainT1"> … </div>.
#Hauptbereich des Scripts definieren
<Section>
#Name des Bereichs definieren
Name AccessLog
# Inhalt aus Datei auf Festplatte laden
<Action ContentFile>
#Inhalt aus der folgenden Datei laden
File c:/temp/access.log
</Action>
<Section While>
#eine Zeile innerhalb der Protokolldatei an das folgende Muster anpassen
<Pattern>
Name LogRow
RegExp ^{$client_ip:regexp(\S+)} \
{$ident:regexp(\S+)} \
{$userid:regexp(\S+)} \
[{$date:regexp(([^:]+):(\d+:\d+:\d+) ([^\]]+))}] \
"{$request:regexp(.+?)}" \
{$status:regexp(\S+)} \
{$size:regexp(\S+)} \
"{$referer:regexp(.+?)}" \
"{$client_type:regexp(.+?)}"{:regexp(\s+)}
</Pattern>
</Section>
</Section>
#Ausführung des Bereichs mit dem Namen AccessLog beginnen
Main AccessLog
Im vorherigen Schritt haben wir ein übereinstimmendes Muster definiert, aber wir sehen noch kein Ergebnis. Daher werden wir einen Vorgang erstellen, der einige der angepassten Variablen in einen Standard-Output ausdruckt.
Jeder beliebige Text kann mit <Action Print> gedruckt werden. Der auszudruckende Text sollte als Parameter an das Attribut Text gegeben werden.
Jedes Script enthält den Hauptbereich, der die Seite von der benannten URL herunterlädt und führt dann einen Vorgang mit dem heruntergeladenen Script aus. Im nächsten Schritt werden wir sehen, wie die Daten angepasst werden.
#Hauptbereich des Scripts definieren
<Section>
#Name des Bereichs definieren
Name AccessLog
# Inhalt aus Datei auf Festplatte laden
<Action ContentFile>
#Inhalt aus der folgenden Datei laden
File c:/temp/access.log
</Action>
<Section While>
#eine Zeile innerhalb der Protokolldatei an das folgende Muster anpassen
<Pattern>
Name LogRow
RegExp ^{$client_ip:regexp(\S+)} \
{$ident:regexp(\S+)} \
{$userid:regexp(\S+)} \
[{$date:regexp(([^:]+):(\d+:\d+:\d+) ([^\]]+))}] \
"{$request:regexp(.+?)}" \
{$status:regexp(\S+)} \
{$size:regexp(\S+)} \
"{$referer:regexp(.+?)}" \
"{$client_type:regexp(.+?)}"{:regexp(\s+)}
</Pattern>
#drucken, was wir im Muster angepasst haben
<Action Print>
Text {$client_ip}, {$ident}, {$userid}, \
{$date}, {$request}, {$status}, {$size}, \
{$referer}, {$client_type}<br>
</Action>
</Section>
</Section>
#Ausführung des Bereichs mit Namen AccessLog beginnen
Main AccessLog
Der definierte Vorgang wird die übereinstimmenden Daten in Standard-Output ausdrucken.
Wir sehen, dass die übereinstimmenden Daten aus unserem access.log geparst wurden und im Standard-Output angezeigt wurden. Als letzten Schritt werden wir außerdem Daten aus access.log in der Datenbank speichern. Nehmen wir an, wir hätten eine MySQL-Datenbank mit dem Namen server_stat und sie beinhaltet eine Tabelle namens accesslog mit den folgenden Spalten: clientip, Anfrage_Zeit, Anfrage und erstellt.
Zur Einfügung der Daten in die Tabelle können wir den Tag <Action SaveDbRow> verwenden.
#Hauptbereich des Scripts definieren
<Section>
#Name des Bereichs definieren
Name AccessLog
# Inhalt aus Datei auf Festplatte laden
<Action ContentFile>
#Inhalt aus der folgenden Datei laden
File c:/temp/access.log
</Action>
<Section While>
#eine Zeile innerhalb der Protokolldatei an das folgende Muster anpassen
<Pattern>
Name LogRow
RegExp ^{$client_ip:regexp(\S+)} \
{$ident:regexp(\S+)} \
{$userid:regexp(\S+)} \
[{$date:regexp(([^:]+):(\d+:\d+:\d+) ([^\]]+))}] \
"{$request:regexp(.+?)}" \
{$status:regexp(\S+)} \
{$size:regexp(\S+)} \
"{$referer:regexp(.+?)}" \
"{$client_type:regexp(.+?)}"{:regexp(\s+)}
</Pattern>
#übereinstimmende Daten auch in Datenbanktabelle speichern
<Action SaveDbRow>
# Optional weist es das System an, dass das Script mit der Ausführung fortfahren kann, wenn die Einfügung
# in die Datenbank
# fehlschlägt
Optional
#definiert Name des Vorgangs
Name save-to-db
#Name des Datenbankservers
Server localhost
#Datenbanktyp
DBType mysql
#Name der Datenbank
Database server_stat
Username root
Password root
#Daten in Tabelle mit Namen accesslog speichern
TableName accesslog
#Zuordnung von Spaltennamen und Namen der übereinstimmenden Variablen definieren
ColumnDef clientip, $client_ip
ColumnDef request_time, $date
ColumnDef request, $request
# vordefinierte Variable $_NOW gibt aktuelles Datum/Zeit an
ColumnDef created, $_NOW
</Action>
</Section>
</Section>
#Ausführung des Bereichs mit dem Namen AccessLog starten
Main AccessLog
Der definierte Vorgang wird die übereinstimmenden Daten in Standard-Output ausdrucken.