步骤 1 - 识别样式

在第二个例子中,我们将展示给您简单的网络管理员的例子。假设您面对一个问题,怎样容易的匹配行,从一个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

在页面源代码里的主要文章已经被高亮显示:

步骤 2 - 增加匹配的样式

现在,我们将增加一个样式,从而匹配在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

步骤 3 - 显示匹配的数据

在前面的步骤里,我们定义了匹配样式,但是我们没有看到任何结果。所以,我们将建立行为,打印某些匹配的变量到默认输出。

任何通过<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

此定义的行为将标准打印输出匹配的数据。

步骤 4 - 向数据库中插入匹配数据

我们在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

此定义行文将打印匹配的数据到标准输出。

Stay in touch with UnitMiner
© 2004-2012 QualityUnit.com, All rights reserved