【问题标题】:log4php is anti-intuitive (was not honouring logger levels)log4php 是反直觉的(不尊重记录器级别)
【发布时间】:2014-03-19 18:30:45
【问题描述】:

我正在尝试使用 log4php,但无法理解 配置,我正在比较从 log4j xml 到 log4php 的行为 xml 是一样的。相同的代码。但是输出不同。来自 文档我希望记录 5 行,但在 log4php 中,只有 一个是。 拜托,我快把自己逼疯了。

PHP 代码:

<?php

include("log4php/Logger.php");

Logger::configure('log4php.xml');

$rlogger = Logger::getRootLogger();
$rlogger->debug('Not logged');
$rlogger->error('Logged');

$logger = Logger::getLogger('com.suri');
$logger->debug('Logged');
$logger->warn('Logged');

$logger = Logger::getLogger('com.suri.factory');
$logger->debug('Not logged');
$logger->warn('Logged');

$logger = Logger::getLogger('com.suri.factory.Bar');
$logger->debug('Not logged');
$logger->info('Logged');

?>

XML 配置:

<?xml version="1.0" encoding="UTF-8" ?>
<configuration xmlns="http://logging.apache.org/log4php/">
  <!-- A1 is set to be a ConsoleAppender -->
  <appender name="A1" class="LoggerAppenderConsole">
    <layout class="LoggerLayoutPattern">
      <param name="ConversionPattern" value="%d [%t] - %-5p %c - %m%n"/>
    </layout>
  </appender>

  <logger name="com.suri.factory.Bar">
    <level value="info"/>
  </logger>
  <logger name="com.suri.factory">
    <level value="warn"/>
  </logger>

  <logger name="com">
    <level value="debug"/>
  </logger>

  <root>
    <level value="error" />
    <appender-ref ref="A1" />
  </root>

</configuration>

输出:

2014-03-13T18:01:30-03:00 [14939] - ERROR root - Logged

预期输出(在 jython+log4j 中使用相同的配置和相同的代码生成):

2014-03-13 18:09:03,591 [main] - ERROR root - Logged
2014-03-13 18:09:03,592 [main] - DEBUG com.suri - Logged
2014-03-13 18:09:03,592 [main] - WARN  com.suri - Logged
2014-03-13 18:09:03,592 [main] - WARN  com.suri.factory - Logged
2014-03-13 18:09:03,592 [main] - INFO  com.suri.factory.Bar - Logged

jython 代码:

from org.apache.log4j import *
from org.apache.log4j.xml import *


if __name__ == '__main__':
    xml.DOMConfigurator.configure('log4j.xml')
    rlogger = LogManager.getRootLogger()
    rlogger.debug('Not logged');
    rlogger.error('Logged');

    logger = LogManager.getLogger('com.suri');
    logger.debug('Logged');
    logger.warn('Logged');

    logger = LogManager.getLogger('com.suri.factory');
    logger.debug('Not logged');
    logger.warn('Logged');

    logger = LogManager.getLogger('com.suri.factory.Bar');
    logger.debug('Not logged');
    logger.info('Logged');

Jython XML 配置:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
  <!-- A1 is set to be a ConsoleAppender -->
  <appender name="A1" class="org.apache.log4j.ConsoleAppender">
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d [%t] - %-5p %c - %m%n"/> 
    </layout> 
  </appender>

  <logger name="com.suri.factory.Bar">
    <level value="info"/> 
  </logger>
  <logger name="com.suri.factory">
    <level value="warn"/>
  </logger>

  <logger name="com">
    <level value="debug"/>
  </logger>

  <root>
     <level value="error" />
    <appender-ref ref="A1" /> 
  </root>

</log4j:configuration>

谢谢!

