Log4j:为什么无论配置如何,root logger都会收集所有日志类型?

时间:2020-03-05 18:59:49  来源:igfitidea点击:

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

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

  • 我已经检查了log4j.properties的类路径(没有),除了log4j.xml

这是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>

如果我用另一个记录器替换根目录,那么什么都不会记录到指定的添加程序。

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

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

解决方案

回答

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

其次,检查根记录器的级别。此外,我们还可以在添加程序本身上添加过滤,但是通常不需要这样做。

回答

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

回答

补充一下James A. N. Stauffer和cynicalman所说的话,我敢打赌,类路径上还有另一个log4j.xml / log4j.properties,而不是我们希望使用的那个,它导致log4j按其自身方式进行配置。

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

回答

如果我们使用的是log4j.properties文件,则通常希望该文件位于类路径的根目录中,因此请确保该文件位于该目录中。

回答

这是正确的行为。根记录器类似于默认行为。因此,如果我们未指定任何记录器,它将采用根记录器级别作为默认级别,但这并不意味着根记录器级别是所有日志的级别。

使用'TraceLogger'记录器或者'org.springframework.ws.server.endpoint.interceptor'记录器记录的任何代码将分别使用TRACE和DEBUG级别记录消息,其他任何代码将使用root记录器使用level记录消息。在情况下为ERROR。

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

我希望这是有帮助的。

回答

根记录器位于记录器层次结构的顶部。它在三种方式上是例外的:

  • 它一直存在,
  • 其级别不能设置为null
  • 无法通过名称检索。

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

例如,如果将" console"添加程序添加到" root logger",则所有已启用的日志记录请求至少将在控制台上打印。如果另外将文件追加器添加到记录器中,例如说" L",则对" L"和" L"子级启用的记录请求将打印在文件和"控制台"上。可以覆盖此默认行为,以便通过将可加性标志设置为false不再增加添加器累积。

从log4j手册

总结一下:

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

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

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

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

希望这可以帮助。