Java Log4j:为什么不管配置如何,根记录器都会收集所有日志类型?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/86878/
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-08-11 08:08:51  来源:igfitidea点击:

Log4j: Why is the root logger collecting all log types regardless the configuration?

javalogginglog4j

提问by Petr Macek

I am having problem that even though I specify the level to ERROR in the root tag, the specified appender logs all levels (debug, info, warn) to the file regardless the settings. I am not a log4j expert so any help is appreciated.

我遇到的问题是,即使我在根标记中将级别指定为 ERROR,指定的 appender 也会将所有级别(调试、信息、警告)记录到文件中,而不管设置如何。我不是 log4j 专家,因此不胜感激。

Here is a bit more info on the subject:

以下是有关该主题的更多信息:

  • I have checked the classpath for log4j.properties (there is none) except the log4j.xml
  • 我已经检查了 log4j.properties 的类路径(没有),除了 log4j.xml

here is the log4j.xml file:

这是 log4j.xml 文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>


    <!-- ============================== -->
    <!-- Append messages to the console -->
    <!-- ============================== -->


    <appender name="console" class="org.apache.log4j.ConsoleAppender">
        <param name="Target" value="System.out" />

        <layout class="org.apache.log4j.PatternLayout">
            <!-- The default pattern: Date Priority [Category] Message\n -->
            <param name="ConversionPattern" value="[AC - %5p] [%d{ISO8601}] [%t] [%c{1} - %L] %m%n" />
        </layout>
    </appender>

    <appender name="logfile" class="org.apache.log4j.RollingFileAppender">
        <param name="File" value="./logs/server.log" />
        <param name="MaxFileSize" value="1000KB" />
        <param name="MaxBackupIndex" value="2" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="[AC - %-5p] {%d{dd.MM.yyyy - HH.mm.ss}} %m%n" />
        </layout>
    </appender>

    <appender name="payloadAppender" class="org.apache.log4j.RollingFileAppender">
        <param name="File" value="./logs/payload.log" />
        <param name="MaxFileSize" value="1000KB" />
        <param name="MaxBackupIndex" value="10" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="[AC - %-5p] {%d{dd.MM.yyyy - HH.mm.ss}} %m%n" />
        </layout>
    </appender>

    <appender name="errorLog" class="org.apache.log4j.RollingFileAppender">
        <param name="File" value="./logs/error.log" />
        <param name="MaxFileSize" value="1000KB" />
        <param name="MaxBackupIndex" value="10" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="[AC - %-5p] {%d{dd.MM.yyyy - HH.mm.ss}} %m%n" />
        </layout>
    </appender>

    <appender name="traceLog"
        class="org.apache.log4j.RollingFileAppender">
        <param name="File" value="./logs/trace.log" />
        <param name="MaxFileSize" value="1000KB" />
        <param name="MaxBackupIndex" value="20" />

        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern"
                value="[AccessControl - %-5p] {%t: %d{dd.MM.yyyy - HH.mm.ss,SSS}} %m%n" />
        </layout>
    </appender>

    <appender name="traceSocketAppender" class="org.apache.log4j.net.SocketAppender">
        <param name="remoteHost" value="localhost" />
        <param name="port" value="4445" />
        <param name="locationInfo" value="true" />
    </appender>

    <logger name="TraceLogger">
        <level value="trace" /> <!-- Set level to trace to activate tracing -->
        <appender-ref ref="traceLog" />     
    </logger>

    <logger name="org.springframework.ws.server.endpoint.interceptor">
        <level value="DEBUG" />
        <appender-ref ref="payloadAppender" />
    </logger>

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

</log4j:configuration>

If I replace the root with another logger, then nothing gets logged at all to the specified appender.

如果我用另一个记录器替换根,则没有任何记录到指定的附加程序。

<logger name="com.mydomain.logic">
    <level value="error" />
    <appender-ref ref="errorLog" />
</logger>

... and thank you guys for the hints so far:-)

...感谢你们到目前为止的提示:-)

回答by Asgeir S. Nilsen

Two things: Check additivity and decide whether you want log events captured by more detailed levels of logging to propagate to the root logger.

两件事:检查可加性并决定是否希望由更详细的日志记录级别捕获的日志事件传播到根记录器。

Secondly, check the level for the root logger. In addition you can also add filtering on the appender itself, but this should normally not be necessary.

其次,检查根记录器的级别。此外,您还可以在 appender 本身上添加过滤,但这通常不是必需的。

回答by James A. N. Stauffer

