Java 为什么两个记录器不根据它们在Log4j中的级别拆分消息?

Java 为什么两个记录器不根据它们在Log4j中的级别拆分消息?,java,logging,log4j2,Java,Logging,Log4j2,我想将所有日志记录器级别记录到一个文件(致命->全部),同时在控制台中显示错误级别和更高级别。我使用根记录器将所有级别记录到一个文件中,使用单独的记录器将错误级别记录到控制台中。我的XML配置文件如下所示: <?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN"> <Appenders> <Console name="Console" target="

我想将所有日志记录器级别记录到一个文件(致命->全部),同时在控制台中显示错误级别和更高级别。我使用根记录器将所有级别记录到一个文件中,使用单独的记录器将错误级别记录到控制台中。我的XML配置文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout
                    pattern="%d{HH:mm:ss.SSS} [%t] %highlight{%level}{FATAL=bg_red, ERROR=red, WARN=yellow, INFO=blue} %logger{36} - %msg%n" disableAnsi="false"/>
        </Console>

        <File name="File" fileName="output.log" bufferedIO="true" >
            <PatternLayout
                    pattern="%d{HH:mm:ss.SSS} [%t] %highlight{%level}{FATAL=bg_red, ERROR=red, WARN=yellow, INFO=blue} %logger{36} - %msg%n"/>
        </File>
    </Appenders>

    <Loggers>
        <Root level="ALL">
            <AppenderRef ref="File"/>
        </Root>

        <Logger name="com.danielk" level="ERROR">
            <AppenderRef ref="Console"/>
        </Logger>

    </Loggers>
</Configuration>

我希望在文件中有所有级别的日志记录,在控制台中只有“Error”和更高级别的日志记录,但在这两个级别(控制台和文件)上我只有“Error”级别:

23:19:54.422[main]ERROR com.danielk.Example-示例中的错误 23:19:54.434[main]错误com.danielk.main-来自main的错误

消息本身是正确构建的,因为当我将两个记录器(Root和additional)都设置为“ALL”级别时,我可以看到所有类型的消息(不仅仅是“Error”级别)

我应该如何拆分级别:

  • 文件-所有级别
  • 控制台-仅限错误及以上

  • 您可以在console appender上使用
    ThresholdFilter
    ,筛选出具有
    错误
    或更特定级别()的日志事件

    整个配置,例如:

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="WARN">
        <Appenders>
            <Console name="Console" target="SYSTEM_OUT">
                <PatternLayout
                        pattern="%d{HH:mm:ss.SSS} [%t] %highlight{%level}{FATAL=bg_red, ERROR=red, WARN=yellow, INFO=blue} %logger{36} - %msg%n"
                        disableAnsi="false"/>
                <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
            </Console>
            <File name="File" fileName="output.log" bufferedIO="true" append="false">
                <PatternLayout
                        pattern="%d{HH:mm:ss.SSS} [%t] %highlight{%level}{FATAL=bg_red, ERROR=red, WARN=yellow, INFO=blue} %logger{36} - %msg%n"/>
            </File>
        </Appenders>
        <Loggers>
            <Root level="debug">
                <AppenderRef ref="File"/>
                <AppenderRef ref="Console"/>
            </Root>
        </Loggers>
    </Configuration>
    
    
    
    当您指定:

    <Logger name="com.danielk" level="ERROR">
       <AppenderRef ref="Console"/>
    </Logger>
    
    
    

    然后,对于
    com.danielk
    中的所有子包和类,将日志级别设置为
    ERROR
    (除非您使用不同级别配置更具体的记录器,例如
    com.danielk.db.MyClass
    )。这就是为什么日志文件中只出现错误

    回答得很好,但我认为值得注意的是,记录器名称不需要与包名和类名匹配——这只是预期的最佳实践。因此,对于名为“com.danielk”的记录器和该记录器的所有后代记录器,该级别实际上设置为错误。来自@Łukasz感谢您的回答。总之,只有当您希望单独处理项目的不同结构(例如模块、类等)时,才有必要创建其他记录器(而不是通用根记录器)但不是针对相同的结构-因此,应通过适当的appender配置来完成指向不同appender的不同登录级别…@D.B.感谢您的评论,您能更具体地说明您的意思吗?正如我所检查的,每个记录器都应该有一个名称(没有name属性,我有comple-time错误),但不一定是包名或类名-这就是你的意思吗?@Daniel我只是想指出,记录器名称在大多数情况下都应该与完全限定的java类名匹配,因为这是最佳实践,但没有严格的要求保证这一点永远正确。Lukasz编写了“com.danielk中的所有子包和类的日志级别都设置为错误”,它有一个内置的假设,即您遵循最佳实践,并根据java包和类名命名记录器。您可能正在这样做,但我想区分logger和类名,以帮助您理解log4j2。