在第二个例子中,我们将展示给您简单的网络管理员的例子。假设您面对一个问题,怎样容易的匹配行,从一个Apache access.log文件中,且传输这些记录到您服务器的数据库。这是一个短片段,从我们的通入日志中,这些日志通过我们的服务器被捕获。同时,我们将使用它作为一个示例内容:
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)"
正如步骤1,我们能够理解文件里的这些行拥有同样的结构。您能够在Apache帮助中找到此日志格式:
%h %l %u %t "%r" %>s %b "%{Referrer}i" "%{User-agent}i"
在哪里:
%h – IP address of client
%l - The "hyphen" in the output indicates that the requested piece of information is not available
%u - This is the userid of the person requesting the document as determined by HTTP authentication
%t - The time that the server finished processing the request
%r - The request line from the client
%>s - This is the status code that the server sends back to the client
%b - The last entry indicates the size of the object returned to the client, not including the response headers
%{Referrer}i – HTTP referrer
%{User-agent}i - This is the identifying information that the client browser reports about itself
我们将使用 <Section While> 结构, 重复执行在主体中的二级元素,知道每一个评估是正确的。让我们为我们的脚本写小的框架(最好的办法是从某些已存在的脚本中拷贝)。
#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
在页面源代码里的主要文章已经被高亮显示:
现在,我们将增加一个样式,从而匹配在access.log里的一行。我们将此样式放入<Section While>循环。
我们只想使用主要文章的标题和图片下方的短语。
正如我们所看到的,标题被Tag封装 <div class="cnnMainT1Hd"> … </div> 短语也在Tag封装里 <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
在前面的步骤里,我们定义了匹配样式,但是我们没有看到任何结果。所以,我们将建立行为,打印某些匹配的变量到默认输出。
任何通过<Action Print>能被打印的文本。将要打印的文本应该是作为参数给出。
每一个脚本包括从URL下载指定页面的主要部分,然后执行某些行为,随着下载的内容。我们将在下一步看到如何匹配数据。
<Section>
Name AccessLog
# 从磁盘文件加载内容
<Action ContentFile>
#从下面的文件加载内容
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>
#打印匹配内容
<Action Print>
Text {$client_ip}, {$ident}, {$userid}, \
{$date}, {$request}, {$status}, {$size}, \
{$referer}, {$client_type}<br>
</Action>
</Section>
</Section>
#开始主体运行 AccessLog
Main AccessLog
此定义的行为将标准打印输出匹配的数据。
我们在access.log文件中将匹配的数据进行分析,同时默认显示。当最后一步时,我们将从access.log文件存数数据到数据库中。我们要说,我有拥有一个MySQL数据库文件server_stat,一个名为accesslog的表单,其拥有下列项:clientip, request_time, request and created。
为了插入数据到数据库,我们可以使用<Action SaveDbRow>。
<Section>
Name AccessLog
# 从磁盘文件加载内容
<Action ContentFile>
#从下面的文件加载内容
File c:/temp/access.log
</Action>
<Section While>
#随着下列样式,匹配日志文件中的一行
<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>
#同时将匹配的数据存储到数据库表单中
<Action SaveDbRow>
# Optional 告诉系统如果数据库插入失败,那么脚本可以继续执行
Optional
#定义主体
Name save-to-db
#数据库服务器名称
Server localhost
#数据库类型
DBType mysql
#数据库名称
Database server_stat
Username root
Password root
#将数据存储到名为accesslog的表中
TableName accesslog
#在类名称和匹配的变量名称中定义匹配
ColumnDef clientip, $client_ip
ColumnDef request_time, $date
ColumnDef request, $request
#预定义变量 $_NOW will返回当前的日期时间
ColumnDef created, $_NOW
</Action>
</Section>
</Section>
#开始执行名为 AccessLog的主体
Main AccessLog
此定义行文将打印匹配的数据到标准输出。