How to configure Logger Programmatically in log4j2.02?

后端 未结 3 402
北恋
北恋 2021-02-05 14:05

I want to use log4j without any configure file. What I wan to do is something as:

logger = (Logger) LogManager.getLogger(this.getClass());
Strin         


        
相关标签:
3条回答
  • 2021-02-05 14:44

    The official documentation shows an example : Programatically Adding to the Current Configuration

    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();
    

    With these limitations :

    1. If the configuration file is changed the configuration will be reloaded and the manual changes will be lost.
    2. Modification to the running configuration requires that all the methods being called (addAppender and addLogger) be synchronized.

    This solution avoids to use method from the core implementation org.apache.logging.log4j.core.Logger, and it avoids dirty cast like that :

    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 讨论(0)
  • 2021-02-05 14:47

    If I simply respond to your requirement, I can suggest three options. I use the first one for a kind of bootstrap Logger config; however I thought the second would be necessary at first. Your third choice seems cumbersome since you need to call different log4j API-s to get configured.

    Using Log4j over the simple logging framework for Java ...

    1. Make a 'minimal' or 'default' log4j.properties file in your resources for the JAR file. Then declare some statics...

      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. Write your config to a StreamWriter instead of placing a file in your JAR, and then give the Stream to the log configurator as a StringReader and use the example above (more or less).

    3. You can use the slf4j API to do your log config, rather than write direct to Log4j. Most places I've been prefer the SLF4J route.

    Personally, I prefer option #1; it is easy to maintain. simple and you can always re-order the code to accept/look for a file to load first. There are some other lateral avenues you can consider, such as setting environment variables programmatically at start-up. That seems contrived to me.

    The way I use #1 is to establish a default / bootstrap logger configuration via the resources file, which itself gets wrapped into the JAR file. You can reconfigure things 'later' while this option gives you a minimalist star-up or bootstrap config. In the early stages I found things weren't (yet) being logged because the logger initialisation was yet to happen on embedded apps. So I kept the simple option for bootstrap (or default) as a basic ever since. Hope this helps.

    0 讨论(0)
  • 2021-02-05 14:52

    With the latest version of log4j2, all create the APIs like

    PatternLayout.createLayout, 
    FileAppender.createAppender, 
    LoggerConfig.createLogger 
    

    have become deprecated, it's better to use a custom log ConfigurationFactory along with ConfigurationBuilder for defining the log configuration programmatically.

    0 讨论(0)
提交回复
热议问题