过去几天我一直陷入困境。我已经搜索和搜索但是发布的示例和技术仅部分工作,而不是它们在循环中。基本上我要做的是为Apache日志文件制作一个过滤器。使用以下代码,我可以将Apache日志拆分为其基本块。使用这些块我想创建过滤器。
<?php
$out = array();
exec('tail -n 5 /var/log/httpd/error_log',$out);
foreach($out as $output){
preg_match('~^\[(.*?)\]~',$output,$date);
preg_match('~\ \[([a-z]*?)\] ~',$output,$type);
preg_match('~\ \[client ([0-9\.]*)\]~',$output,$client);
preg_match('~[a-z\A-Z\.0-9][^\]]*$~',$output,$message);
echo "</br>";
echo "Date chunk = ";
print_r($date[0]);
echo "</br>";
echo "Type chunk = ";
print_r($type[0]);
echo "</br>";
echo "Client chunk =";
print_r ($client[0]);
echo "</br>";
echo "Message chunk = ";
print_r ($message[0]);
echo "</br>";
}
?>
这是一个截屏。
http://i.imgur.com/BAZaWDc.png
在apache日志文件中,类型块可以是[error]或[Notice],我希望有办法过滤日志文件并查看它们。例如,我只希望显示包含[error]类型的日志,或者键入[Notice]来显示,甚至日期块也可以用作过滤器来查看来自不同日期的日志。我可以制作一个php下拉选项,让用户选择[错误]或[注意],但我如何使用它们来过滤掉日志并查看它们?。
答案 0 :(得分:0)
这里有regexp(与preg_match_all一起使用):
(\[[^\]]+\])\s(\[[^\]]+\])\s(\[[^]]+\]):\s([^$]+)
使用此字符串,例如
[Thu Jan 23 02:00:48 2014] [error] [mod_geoip]: Error while opening data file
preg_match_all返回
Array
(
[0] => Array
(
[0] => [Thu Jan 23 02:00:48 2014] [error] [mod_geoip]: Error while opening data file
)
[1] => Array
(
[0] => [Thu Jan 23 02:00:48 2014]
)
[2] => Array
(
[0] => [error]
)
[3] => Array
(
[0] => [mod_geoip]
)
[4] => Array
(
[0] => Error while opening data file
)
)
答案 1 :(得分:0)
假设您有一个包含以下值的过滤器表单,您将正确执行必要的输入验证:
Log Type : error, notice(select options)
start date : filter start date()
end date : filter end date
在你的php文件中
$search_type = isset($_POST['log_type'])?"[".$_POST['log_type']."]":FALSE;
$start_date = isset($_POST['start_date'])?$_POST['start_date']:FALSE;
$end_date = isset($_POST['end_date'])?$_POST['end_date']:FALSE;
$result= array();
foreach($out as $output){
$fl = false;
$tempStr = substr(substr($date[0],0,-1),1);
..................
....................
if( $search_type && ($type[0]==$search_type){
$fl = true;
}
if($start_date){
if( strtotime($start_date." 0:0:0 ") >= strtotime($tempstr) ){
$fl=true;
}
}
if($end_date){
if( strtotime($end_date." 0:0:0 ") <= strtotime($tempstr) ){
$fl=true;
}
}
if($fl==true){
$result[] = array('date'=>date[0],'type'=>$type[0],'client'=>$client[0],'message'=>$message[0]);
}
}
的print_r($结果;)
答案 2 :(得分:0)
非常感谢你们,非常乐于助人的见解。头脑风暴一段时间之后,我认为最好直接从centos实现一个方法,而不是完整的php。我正在为其他任何可能找到这个帮助的人发布该方法
您可以使用Bash / PHP填充$ Day变量,它应该是Sun,Mon,Tue,Wed等格式。返回的日志行只是1000行中$ Day的日志行。 awk的美妙之处在于您可以通过Date / type / ip =)进行调整,只需更改$ 1到$ 2,$ 3等,并将$ Day变量更改为正确的类型。
tail -n 1000 /var/log/httpd/error_log | awk -F " " '{if $1 =="[Tue") print $all}'
对于php,你需要逃脱。
"tail -n 1000 /var/log/httpd/error_log | awk -F \" \" '{if $1 == \"[$Day\") print $all}'"