Log4j2-为什么不注册自定义级别

时间:2018-07-20 03:07:07

标签: java log4j2

我正在学习log4j2。我尝试编写一个在xml配置文件中定义的自定义级别过滤器的示例。

由于某些原因,它们似乎未被识别。

log4j2 xml配置文件

log4j2_config_20_Filters_LevelFilter_Custom.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
    <CustomLevels>
        <CustomLevel name="level350" intLevel="350"/>
        <CustomLevel name="level450" intLevel="450"/>
        <CustomLevel name="level550" intLevel="550"/>
    </CustomLevels>
    <Appenders>
        <Console name="appender1" target="SYSTEM_OUT">
            <PatternLayout charset="UTF-8" pattern="[%date]('%logger'-'%level') %msg\n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Logger name="logger1_level350" level="level350" additivity="false">
            <AppenderRef ref="appender1"/>
        </Logger>
        <Logger name="logger1_level450" level="level450" additivity="false">
            <AppenderRef ref="appender1"/>
        </Logger>
        <Logger name="logger1_level550" level="level550" additivity="false">
            <AppenderRef ref="appender1"/>
        </Logger>
    </Loggers>
</Configuration>

一种用于打印已识别级别的实用程序方法。

    public static List<String> getLog4j2LevelsDescriptionsList() {
        final List<Level> sortedLevels = Arrays.stream(Level.values()).sorted(Comparator.comparingInt(Level::intLevel)).collect(Collectors.toList());
        final List<String> levelsDescriptionList = new ArrayList<>();

        int maxNameLength = 5;
        for (Level sortedLevel : sortedLevels) {
            final int currentLength = sortedLevel.name().length();
            if (currentLength > maxNameLength) maxNameLength = currentLength;
        }

        for (Level level : sortedLevels) {
            levelsDescriptionList.add(String.format("%-" + maxNameLength + "S : %d", level.name(), level.intLevel()));
        }
        return levelsDescriptionList;
    }

测试

    @Test
    public void test_CustomLevels_DeclaredIn_ConfigFile() {
        setLog4j2ConfigFile("log4j2_config_20_Filters_LevelFilter_Custom.xml");
        final Level level350 = Level.getLevel("level350");
//        Level.forName("level350", 350);
//        Level.forName("level450", 450);
//        Level.forName("level550", 550);

        for (String s : getLog4j2LevelsDescriptionsList()) {
            System.out.println(s);
        }
        System.out.println();

        final Logger loggers[] = {
                LogManager.getLogger("logger1_level350"),
                LogManager.getLogger("logger1_level450"),
                LogManager.getLogger("logger1_level550")
        };

        for (Logger logger : loggers) {
            logger.fatal("This is a fatal message");
            logger.error("This is an error message");
            logger.warn("This is a warning message");
            logger.info("This is an info message");
            logger.debug("This is a debug message");
            logger.trace("This is a trace message");
            System.out.println();
        }
    }

输出

OFF   : 0
FATAL : 100
ERROR : 200
WARN  : 300
INFO  : 400
DEBUG : 500
TRACE : 600
ALL   : 2147483647

[2018-07-20 06:04:20,819]('logger1_level350'-'FATAL') This is a fatal message
[2018-07-20 06:04:20,821]('logger1_level350'-'ERROR') This is an error message

[2018-07-20 06:04:20,821]('logger1_level450'-'FATAL') This is a fatal message
[2018-07-20 06:04:20,821]('logger1_level450'-'ERROR') This is an error message

[2018-07-20 06:04:20,821]('logger1_level550'-'FATAL') This is a fatal message
[2018-07-20 06:04:20,821]('logger1_level550'-'ERROR') This is an error message

为什么不能识别自定义级别? 我希望可以识别自定义级别。并根据其intLevel将记录的事件“追加”。

1 个答案:

答案 0 :(得分:0)

