【问题标题】:Parsing raw apache logs解析原始 apache 日志
【发布时间】:2011-02-18 05:19:33
【问题描述】:

我需要一些 php 代码来解析原始 apache 日志。 特别是,我想要 mode=search 的次数和用于搜索的术语。这是一个例子:

207.46.195.228 - - [30/Apr/2010:03:24:26 -0700] "GET /index.php?mode=search&term=AE1008787E0174 HTTP/1.1" 200 13047 "-" "msnbot/2.0b (+http://search.msn.com/msnbot.htm)"
212.81.200.167 - - [30/Apr/2010:04:21:43 -0700] "GET /index.php?mode=search&term=WH2002D-YYH HTTP/1.1" 200 12079 "http://www.mysite.com/SearchGBY.php?page=81" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; GTB6.4; .NET CLR 1.1.4322; .NET CLR 2.0.50727; WinuE v6; InfoPath.2; WinuE v6)"
212.81.200.167 - - [30/Apr/2010:04:21:44 -0700] "GET /file_uploads/banners/banner.swf HTTP/1.1" 200 50487 "-" "contype"
66.249.68.168 - - [30/Apr/2010:04:21:45 -0700] "GET /index.php?mode=search&term=WH2002D-YYH HTTP/1.1" 200 12079 "-" "Mediapartners-Google"

【问题讨论】:

    标签: php apache parsing logging


    【解决方案1】:

    就像使用正则表达式一样简单:http://php.net/manual/en/book.regex.php

    【讨论】:

    • 对不起,Casidiablo,正则表达式对我来说太混乱了。我已经编程 20 年了,仍然不知道也不喜欢它们。
    • 哈哈……我也是。但它们很有用。
    • 正则表达式在大多数情况下被证明是解析字符串的错误工具,因为您要解析的语法通常不是正则的。有没有先检查 Apache 日志的语法?
    • erikb85:我们认为的正则表达式已经扩展到这样的程度,如果我们能够感知字符串中的模式,我们就能够为该字符串发明语法发现并创建一个正则表达式来解析它。 Apache 日志在字段之间缺乏一致的语法,有些字段用引号括起来,有些用括号括起来,有些则什么也没有。所以我们需要这样的东西: preg_match('/^(\S+) \S+ \S+ [(.*?)] "(\S+).*?" \d+ \d+ "(.*?)" "(. *?)"/', $line, $m) 正则表达式永远不是解析字符串的错误工具。这就是为什么每种语言都支持它们的原因
    【解决方案2】:

    我最近为此写了一个非常粗略的解析器:

    $ignore = array('css', 'png', 'gif', 'jpg', 'jpeg', 'js', 'ico'); $f = fopen('access_log', "r"); if(!$f) die("Failed to open log for reading."); while (!feof($f)) { $buff = fgets($f, 4096); $parts = explode(' ', $buff); if(in_array(end(explode('.', $parts[6])), $ignore)) continue; $domain = trim(end($parts)); // http method $http_method = substr($parts[5], 1); if($http_method != 'GET' && $http_method != 'POST') continue; // parse out the date list($d, $m, $y) = explode('/', substr($parts[3], 1)); $y = substr($y, 0, 4); $time = strtotime("{$d} {$m} {$y}"); print "{$time} {$parts[0]} {$http_method} {$parts[6]} $domain\n"; }

    $parts[6] 应该包含您感兴趣的部分(被访问的资源)。这应该会让你上路……

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-23
      • 1970-01-01
      • 1970-01-01
      • 2021-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多