PHP/regex解析NGINX错误日志
错误条目如下所示:PHP/regex解析NGINX错误日志,php,regex,Php,Regex,错误条目如下所示: 2011/06/10 13:30:10 [error] 23263#0: *1 directory index of "/var/www/ssl/" is forbidden, client: 86.186.86.232, server: hotelpublisher.com, request: "GET / HTTP/1.1", host: "hotelpublisher.com" 我需要解析: date/time error type error message cli
2011/06/10 13:30:10 [error] 23263#0: *1 directory index of "/var/www/ssl/" is forbidden, client: 86.186.86.232, server: hotelpublisher.com, request: "GET / HTTP/1.1", host: "hotelpublisher.com"
我需要解析:
date/time
error type
error message
client
server
request
host
第一位(解析日期)很容易使用substr
。虽然我的REGEX
不是很好,我希望听到更好的解决方案。我想,简单地按分解,
也不会起作用,因为错误也可能包含逗号
执行此操作最有效的方法是什么?如果您无权格式化日志文件,则可以执行以下操作:
$regex = '~(\d{4}/\d{2}/\d{2}) (\d{2}:\d{2}:\d{2}) \[(\w+)\] (.*?) client: (\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}), server: (.*?), request: "(.*?)", host: "(.*?)"~';
preg_match($regex, $line, $matches);
list($all,$date,$time,$type,$message,$client,$server,$request,$host) = $matches;
如果您确实可以访问日志的格式,请将消息放在末尾而不是中间,然后您可以执行以下操作:
$log_arr = explode(', ', $line, 7);
list($date,$time,$type,$client,$server,$request,$host,$message) = $matches;
秘密在于explode
采用可选的第三个参数,限制要拆分的元素数量。因此,通过将其设置为8
,行的其余部分将作为返回数组中的最后一个元素存储。有关这方面的更多信息。我就是这样做的
$error = array();
$error['date'] = strtotime(substr($line, 0, 19));
$line = substr($line, 20);
$error_str = explode(': ', strstr($line, ', client:', TRUE), 2);
$error['message'] = $error_str[1];
preg_match("|\[([a-z]+)\] (\d+)#(\d+)|", $error_str[0], $matches);
$error['error_type'] = $matches[1];
$args_str = explode(', ', substr(strstr($line, ', client:'), 2));
$args = array();
foreach($args_str as $a)
{
$name_value = explode(': ', $a, 2);
$args[$name_value[0]] = trim($name_value[1], '"');
}
$error = array_merge($error, $args);
die(var_dump( $error ));
这将产生:
array(7) {
["date"]=>
int(1307709010)
["message"]=>
string(50) "*1 directory index of "/var/www/ssl/" is forbidden"
["error_type"]=>
string(5) "error"
["client"]=>
string(13) "86.186.86.232"
["server"]=>
string(18) "hotelpublisher.com"
["request"]=>
string(14) "GET / HTTP/1.1"
["host"]=>
string(18) "hotelpublisher.com"
}
只想看几张选票,就知道哪一张是性能/可靠性方面的首选选项。试试下面的代码:
$str = '2011/06/10 13:30:10 [error] 23263#0: *1 directory index of "/var/www/ssl/" is forbidden, client: 86.186.86.232, server: hotelpublisher.com, request: "GET / HTTP/1.1", host: "hotelpublisher.com"';
preg_match('~^(\d{4}/\d{2}/\d{2}\s\d{2}:\d{2}:\d{2})\s\[([^]]*)\]\s[^:]*:\s(.*?)\sclient:\s([^,]*),\sserver:\s([^,]*),\srequest:\s"([^"]*)",\shost:\s"([^"]*)"~', $str, $m );
list($line, $dateTime, $type, $msg, $client, $server, $request, $host ) = $m;
var_dump($dateTime);
var_dump($type);
var_dump($msg);
var_dump($client);
var_dump($server);
var_dump($request);
var_dump($host);
输出
那么:
$str = '2011/06/10 13:30:10 [error] 23263#0: *1 directory index of "/var/www/ssl/" is forbidden, client: 86.186.86.232, server: hotelpublisher.com, request: "GET / HTTP/1.1", host: "hotelpublisher.com"';
preg_match('~^(?P<datetime>[\d+/ :]+) \[(?P<errortype>.+)\] .*?: (?P<errormessage>.+), client: (?P<client>.+), server: (?P<server>.+), request: (?P<request>.+), host: (?P<host>.+)$~', $str, $matches);
print_r($matches);
请查收;用于Nginx错误日志文件的php读取器/解析器。该脚本能够递归读取错误日志,并将其显示在用户友好的表中。脚本配置包括每页要读取的字节数,并允许通过错误日志分页 有一个小错误,请参见
errortype
,不过我想这也行。@Guy:错误类型应该是什么?就在
之前的数字?它可以是错误/通知/警告等。它是括号中的文本[]
。我在regexp中添加了一些小的改进:const nginxror=“^(?P[\\d+/:]+)\[(?P.+)\.*:(?P.+),客户端:(?P.+),服务器:(?P.+),请求:“(?P\\S+)\”(?P\\S+)\”,主机:“(?P.+)”
$str = '2011/06/10 13:30:10 [error] 23263#0: *1 directory index of "/var/www/ssl/" is forbidden, client: 86.186.86.232, server: hotelpublisher.com, request: "GET / HTTP/1.1", host: "hotelpublisher.com"';
preg_match('~^(?P<datetime>[\d+/ :]+) \[(?P<errortype>.+)\] .*?: (?P<errormessage>.+), client: (?P<client>.+), server: (?P<server>.+), request: (?P<request>.+), host: (?P<host>.+)$~', $str, $matches);
print_r($matches);
Array
(
[0] => 2011/06/10 13:30:10 [error] 23263#0: *1 directory index of "/var/www/ssl/" is forbidden, client: 86.186.86.232, server: hotelpublisher.com, request: "GET / HTTP/1.1", host: "hotelpublisher.com"
[datetime] => 2011/06/10 13:30:10
[1] => 2011/06/10 13:30:10
[errortype] => error
[2] => error
[errormessage] => *1 directory index of "/var/www/ssl/" is forbidden
[3] => *1 directory index of "/var/www/ssl/" is forbidden
[client] => 86.186.86.232
[4] => 86.186.86.232
[server] => hotelpublisher.com
[5] => hotelpublisher.com
[request] => "GET / HTTP/1.1"
[6] => "GET / HTTP/1.1"
[host] => "hotelpublisher.com"
[7] => "hotelpublisher.com"
)