代码之家  ›  专栏  ›  技术社区  ›  Petr Macek

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

  •  39
  • Petr Macek  · 技术社区  · 16 年前

    我遇到的问题是,即使我在根标记中指定要出错的级别,指定的附加程序也会将所有级别(调试、信息、警告)记录到文件中,而不管设置如何。我不是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>
    

    如果我用另一个记录器替换根目录,则不会将任何内容记录到指定的appender。

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

    …谢谢你们的提示:-)

    6 回复  |  直到 11 年前
        1
  •  72
  •   James Bassett    11 年前

    根记录器位于记录器层次结构的顶部。它有三个例外:

    • 它总是存在的,
    • 其级别不能设置为空
    • 无法按名称检索。

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

    例如,如果 console 将appender添加到 root logger ,则所有启用的日志记录请求将 至少 在控制台上打印。如果另外在日志中添加了一个文件追加器,比如 L ,然后为 L L's 孩子们将打印在文件上 慰问 . 可以重写此默认行为,使appender累加不再是累加的。 通过将additivity标志设置为false .

    来自log4j手册

    总而言之:

    如果不想将日志事件传播到父日志记录器(比如rootlogger),那么在这些日志记录器中将additivity标志添加到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
    

    希望这有帮助。

        2
  •  8
  •   James A. N. Stauffer    16 年前

    使用-dlog4j.debug运行您的程序,以便standard out获得有关log4j配置方式的信息——我怀疑它的配置方式与您想象的不同。

        3
  •  5
  •   matt b    16 年前

    再加上james a.n.stauffer和愤世嫉俗的人所说的话——我敢打赌,在你的类路径上还有另外一个log4j.xml/log4j.properties,而不是你希望使用的那个导致log4j按原样配置自身的log4j.xml/log4j.properties。

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

        4
  •  4
  •   Asgeir S. Nilsen    16 年前

    两件事:检查additivity并决定是否希望日志事件被更详细的日志级别捕获,以传播到根日志记录器。

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

        5
  •  2
  •   Michael    16 年前

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

        6
  •  0
  •   JCaptain    14 年前

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

    使用“trace logger”记录器或“org.springframework.ws.server.endpoint.interceptor”记录器记录消息的任何代码将分别使用跟踪和调试级别任何其他代码将使用根记录器记录使用级别的消息,这在您的情况下是错误的。

    因此,如果使用的不是根日志记录器,则根日志级别将被该记录器的日志级别覆盖。要获得所需的输出,请将其他两个日志级别更改为error。

    我希望这对你有帮助。