Run your program with -Dlog4j.debug so that standard out gets info about how log4j is configured -- I suspected that it isn't configured the way that you think it is.

使用 -Dlog4j.debug 运行您的程序,以便标准输出获取有关如何配置 log4j 的信息——我怀疑它没有按照您认为的方式进行配置。

回答by matt b

To add on to what James A. N. Stauffer and cynicalman said - I would bet that there is another log4j.xml / log4j.properties on your classpath other than the one you wish to be used that is causing log4j to configure itself the way it is.

补充一下 James AN Stauffer 和愤世嫉俗者所说的内容 - 我敢打赌,除了您希望使用的导致 log4j 配置自身的类路径之外,您的类路径中还有另一个 log4j.xml / log4j.properties。

-Dlog4j.debugis an absolute killer way to troubleshoot any log4j issues.

-Dlog4j.debug是解决任何 log4j 问题的绝对杀手级方法。

回答by Michael

If you are using a log4j.propertiesfile, this file is typically expected to be in the root of your classpath, so make sure it's there.

如果您使用的是log4j.properties文件,则该文件通常应位于类路径的根目录中,因此请确保它在那里。

回答by JCaptain

This is correct behavior. The root logger is like the default behavior. So if you don't specify any logger it will take root logger level as the default level but this does not mean that root logger level is the level for all your logs.

这是正确的行为。根记录器就像默认行为。因此,如果您不指定任何记录器,它将以根记录器级别作为默认级别,但这并不意味着根记录器级别是所有日志的级别。

Any of your code which logs using 'TraceLogger'logger or 'org.springframework.ws.server.endpoint.interceptor' logger will log messages using TRACE and DEBUG level respectively any other code will use root logger to log message using level, which is in your case ERROR.

使用“TraceLogger”记录器或“org.springframework.ws.server.endpoint.interceptor”记录器记录的任何代码将分别使用TRACE和DEBUG级别记录消息任何其他代码将使用根记录器使用级别记录消息,即在你的情况下错误。

So if you use logger other than root, root log level will be overridden by that logger's log level. To get the desired output change the other two log level to ERROR.

因此,如果您使用 root 以外的 logger,则 root 日志级别将被该 logger 的日志级别覆盖。要获得所需的输出,请将其他两个日志级别更改为 ERROR。

I hope this is helpful.

我希望这是有帮助的。

回答by monzonj

The root logger resides at the top of the logger hierarchy. It is exceptional in three ways:

根记录器位于记录器层次结构的顶部。它在三个方面非常出色:

  • it always exists,
  • its level cannot be set to null
  • it cannot be retrieved by name.
  • 它一直存在,
  • 其级别不能设置为空
  • 它不能通过名称检索。

The rootLogger is the father of all appenders. Each enabled logging request for a given logger will be forwarded to all the appenders in that logger as well as the appenders higher in the hierarchy (including rootLogger)

rootLogger 是所有 appender 的父亲。给定记录器的每个启用的日志记录请求都将转发到该记录器中的所有附加程序以及层次结构中更高的附加程序(包括 rootLogger)

For example, if the consoleappender is added to the root logger, then all enabled logging requests will at leastprint on the console. If in addition a file appender is added to a logger, say L, then enabled logging requests for Land L'schildren will print on a file andon the console. It is possible to override this default behavior so that appender accumulation is no longer additive by setting the additivity flag to false.

例如,如果将consoleappender 添加到root logger,则所有启用的日志记录请求至少会打印在控制台上。如果另外一个文件附加目的地添加到记录器,比如说L,则启用日志的请求LL's儿童将打印上的文件console。可以通过将 additivity 标志设置为 false来覆盖此默认行为,以便 appender 累积不再是可加的

From the log4j manual

来自 log4j 手册

To sum up:

总结:

If you want not to propagate a logging event to the parents loggers (say rootLogger) then add the additivity flag to false in those loggers. In your case:

如果您不想将日志事件传播到父记录器(例如 rootLogger),则在这些记录器中将可加性标志添加为 false。在你的情况下:

<logger name="org.springframework.ws.server.endpoint.interceptor"
        additivity="false">
        <level value="DEBUG" />
        <appender-ref ref="payloadAppender" />
</logger>

In standard log4j config style (which I prefer to XML):

在标准的 log4j 配置样式中(我更喜欢 XML):

log4j.logger.org.springframework.ws.server.endpoint.interceptor = INFO, payloadAppender
log4j.additivity.org.springframework.ws.server.endpoint.interceptor = false

Hope this helps.

希望这可以帮助。