V tomto príklade Vám ukážeme jednoduchú ukážku zo života sieťového administátora. Predstavte si, že chcete jednoducho vytiahnuť rôzne záznamy z apache súboru access.log a preniesť tieto údaje do databázy na Vašom serveri. Toto je ukážka ako vyzerá náš access log a použijeme ho pre náš príklad:
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)"
Ako prvé sme zistili, že riadky v súbore majú ten istý formát. Tento formát môžete nájsť v pomocníkovi v Apache:
%h %l %u %t "%r" %>s %b "%{Referrer}i" "%{User-agent}i"
Kde:
%h – IP adresa klienta
%l - Pomlčka tu značí, že daná informácia nie je k dispozícii
%u - Toto je id používateľa z HTTP autentifikácie, ktorý si dokument vyžiadal
%t - Čas, kedy server skončil s vykonávaním požiadavky
%r - Čo žiada používateľ
%>s - Kód stavu, ktorý server pošle naspäť klientovi
%b - Posledný záznam hovorí o veľkosti objektu predanhého klientovi, vrátane hlavičiek.
%{Referrer}i – HTTP referer
%{User-agent}i - Toto je informácia o identite, ktorú poskytuje HTTP prehliadač klienta
Použijeme štruktúru <Section While> , ktorá bude opakovať vykonávanie svojich podsekcii, pokiaľ sa každá z nich vykoná správne. Poďme napísať malú kostru nášho skriptu (najlepší spôsob je skopírovanie z predchádzajúceho skriptu)
#define main section of script
<Section>
#define name of section
Name AccessLog
# load content from file on disk
<Action ContentFile>
#load content from following file
FileName c:/temp/access.log
</Action>
<Section While>
#later we will put code that matches and processes log row here
</Section>
</Section>
#start execution of Section with name AccessLog
Main AccessLog
Článok je vyznačený v zdrojovom kóde stránky:
Teraz pridáme porovnávajúci reťazec, ktorý zachytí jeden riadok access logu. Vložíme ho do cyklu <Section While>
Chceli by sme extrahovať iba titulok článku a krátky text pod obrázkom. Ako vidíme, titulok je ohraničený tagmi <div class="cnnMainT1Hd"> … </div> a krátky text je medzi <div class="cnnMainT1"> … </div>
<Section>
Name AccessLog
# load content from file on disk
<Action ContentFile>
#load content from following file
File c:/temp/access.log
</Action>
<Section While>
#match one line inside log file with following pattern
<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>
#start execution of Section with name AccessLog
Main AccessLog
V predchádzajúcom kroku sme zadefinovali porovnávajúci reťazec, ale nevidíme žiaden výstup. Preto vytvoríme postup pre vypísanie zachytených premenných na štandardný výstup.
Hocijaký text môžeme vypísať cez <Action Print>. Text, ktorý chceme vypísať musí byť parametrom atribútu Text
Každý skript obsahuje hlavnú sekciu, ktorá stiahne stránku z požadovanej URL a potom niečo spraví s jej obsahom. V nasledujúcom kroku sa pozrieme ako zachytiť dáta.
<Section>
Name AccessLog
# load content from file on disk
<Action ContentFile>
#load content from following file
File c:/temp/access.log
</Action>
<Section While>
#match one line inside log file with following pattern
<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>
#print what we matched in pattern
<Action Print>
Text {$client_ip}, {$ident}, {$userid}, \
{$date}, {$request}, {$status}, {$size}, \
{$referer}, {$client_type}<br>
</Action>
</Section>
</Section>
#start execution of Section with name AccessLog
Main AccessLog
Definovaný postup vypíše zachytené dáta na štandardný výstup.
Už vidíme, že sme zachytili nejaké dáta zo súboru access.log a vypísali sme ich na štandardný výstup. V poslednom kroku uložíme dáta zo súboru access.log do databázy. Povedzme, že máme MySQL databázu s názvom server_stat a v nej tabuľku accesslog s nasledujúcimi stĺpcami: clientip, request_time, request a created.
Pre vloženie dát do databázy môžeme použiť tag <Action SaveDbRow>.
<Section>
Name AccessLog
# load content from file on disk
<Action ContentFile>
#load content from following file
File c:/temp/access.log
</Action>
<Section While>
#match one line inside log file with following pattern
<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>
#store matched data also to database table
<Action SaveDbRow>
# Optional tells the system that if database insert
# fails, script can continue execution
Optional
#defines name of action
Name save-to-db
#database server name
Server localhost
#database type
DBType mysql
#Database name
Database server_stat
Username root
Password root
#store data to table with name accesslog
TableName accesslog
#define mapping between column names and matched variable names
ColumnDef clientip, $client_ip
ColumnDef request_time, $date
ColumnDef request, $request
# predefined variable $_NOW will return current datetime
ColumnDef created, $_NOW
</Action>
</Section>
</Section>
#start execution of Section with name AccessLog
Main AccessLog
Definovaný postup vypíše zachytené dáta na štandardný výstup.