log4j2_config_20_2_Filters_LevelFilter_Custom_OverridingCustomLevels.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
    <CustomLevels>
        <CustomLevel name="ALL_CAPS_CONFIG_FILE_ONLY_LOGGER_LEVEL_310" intLevel="310"/>
    </CustomLevels>
    <CustomLevels>
        <CustomLevel name="all_small_config_file_only_logger_level_320" intLevel="320"/>
    </CustomLevels>
    <CustomLevels>
        <CustomLevel name="ALL_CAPS_CONFIG_FILE_ONLY_APPENDER_REF_LEVEL_350" intLevel="350"/>
    </CustomLevels>
    <CustomLevels>
        <CustomLevel name="all_small_config_file_only_appender_ref_level_360" intLevel="360"/>
    </CustomLevels>
    <CustomLevels>
        <CustomLevel name="ALL_CAPS_CONFIG_FILE_ONLY_NOT_USED_LEVEL_370" intLevel="370"/>
    </CustomLevels>
    <Appenders>
        <Console name="appender1" target="SYSTEM_OUT">
            <PatternLayout charset="UTF-8" pattern="[%date]('%logger'-'%level') %msg\n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Logger name="logger1" level="ALL_CAPS_CONFIG_FILE_ONLY_LOGGER_LEVEL_310" additivity="false">
            <AppenderRef ref="appender1"/>
        </Logger>
        <Logger name="logger2" level="all_small_config_file_only_logger_level_320" additivity="false">
            <AppenderRef ref="appender1"/>
        </Logger>
        <Logger name="logger3" level="ALL_SMALL_CONFIG_FILE_ONLY_LOGGER_LEVEL_320" additivity="false">
            <AppenderRef ref="appender1"/>
        </Logger>
        <Logger name="logger4" additivity="false">
            <AppenderRef ref="appender1" level="ALL_CAPS_CONFIG_FILE_ONLY_APPENDER_REF_LEVEL_350"/>
        </Logger>
        <Logger name="logger5" additivity="false">
            <AppenderRef ref="appender1" level="all_small_config_file_only_appender_ref_level_360"/>
        </Logger>
        <Logger name="logger6" additivity="false">
            <AppenderRef ref="appender1" level="ALL_SMALL_CONFIG_FILE_ONLY_APPENDER_REF_LEVEL_320"/>
        </Logger>
        <Logger name="logger7" level="ALL_CAPS_JAVA_ONLY_LEVEL_330" additivity="false">
            <AppenderRef ref="appender1"/>
        </Logger>
        <Logger name="logger8" level="all_small_java_only_level_340" additivity="false">
            <AppenderRef ref="appender1"/>
        </Logger>
        <Logger name="logger9" level="ALL_SMALL_JAVA_ONLY_LEVEL_340" additivity="false">
            <AppenderRef ref="appender1"/>
        </Logger>
    </Loggers>
</Configuration>

JUnit test

    /*
     * If you register a level in the config file, make sure to call at least one logger before attempting to obtain the level's instance.
     * Make sure that the level's name is in capital letters only.
     * */
    @Test
    public void test_CustomLevels_RegisteringCustomLevelsInConfigFileAndJava_Testing() {
        setLog4j2ConfigFile("log4j2_config_20_1_Filters_LevelFilter_Custom_RegisteringCustomLevels_test.xml");
        Level.forName("ALL_CAPS_JAVA_ONLY_LEVEL_330", 330);
        Level.forName("all_small_java_only_level_340", 340);

        printLevels("Before calling loggers");
        LogManager.getLogger("logger1"); /*LogManager.getRootLogger();*//*Same effect*/
        printLevels("After calling logger1 only");
        System.out.println("Level.getLevel(\"ALL_CAPS_CONFIG_FILE_ONLY_NOT_USED_LEVEL_370\") = " + Level.getLevel("ALL_CAPS_CONFIG_FILE_ONLY_NOT_USED_LEVEL_370"));
        final Logger[] loggers = {
                LogManager.getLogger("logger1"),
                LogManager.getLogger("logger2"),
                LogManager.getLogger("logger3"),
                LogManager.getLogger("logger4"),
                LogManager.getLogger("logger5"),
                LogManager.getLogger("logger6"),
                LogManager.getLogger("logger7"),
                LogManager.getLogger("logger8"),
                LogManager.getLogger("logger9")
        };
        printLoggersAndTheirLevels(loggers);
        printLevels("After calling loggers");
    }

