【问题标题】:Edit prepended date format in error_log在 error_log 中编辑前置日期格式
【发布时间】:2016-05-25 19:37:25
【问题描述】:

PHP 5.6

有什么方法可以定义使用error_log 时显示的日期格式吗?

我正在使用它来记录来自某个脚本的消息和错误。好像是set_error_handlerwon't handle all error messages

在一些例子中,人们直接在error_log 的参数前面加上date 的日期。使用这种方法会导致我的日志文件中出现重复的日期字符串。

我想输出一个 ISO 格式的本地日期时间,但是我在 CLI (php -f script.php) 和 Apache 上使用的日期前缀

ini_set('log_errors', 1);
ini_set('error_log', 'file.log');
error_log('Test');

是这样的:

[14-Feb-2016 18:07:31 America/Mexico_City] Test

请注意,在大多数代码示例中,日期格式通常不包括时区。而且,如果我从控制台运行它,我不会得到前面的日期:

$ php -r 'error_log("Test");'
Test

时区未在运行时或 php.ini 中设置,但已正确表示。我在php5.6.18 package 和从源代码 php5.6.13 编译时得到了这种行为。在生产服务器上,脚本通过 CLI 运行,没有安装 apache。

解决方案

似乎 error_log 显示的日期不可自定义。 按照@fusion3k 的建议,继续使用set_error_handler,我将这个错误处理程序放在一起,它将以更计算机/人类友好的格式格式化日期、消息和错误级别

// set_trigger_error only accepts E_USER_ constants values
define('ERROR', 256);   // Before E_USER_ERROR
define('INFO',  512);   // Before E_USER_WARNING
define('DEBUG', 1024);  // Before E_USER_NOTICE

function errorHandler ($errType, $errStr, $errFile, $errLine, $errContext) {
    $displayErrors = ini_get( 'display_errors' );
    $logErrors     = ini_get( 'log_errors' );
    $errorLog      = ini_get( 'error_log' );

    if( $displayErrors ) echo $errStr.PHP_EOL;

    if( $logErrors ) {
        $line = "";
        switch ($errType) {
            case DEBUG: 
                $type = 'DEBUG'; 
                break;
            case INFO: 
                $type = 'INFO'; 
                break;
            case ERROR: 
                $type = 'ERROR'; 
                $line = " (Line:".$errLine.")";
                break;
            default: 
                $type = 'WARN'; 
                $line = " (Line:".$errLine.")";
                break;
        }
        $message = date('Y-m-d H:i:sO').";".$type.";".$errStr.$line;
        file_put_contents($errorLog, $message.PHP_EOL, FILE_APPEND);
    }
}

set_error_handler('errorHandler');

error_reporting(E_ALL);
ini_set('log_errors', 1);
ini_set('error_log', 'test.log');

trigger_error('Test', DEBUG);

输出

2016-02-15 14:20:05-0600;DEBUG;Test

【问题讨论】:

标签: php error-logging


【解决方案1】:

如果您使用您的自定义错误日志文件,您可以简单地将您喜欢的日期格式添加到日志消息中。

如果你使用标准的Apache日志文件,你不能通过php修改日志格式。

您必须改为在 httpd.confLogFormat 关键字中修改整个 Apache 错误日志格式:用您想要的格式替换现有格式。

Here 你可以找到LogFormat 的完整语法指南。

编辑:

在您的最后评论之后,我通过互联网搜索并进行了一些测试,然后我意识到我之前的答案不正确:无法修改 php.ini 中的error_log() 行为。就我而言(我安装了 Apache),error_log() 函数在自定义日志文件(通过ini_set('error_log') 定义)上输出 Apache 日志格式甚至

在你的情况下,我认为php使用操作系统日志格式(你确定你没有安装Apache,即使你不使用它?)。

替代方案:trigger_error()

您可以使用trigger_error()(与set_error_handler() 结合使用)来设置完全可自定义的错误日志格式,而不是error_log()

