• 2007年08月07日

    Perl解析Apache服务器日志

    分类:

    Apache服务器日志文件的格式:

    127.0.0.1 - - [08/Apr/2007:22:19:48 +0800] "GET / HTTP/1.1" 200 44

    127.0.0.1 - - [08/Apr/2007:22:21:35 +0800] "GET / HTTP/1.1" 200 44

    127.0.0.1 - - [08/Apr/2007:22:21:38 +0800] "GET / HTTP/1.1" 304 -

    10.10.225.155 - - [08/Apr/2007:22:22:15 +0800] "GET / HTTP/1.1" 200 44

    10.10.224.220 - - [08/Apr/2007:22:23:05 +0800] "GET / HTTP/1.1" 200 44

    10.10.224.220 - - [08/Apr/2007:22:23:06 +0800] "GET /favicon.ico HTTP/1.1" 404 209

    10.10.224.137 - - [08/Apr/2007:22:24:48 +0800] "GET / HTTP/1.1" 200 44

    127.0.0.1 - - [08/Apr/2007:22:55:19 +0800] "GET /cgi-bin/first.pl HTTP/1.1" 404 214

    127.0.0.1 - - [08/Apr/2007:22:55:35 +0800] "GET /cgi-bin/test.pl HTTP/1.1" 200 13

    Perl解析代码:

    #!/usr/bin/perl

    use warnings;

    use strict;

    use English;

     

    my $access='C:\Documents and Settings\Administrator\Desktop\access.log';

    my @entry;

     

    # loop that prints each entry and gathers the statistics

    open(FILE, $access) or die( "Cannot open $access" );

     

    while (<FILE>) {

       next if ( $_ eq "\n" );           # skip blank lines

       @entry = parseAccessEntry($_);

       print $entry[0]." ".$entry[1]." ".$entry[2]." ".$entry[3]." ".$entry[4]." ".$entry[5]." ".$entry[6];

       print "\n";

    }

     

     

    sub parseAccessEntry

    {

       my $entry = shift;

     

       if ($entry =~/^(\d+\.\d+\.\d+\.\d+)\s-\s-\s\[      #IP Address

                        ([\d\w:\/]+)\s\+\d{4}\]\s\"               #time

                        (\w+)\s                               #Request type

                        \/([^\s]*)                                     #File name

                        ([^\"]*)\"\s                                 #Protocol

                        (\d+)\s                                #Request result

                        (\d+|\-)$/x)                                #Total bytes

       {        

          return ($1,$2,$3,$4,$5,$6,$7);

       }

       warn "Not a normal access log entry.\n$entry\n";

       return undef;

    }

    关键点在于反向引用:(pattern)

    []反向引用(Backreference\1$1)用作捕获保存,\1仅能用于匹配表达式中,而$1能用于闭块和直到另一个成功搜索。

    在正则表达式中用圆括号括住某模式就是告诉解释器要保存那个数据。Perl解释器响应请求,且将查找到的匹配保存在一系列特珠的变量中($1,$2,$3$65536),这些变量可用来查询第一个、第二个、第三个等等圆括号匹配,这些变量于是可以通过查看相应的变量或在数组环境下对正则表达式进行求值或者进行访问。

    上述正则表达式中标红色的即是获取匹配所需关键值。

     

    输出结果:

    127.0.0.1 08/Apr/2007:22:19:48 GET   HTTP/1.1 200 44

    127.0.0.1 08/Apr/2007:22:21:35 GET   HTTP/1.1 200 44

    127.0.0.1 08/Apr/2007:22:21:38 GET   HTTP/1.1 304 -

    10.10.225.155 08/Apr/2007:22:22:15 GET   HTTP/1.1 200 44

    10.10.224.220 08/Apr/2007:22:23:05 GET   HTTP/1.1 200 44

    10.10.224.220 08/Apr/2007:22:23:06 GET favicon.ico  HTTP/1.1 404 209

    10.10.224.137 08/Apr/2007:22:24:48 GET   HTTP/1.1 200 44

    127.0.0.1 08/Apr/2007:22:55:19 GET cgi-bin/first.pl  HTTP/1.1 404 214

    127.0.0.1 08/Apr/2007:22:55:35 GET cgi-bin/test.pl  HTTP/1.1 200 13


    随机文章:

    Perl学习(3) 2008年12月01日
    Perl学习(2) 2008年11月24日
    Ruby学习 2008年01月24日
    Python学习 2007年12月25日

    收藏到:Del.icio.us




    评论

  • 如何将上述输出结果各项对齐(列对齐)?
    阿里回复zhx说:
    format STDOUT=
    2008-11-08 13:58:51