哪个是使用PHP从巨大的日志文件中删除行列表的更快方法

时间:2017-03-10 09:29:41

标签: php logging

我需要从巨大的日志文件中删除各种无用的日志行(200 MB) /usr/local/cpanel/logs/error_log

无用的日志行在数组$useless

我正在做的是

$working_log="/usr/local/cpanel/logs/error_log";        
foreach($useless as $row) 
{

    if ($row!="") {
        file_put_contents($working_log, 
            str_replace("$row","",  file_get_contents($working_log)));
    }
}

我需要从日志文件中删除大约65000行; 上面的代码完成了这项工作,但它工作缓慢,每行删除大约0.041秒。

您是否知道使用php更快地完成这项工作?

1 个答案:

答案 0 :(得分:1)

如果文件可以在内存中加载两次(如果您的代码可以正常工作),那么您可以在$useless次调用中删除str_replace()中的所有字符串。

str_replace()功能的文档解释了如何:

  

如果search是一个数组且replace是一个字符串,则此替换字符串将用于search的每个值。

$working_log="/usr/local/cpanel/logs/error_log";
file_put_contents(
    $working_log,
    str_replace($useless, '', file_get_contents($working_log))
);

当文件变得太大而无法通过上面的代码处理时,您必须采用不同的方法:创建临时文件,从输入文件中读取每一行并将其写入临时文件或忽略它。最后,将临时文件移到源文件上:

$working_log="/usr/local/cpanel/logs/error_log";
$tempfile = "/usr/local/cpanel/logs/error_log.new";

$fin  = fopen($working_log, "r");
$fout = fopen($tempfile, "w");
while (! feof($fin)) {
    $line = fgets($fin);
    if (! in_array($line, $useless)) {
        fputs($fout, $line);
    }
}
fclose($fin);
fclose($fout);

// Move the current log out of the way (keep it as backup)
rename($working_log, $working_log.".bak");
// Put the new file instead.
rename($tempfile, $working_log);

您必须添加错误处理(fopen()fputs()可能因各种原因而失败)以及代码或人工干预以删除备份文件。