2014-10-31 51 views
10

我想使用log4j 而不是任何配置文件。 我婉做是值得的:如何在log4j2.02中以编程方式配置记录器?

logger = (Logger) LogManager.getLogger(this.getClass()); 
String pattern = "[%level] %m%n"; 
//do something to make this logger output to an local file "/xxx/yyy/zzz.log" 

我发现这个答案:Configuring Log4j Loggers Programmatically

Logger#addAppender的文档说: 这种方法是不通过公共API暴露并主要用于单元测试。

我不确定是否在我的代码中使用此方法的正确方法,或者有其他更好的解决方案来解决我的问题。

回答

19

The official documentation示出了一个例子:如果配置文件被改变的配置将被装载,并手动更改将

  1. 编程方式添加到当前配置

    final LoggerContext ctx = (LoggerContext) LogManager.getContext(false); 
    final Configuration config = ctx.getConfiguration(); 
    
    Layout layout = PatternLayout.createLayout(PatternLayout.SIMPLE_CONVERSION_PATTERN, config, null, null,null, null); 
    Appender appender = FileAppender.createAppender("target/test.log", "false", "false", "File", "true", "false", "false", "4000", layout, null, "false", null, config); 
    appender.start(); 
    config.addAppender(appender); 
    
    AppenderRef ref = AppenderRef.createAppenderRef("File", null, null); 
    AppenderRef[] refs = new AppenderRef[] {ref}; 
    LoggerConfig loggerConfig = LoggerConfig.createLogger("false", "info", "org.apache.logging.log4j", "true", refs, null, config, null); 
    loggerConfig.addAppender(appender, null, null); 
    config.addLogger("org.apache.logging.log4j", loggerConfig); 
    ctx.updateLoggers(); 
    

    有了这些限制迷路了。

  2. 对运行配置的修改要求所有被调用的方法(addAppender和addLogger)都要同步。

该解决方案避免使用这种方法从核心实现org.apache.logging.log4j.core.Logger,它可以避免脏投这样的:

import org.apache.logging.log4j.Logger; 

Logger logger = (Logger) LogManager.getLogger(this.getClass()); 
((org.apache.logging.log4j.core.Logger) logger).addAppender(...); // Bypassing the public API 
+0

如果您打算将记录器jar遮蔽以将其完全隐藏,请将其添加为第一行:LogManager.setFactory(new Log4jContextFactory());现在,您还可以使用遮阳过滤器省略所有配置和属性文件。 – bebbo 2017-12-20 14:44:31

0

如果我只是回应您的要求,我可以提出三种选择。我使用第一个引导记录器配置;不过,我认为第一个是必要的。你的第三个选择似乎很麻烦,因为你需要调用不同的log4j API-s来配置。

使用的Log4j在Java的简单日志框架...

  1. 做出“最小”或“默认” log4j.properties在你的资源的JAR文件的文件。然后声明一些静...

    private static final URL LOGGER_CONFIG_URL = resolveConfigUrl(); 
        : 
    
    private static URL resolveConfigUrl(){ 
    
        URL url = LogConfig.class.getResource(LOGGER_CONFIG_NAME); 
    
        if(null == url) // Second chance, try for a file. 
        { 
         url = FileHelp.resolveUrlNameAsUrlToFile(LOGGER_CONFIG_NAME); 
            //-- Make this function with: url = tmpFile.toURI().toURL() 
            // Plus appropriate try/catch and error checks. 
         } 
         return url; 
    } 
    
    private static void configureLogger(){ 
    
        BasicConfigurator.configure(); 
        PropertyConfigurator.configure(LOGGER_CONFIG_URL ); 
        LOG.info("Logging config done: " + LOGGER_CONFIG_NAME); 
    } 
    
  2. 写你的配置到一个StreamWriter,而不是将文件放在你的JAR,然后给流将日志配置为StringReader并用上面的例子(或更多减)。

  3. 您可以使用slf4j API来执行您的日志配置,而不是直接写入Log4j。大多数地方我一直喜欢SLF4J路线。

就个人而言,我更喜欢选项#1;很容易维护。简单,您可以随时重新排序代码以接受/查找要先加载的文件。还有其他一些可以考虑的侧向途径,例如在启动时以编程方式设置环境变量。这似乎是我设计的。

我使用#1的方式是通过资源文件建立默认/引导记录器配置,资源文件本身被包装到JAR文件中。你可以重新配置'以后的',而这个选项为你提供了一个简约的星型配置或引导配置。在早期阶段,我发现事情还没有被记录,因为记录器初始化还没有在嵌入式应用上发生。所以我把bootstrap(或默认)这个简单的选项作为一个基础。希望这可以帮助。

0

随着log4j2的最新版本中,所有创建像

PatternLayout.createLayout, 
FileAppender.createAppender, 
LoggerConfig.createLogger 
这些API

已被弃用,最好使用自定义日志ConfigurationFactory以及ConfigurationBuilder以编程方式定义日志配置。

相关问题