apache 如何在 PHP 中解析 A​​pache 的错误日志?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/159393/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 16:48:28  来源:igfitidea点击:

How can I parse Apache's error log in PHP?

phpapacheerror-log

提问by SeanDowney

I want to create a script that parses or makes sense of apache's error log to see what the most recent error was. I was wondering if anyone out there has something that does this or has any ideas where to start?

我想创建一个脚本来解析或理解 apache 的错误日志,以查看最近的错误是什么。我想知道是否有人在那里做这件事或有任何想法从哪里开始?

采纳答案by Powerlord

There are a few things to consider first:

首先需要考虑以下几点:

  1. Firstly, your PHP user may not have access to Apache's log files.
  2. Secondly, PHP and Apache aren't going to tell you where said log file is,
  3. Lastly, Apache log files can get quite large.
  1. 首先,您的 PHP 用户可能无法访问 Apache 的日志文件。
  2. 其次,PHP 和 Apache 不会告诉你所说的日志文件在哪里,
  3. 最后,Apache 日志文件可能会变得非常大。

However, if none of these apply, you can use the normal file reading commands to do it. The easiest way to get the last error is

但是,如果这些都不适用,您可以使用普通的文件读取命令来完成。获得最后一个错误的最简单方法是

$contents = @file('/path/to/error.log', FILE_SKIP_EMPTY_LINES);
if (is_array($contents)) {
    echo end($contents);
}
unset($contents);

There's probably a better way of doing this that doesn't oink up memory, but I'll leave that as an exercise for the reader.

可能有一种更好的方法来做到这一点,而不会增加记忆,但我将把它留给读者作为练习。

One last comment: PHP also has an ini setting to redirect PHP errors to a log file: error_log = /path/to/error.log

最后一条评论:PHP 还有一个 ini 设置可以将 PHP 错误重定向到日志文件: error_log = /path/to/error.log

You can set this in httpd.conf or in an .htaccess file (if you have access to one) using the php_flag notation:

您可以使用 php_flag 表示法在 httpd.conf 或 .htaccess 文件(如果您可以访问)中设置它:

php_flag error_log /web/mysite/logs/error.log

回答by SeanDowney

for anyone else looking for a sample script, i threw something together, it's got the basics:

对于正在寻找示例脚本的其他人,我将一些东西放在一起,它具有基础知识:

<?php
exec('tail /usr/local/apache/logs/error_log', $output);
?>
<Table border="1">
    <tr>
        <th>Date</th>
        <th>Type</th>
        <th>Client</th>
        <th>Message</th>
    </tr>
<?
    foreach($output as $line) {
        // sample line: [Wed Oct 01 15:07:23 2008] [error] [client 76.246.51.127] PHP 99. Debugger->handleError() /home/gsmcms/public_html/central/cake/libs/debugger.php:0
        preg_match('~^\[(.*?)\]~', $line, $date);
        if(empty($date[1])) {
            continue;
        }
        preg_match('~\] \[([a-z]*?)\] \[~', $line, $type);
        preg_match('~\] \[client ([0-9\.]*)\]~', $line, $client);
        preg_match('~\] (.*)$~', $line, $message);
        ?>
    <tr>
        <td><?=$date[1]?></td>
        <td><?=$type[1]?></td>
        <td><?=$client[1]?></td>
        <td><?=$message[1]?></td>
    </tr>
        <?
    }
?>
</table>

回答by Owen

there are piles of php scripts that do this, just do a google search for examples. if you want to roll your own, it's nothing more complex than reading any other file. just make sure you know the location of your logfiles (defined in the httpd.conf file) and the format your log filesare in. the format is also defined in httpd.conf

有成堆的 php 脚本可以做到这一点,只需在谷歌上搜索示例即可。如果你想推出自己的,没有什么比阅读任何其他文件更复杂的了。只需确保您知道日志文件的位置(在 httpd.conf 文件中定义)和日志文件的格式。该格式也在 httpd.conf 中定义

回答by Ben Haley

Here's a small-ish class that makes it easy to read a number of characters from the back of a large file w/o overloading memory. The test setting lets you see it in action cannibalizing itself.

这是一个小型类,可以轻松地从大文件的背面读取多个字符而无需超载内存。测试设置让您可以看到它在蚕食自身。

BigFile.php
<?php
$run_test = true;
$test_file = 'BigFile.php';

class BigFile
{
private $file_handle;

/**
 * 
 * Load the file from a filepath 
 * @param string $path_to_file
 * @throws Exception if path cannot be read from
 */
public function __construct( $path_to_log )
{
    if( is_readable($path_to_log) )
    {
        $this->file_handle = fopen( $path_to_log, 'r');
    }
    else
    {
        throw new Exception("The file path to the file is not valid");
    } 
}

/**
 * 
 * 'Finish your breakfast' - Jay Z's homme Strict
 */
public function __destruct()
{
    fclose($this->file_handle); 
}

/**
 * 
 * Returns a number of characters from the end of a file w/o loading the entire file into memory
 * @param integer $number_of_characters_to_get
 * @return string $characters
 */
public function getFromEnd( $number_of_characters_to_get )
{
    $offset = -1*$number_of_characters_to_get;
    $text = "";

    fseek( $this->file_handle, $offset , SEEK_END);

    while(!feof($this->file_handle))
    {
        $text .= fgets($this->file_handle);
    }

    return $text;
}
}

if( $run_test )
{
$number_of_characters_to_get =  100000; 
$bf = new BigFile($test_file);
$text = $bf->getFromEnd( $number_of_characters_to_get );
echo "$test_file has the following $number_of_characters_to_get characters at the end: 
    <br/> <pre>$text</pre>";
}

?> 

回答by keedy

adm group has access of to view logs in linux system to access the log from apache we have to add www-data user to adm group and restart the apache so all the changes will update

adm 组有权查看 linux 系统中的日志以从 apache 访问日志我们必须将 www-data 用户添加到 adm 组并重新启动 apache 以便所有更改都会更新

$ sudo usermod -G adm www-data
$ sudo service apache2 restart

<?php
 exec('tail /var/log/apache2/error_log', $output);
?>
<Table border="1">
<tr>
    <th>Date</th>
    <th>Type</th>
    <th>Client</th>
    <th>Message</th>
</tr>
<?php
foreach($output as $line) {
    // sample line: [Mon Apr 01 07:23:14.217466 2019] [autoindex:error] [pid 19261] [client 114.143.38.172:55801] AH01276:PHP 99. Debugger->handleError() 
   /home/gsmcms/public_html/central/cake/libs/debugger.php:0

    preg_match('~^\[(.*?)\]~', $line, $date);
    if(empty($date[1])) {
        continue;
    }
    preg_match('~\] \[([a-z:]*?)\] \[~', $line, $type);
    preg_match('~\] \[client ([0-9\.:]*)\]~', $line, $client);
    preg_match('~\] (.*)$~', $line, $message);
    ?>
<tr>
    <td><?=$date[1]?></td>
    <td><?=$type[1]?></td>
    <td><?=$client[1]?></td>
    <td><?=$message[1]?></td>
</tr>
    <?
}
?>

回答by keedy

Have you tried biterScripting ? I am a system admin and I have been using to parse logs. It is univx style scripting. biterScripting.com -> Free download.

你试过 biterScripting 吗?我是系统管理员,我一直在用来解析日志。它是 univx 风格的脚本。biterScripting.com -> 免费下载。