【问题讨论】:

    标签: php log4j log4php


    【解决方案1】:

    按照目前的配置方式,Log4PHP 不会记录任何低于错误级别的内容。这是因为任何配置的记录器(应该被视为日志消息入口点)仅传递等于或高于其配置阈值的消息,并且实际上只有根记录器配置了一个附加程序,它只会如果日志消息级别高于 IT 阈值,则记录(即,任何低于 ERROR 级别的消息都不会被记录)。

    您可以通过向要配置的每个可用记录器添加附加程序来解决此问题。这样,这个 logger 本身会尝试将消息写入 appender,并且还会将其传递到链上。请注意,如果父记录器的阈值等于或小于原始记录器,这可能会导致消息被写入两次。为避免向上游传递消息,您可以使用 additivity="false" 属性。

    请注意,实际上您可以对所有记录器多次使用同一个附加程序,以便只能配置一次,但根据实际记录器的配置方式记录所有不同级别的消息。

    另请注意,Log4PHP 与 log4j 是不同的产品 - 虽然它们看起来很相似,但开发人员不一定会相互交互,并且支持相同的配置格式并以相同的方式启用相同的功能可能没有启用他们的路线图。这实际上对每个单独的项目都是一件好事,因为额外支持完全不同的团队做出的配置决策将是一个硬性限制。

    所以最后,我建议你这样配置:

    <?xml version="1.0" encoding="UTF-8" ?>
    <configuration xmlns="http://logging.apache.org/log4php/">
      <!-- A1 is set to be a ConsoleAppender -->
      <appender name="A1" class="LoggerAppenderConsole">
        <layout class="LoggerLayoutPattern">
          <param name="ConversionPattern" value="%d [%t] - %-5p %c - %m%n"/>
        </layout>
      </appender>
    
      <logger name="com.suri.factory.Bar" additivity="false">
        <level value="info"/>
        <appender-ref ref="A1" />
      </logger>
      <logger name="com.suri.factory" additivity="false">
        <level value="warn"/>
        <appender-ref ref="A1" />
      </logger>
    
      <logger name="com" additivity="false">
        <level value="debug"/>
        <appender-ref ref="A1" />
      </logger>
    
      <root>
        <level value="error" />
        <appender-ref ref="A1" />
      </root>
    
    </configuration>
    

    如果你可以避免使用 XML 作为配置源会更好,而是使用 PHP 数组配置,因为你可以避免每次请求都解析 XML,但是 PHP 将能够缓存配置文件(这是 PHP 代码)在它的操作码缓存中。要获取代表您当前 XML 配置的 PHP 数组,您可以像这样转储结果:

    $configurator = new LoggerConfiguratorDefault();
    $config = $configurator->parse('/path/to/config.xml');
    var_export($config); // prints to stdout
    

    【讨论】:

    • 我明白了。我认为这是对我的问题的正确答案。我认为log4php的设计方式是有缺陷的,它应该尽量模仿log4j,否则改名。此外,我觉得文档具有误导性,并且它的实现方式需要更多的配置(所有可加性)。谢谢!
    【解决方案2】:

    您将阈值级别设置为最高(在您的情况下为error),因此此记录器不会记录较低的级别。read Logger threshold here

    在您的 xml 配置文件中更改以下内容:

    <root>
      <level value="TRACE" />
      <appender-ref ref="A1" />
    </root>
    

    see the different level of threshold here.

    根据log4php:

    可以为记录器分配阈值级别。所有级别低于此阈值的日志记录请求都将被忽略。

    例如,将记录器阈值设置为 INFO 意味着此记录器不会记录级别为 TRACE 和 DEBUG 的记录请求。

    希望对你有用。

    【讨论】:

    • 这不是解决方案。降低根级别只会使其记录每条消息。检查代码,它会记录不应该的消息。另外,我相信 log4php 中存在实现错误。为什么它对于相同的配置会有不同的工作方式?
    • 对不起,如果我显得直率。但我发现两种实现的工作方式不同,这让我非常沮丧。
    • log4php 为您的代码生成此输出2014-03-13T18:01:30-03:00 [14939] - ERROR root - Logged,这是正确的,因为您的日志级别设置为error。查看我的更新答案。
    • 我的主要问题是相同的配置,log4php 和 log4j 中的相同代码会产生不同的日志。阅读文档我得到的想法是,如果我为链中的记录器设置不同的记录阈值,则使用该记录器进行记录应该打印预期的消息(代码中的“记录”消息)。问候
    猜你喜欢
    • 2016-12-13
    • 2019-12-06
    • 1970-01-01
    • 2013-11-15
    • 1970-01-01
    • 2019-01-10
    • 1970-01-01
    • 2020-07-21
    • 1970-01-01
    相关资源
    最近更新 更多