46

是否可以使用 XML 配置中的规范以编程方式添加 Log4J2 附加程序?

我计划在 log4j2.xml 中定义它,然后像这样根据情况选择附加程序(不会编译):

if (arg[0].equals("log") ) {
    Logger.getLogger("loggerNameFromXMLConfig").addAppender("appenderNameFromXMLConfig");
} else {
    //...
}
4

5 回答 5

37

有许多请求支持更好的 Log4j 2 编程配置。抱歉,花了这么长时间。从 Log4j 2.4 开始,API 被添加到 log4j-core 以方便编程配置

新的ConfigurationBuilderAPI 允许用户构建组件定义。使用此 API,无需直接使用实际配置对象(如 LoggerConfig 和 FileAppender),这需要大量了解 Log4j 如何在后台工作的知识。组件定义被添加到 ConfigurationBuilder 中,一旦收集了所有定义,所有实际的配置对象(如 Loggers 和 Appenders)就会被构建。感觉有点像 XML 配置语法,只是您正在编写 Java 代码。

请注意,新ConfigurationBuilderAPI 允许用户代码创建新配置或完全替换现有配置。如果您的用例不同,并且您想在 Log4j 启​​动后以编程方式修改(而不是替换)现有配置,那么您将需要使用实际的配置对象。在这种情况下,请参阅手册的“初始化后以编程方式修改当前配置”部分。

于 2015-11-02T07:49:59.873 回答
28

编辑:有关最新版本的 log4j2,请参阅https://stackoverflow.com/a/33472893/1899566

我的印象是他们不希望你这样做,但这对我有用:

if (arg[0].equals("log") ) {
  org.apache.logging.log4j.Logger logger
    = org.apache.logging.log4j.LogManager.getLogger("loggerNameFromXMLConfig");
  org.apache.logging.log4j.core.Logger coreLogger
    = (org.apache.logging.log4j.core.Logger)logger;
  org.apache.logging.log4j.core.LoggerContext context
    = (org.apache.logging.log4j.core.LoggerContext)coreLogger.getContext();
  org.apache.logging.log4j.core.config.BaseConfiguration configuration
    = (org.apache.logging.log4j.core.config.BaseConfiguration)context.getConfiguration();

  coreLogger.addAppender(configuration.getAppender("appenderNameFromXMLConfig"));
} else {
  //...
}
于 2013-07-24T18:36:41.363 回答
15

正如我上面提到的,我无法让https://logging.apache.org/log4j/2.x/manual/customconfig.html#AddingToCurrent工作,至少不是我期望的那样(我的附加程序会永远不会收到路由到它的消息)。我终于偶然发现了一种对我有用的模式——允许我在运行时添加一个 appender,并让该 appender 实际上将日志消息路由到它。

编辑我从这里删除了一堆没有做任何事情的令人困惑的代码......

    LoggerContext lc = (LoggerContext) LogManager.getContext(false);
    FileAppender fa = FileAppender.newBuilder().withName("mylogger").withAppend(false).withFileName(new File(outputDirectory, "ConsoleOutput.txt").toString())
            .withLayout(PatternLayout.newBuilder().withPattern("%-5p %d  [%t] %C{2} (%F:%L) - %m%n").build())
            .setConfiguration(lc.getConfiguration()).build();
    fa.start();
    lc.getConfiguration().addAppender(fa);
    lc.getRootLogger().addAppender(lc.getConfiguration().getAppender(fa.getName()));
    lc.updateLoggers();

对我来说,一个关键点是调用 addAppender 并直接传递你的 appender 是行不通的,但按名称要求你的 appender 似乎是可行的。这没有意义……但是自从工作以来,我厌倦了在应该如此简单的事情上浪费时间……

于 2018-04-04T23:14:34.687 回答
2

不知道有没有用:可以通过调用当前Configuration的addLoggerAppender方法来添加一个Appender到Logger中。参考: http: //logging.apache.org/log4j/2.x/manual/architecture.html

于 2015-10-19T05:51:19.193 回答
2

在 Log4j2 结构中

        ---"Config"---
                Appenders
                        Appender(0)
                            Console
                        Appender(1)
                            File
                    LoggerConfigs
                        -- LoggerConfig(0) 
                        -- LoggerConfig(1)
                        -- LoggerConfig(2)

        ----"LoggerConfig"----
                - AppenderRefs
                    -- AppenderRef(0)
                        -- Name Console
                        -- Level : DEBUG
                - Appenders
                    -- Appender(0)
                        -- Name Console
                        -- Level : DEBUG
                - Level -- ALL

loggerConfig.getAppenders() --> 将返回“Config”中的 Appenders。对我来说这是一个BUG

loggerConfig.getAppenderRefs() --> 运行良好!!

于 2018-04-10T08:32:36.850 回答