function myErrorHandler( $errType, $errStr, $errFile, $errLine, $errContext )
{
    $displayErrors = ini_get( 'display_errors' );
    $logErrors     = ini_get( 'log_errors' );
    $errorLog      = ini_get( 'error_log' );

    if( $displayErrors ) echo $errStr.PHP_EOL;

    if( $logErrors )
    {
        $message = sprintf( '[%s] %s (%s, %s)', date('d-m H:i'), $errStr, $errFile, $errLine );
        file_put_contents( $errorLog, $message.PHP_EOL, FILE_APPEND );
    }
}

ini_set( 'log_errors', 1 );
ini_set( 'error_log', 'file.log' );

set_error_handler( 'myErrorHandler' );
trigger_error( 'Test' );

在上面的示例中,trigger_error 将在 file.log 中附加如下一行:

[15-02 09:43] Test (Script/File/Path.php, 12)

设置error_handler所有系统错误由自定义函数处理。要模拟系统错误,您必须使用trigger_error() 而不是error_log()

要最大化自定义,可以传递给trigger_error附加参数error_type

trigger_error( 'Test', E_WARNING );

会产生警告级别错误;默认error_type 值为E_USER_NOTICE。错误类型是自定义函数中的第一个参数($errType),因此在自定义错误处理函数中,您可以根据错误类型修改行为。

在我上面的简单示例中,自定义函数还处理了一些ini 指令,因此您可以将ini_setset_error_handler 结合使用。请注意,您可以更改自定义函数参数的变量名称,但不能更改顺序,因为这是由内部 php 错误系统定义的。

如果您决定使用set_error_handler(),请仔细阅读documentation 以了解行为和异常情况。


【讨论】:

  • 脚本正在生产服务器中使用php -f file.php 运行。那里甚至没有安装apache。但更重要的是,“自定义错误日志文件”是什么意思?
  • 我很确定我没有安装 apache。我的系统中没有 httpd.conf。而/etc/apache2/ 只有一个文件:conf.d/javascript-common.conf/etc/javascript-common/javascript-common.conf 的符号链接。 /usr/share/wwwconfig-common/ 中有一些与 apache 相关的脚本,我将使用自定义错误句柄。我简直不敢相信error_log 不可编辑
  • @Sdlion 我忘了检查 php.ini 文件:在我的 php.ini 中有很多错误/日志配置,但没有关于日志格式的内容。我说“你确定你没有安装 Apache”,因为你的日期日志格式看起来像我的 Apache 错误日志格式。
  • 我认为 apache ErrorLog 指令不会遵循 LogFormat,因为它 (LogFormat) 可以被 CustomLog 指令使用
【解决方案2】:

(我将@Sdlion 的答案复制到它自己的答案中,以便我们对其进行投票)

似乎 error_log 显示的日期不可自定义。按照@fusion3k 的建议,继续使用 set_error_handler,我将这个错误处理程序放在一起,它将使用更计算机/人类友好的格式格式化日期、消息和错误级别

// set_trigger_error only accepts E_USER_ constants values
define('ERROR', 256);   // Before E_USER_ERROR
define('INFO',  512);   // Before E_USER_WARNING
define('DEBUG', 1024);  // Before E_USER_NOTICE

function errorHandler ($errType, $errStr, $errFile, $errLine, $errContext) {
    $displayErrors = ini_get( 'display_errors' );
    $logErrors     = ini_get( 'log_errors' );
    $errorLog      = ini_get( 'error_log' );

    if( $displayErrors ) echo $errStr.PHP_EOL;

    if( $logErrors ) {
        $line = "";
        switch ($errType) {
            case DEBUG: 
                $type = 'DEBUG'; 
                break;
            case INFO: 
                $type = 'INFO'; 
                break;
            case ERROR: 
                $type = 'ERROR'; 
                $line = " (Line:".$errLine.")";
                break;
            default: 
                $type = 'WARN'; 
                $line = " (Line:".$errLine.")";
                break;
        }
        $message = date('Y-m-d H:i:sO').";".$type.";".$errStr.$line;
        file_put_contents($errorLog, $message.PHP_EOL, FILE_APPEND);
    }
}

set_error_handler('errorHandler');

error_reporting(E_ALL);
ini_set('log_errors', 1);
ini_set('error_log', 'test.log');

trigger_error('Test', DEBUG);

输出

2016-02-15 14:20:05-0600;DEBUG;Test

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-29
    • 2015-05-24
    相关资源
    最近更新 更多