如何在PHP中解析Apache的错误日志?

时间:2022-10-05 18:35:13

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的错误日志,看看最近的错误是什么。我想知道是否有人有这样做或有任何想法从哪里开始?

5 个解决方案

#1


13  

There are a few things to consider first:

首先要考虑以下几点:

  1. Firstly, your PHP user may not have access to Apache's log files.
  2. 首先,您的PHP用户可能无法访问Apache的日志文件。

  3. Secondly, PHP and Apache aren't going to tell you where said log file is,
  4. 其次,PHP和Apache不会告诉你日志文件在哪里,

  5. Lastly, Apache log files can get quite large.
  6. 最后,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还有一个将PHP错误重定向到日志文件的ini设置: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

#2


11  

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>

#3


3  

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 files are in. the format is also defined in httpd.conf

有成堆的PHP脚本执行此操作,只需谷歌搜索示例。如果你想自己动手,那就没有比阅读任何其他文件更复杂了。只需确保您知道日志文件的位置(在httpd.conf文件中定义)和日志文件所在的格式。格式也在httpd.conf中定义

#4


3  

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>";
}

?> 

#5


0  

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 - >免费下载。

#1


13  

There are a few things to consider first:

首先要考虑以下几点:

  1. Firstly, your PHP user may not have access to Apache's log files.
  2. 首先,您的PHP用户可能无法访问Apache的日志文件。

  3. Secondly, PHP and Apache aren't going to tell you where said log file is,
  4. 其次,PHP和Apache不会告诉你日志文件在哪里,

  5. Lastly, Apache log files can get quite large.
  6. 最后,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还有一个将PHP错误重定向到日志文件的ini设置: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

#2


11  

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>

#3


3  

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 files are in. the format is also defined in httpd.conf

有成堆的PHP脚本执行此操作,只需谷歌搜索示例。如果你想自己动手,那就没有比阅读任何其他文件更复杂了。只需确保您知道日志文件的位置(在httpd.conf文件中定义)和日志文件所在的格式。格式也在httpd.conf中定义

#4


3  

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>";
}

?> 

#5


0  

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 - >免费下载。