在foreach循环中过滤数组

时间:2014-01-23 10:42:47

标签: php regex arrays filter

过去几天我一直陷入困境。我已经搜索和搜索但是发布的示例和技术仅部分工作,而不是它们在循环中。基本上我要做的是为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下拉选项,让用户选择[错误]或[注意],但我如何使用它们来过滤掉日志并查看它们?。

3 个答案:

答案 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}'"