我没有得到官方支持的答案。但是根据以前的测试,必须满足两个条件,才能使用在配置文件中定义/声明的级别。

  1. 该级别的名称必须为 ALL CAPITAL (大写),才能在配置文件中使用。 (这也适用于配置文件中使用的Java定义的级别)
  2. 必须调用至少一个记录器(使用LogManager.getLogger("logger_name")LogManager.getRootLevel()),才能在Java代码中注册和使用所有级别。记录器必须在尝试使用任何config-file-defined-level-filters
  3. 之前调用

输出

Before calling loggers
OFF                           : 0
FATAL                         : 100
ERROR                         : 200
WARN                          : 300
ALL_CAPS_JAVA_ONLY_LEVEL_330  : 330
ALL_SMALL_JAVA_ONLY_LEVEL_340 : 340
INFO                          : 400
DEBUG                         : 500
TRACE                         : 600
ALL                           : 2147483647

After calling logger1 only
OFF                                               : 0
FATAL                                             : 100
ERROR                                             : 200
WARN                                              : 300
ALL_CAPS_CONFIG_FILE_ONLY_LOGGER_LEVEL_310        : 310
ALL_SMALL_CONFIG_FILE_ONLY_LOGGER_LEVEL_320       : 320
ALL_CAPS_JAVA_ONLY_LEVEL_330                      : 330
ALL_SMALL_JAVA_ONLY_LEVEL_340                     : 340
ALL_CAPS_CONFIG_FILE_ONLY_APPENDER_REF_LEVEL_350  : 350
ALL_SMALL_CONFIG_FILE_ONLY_APPENDER_REF_LEVEL_360 : 360
ALL_CAPS_CONFIG_FILE_ONLY_NOT_USED_LEVEL_370      : 370
INFO                                              : 400
DEBUG                                             : 500
TRACE                                             : 600
ALL                                               : 2147483647

Level.getLevel("ALL_CAPS_CONFIG_FILE_ONLY_NOT_USED_LEVEL_370") = ALL_CAPS_CONFIG_FILE_ONLY_NOT_USED_LEVEL_370

[Logger]"logger1": Level=("ALL_CAPS_CONFIG_FILE_ONLY_LOGGER_LEVEL_310" - 310)
[Logger]"logger2": Level=("ERROR" - 200)
[Logger]"logger3": Level=("ERROR" - 200)
[Logger]"logger4": Level=("ERROR" - 200)
[Logger]"logger5": Level=("ERROR" - 200)
[Logger]"logger6": Level=("ERROR" - 200)
[Logger]"logger7": Level=("ALL_CAPS_JAVA_ONLY_LEVEL_330" - 330)
[Logger]"logger8": Level=("ERROR" - 200)
[Logger]"logger9": Level=("ERROR" - 200)

After calling loggers
OFF                                               : 0
FATAL                                             : 100
ERROR                                             : 200
WARN                                              : 300
ALL_CAPS_CONFIG_FILE_ONLY_LOGGER_LEVEL_310        : 310
ALL_SMALL_CONFIG_FILE_ONLY_LOGGER_LEVEL_320       : 320
ALL_CAPS_JAVA_ONLY_LEVEL_330                      : 330
ALL_SMALL_JAVA_ONLY_LEVEL_340                     : 340
ALL_CAPS_CONFIG_FILE_ONLY_APPENDER_REF_LEVEL_350  : 350
ALL_SMALL_CONFIG_FILE_ONLY_APPENDER_REF_LEVEL_360 : 360
ALL_CAPS_CONFIG_FILE_ONLY_NOT_USED_LEVEL_370      : 370
INFO                                              : 400
DEBUG                                             : 500
TRACE                                             : 600
ALL                                               : 2147483647