Spring Boot程序化日志记录配置

时间:2013-12-10 23:12:53

标签: java logging spring-boot

如何在Spring启动应用程序中配置以编程方式进行日志记录?

使用xml或属性文件不够灵活,无法满足我的需求。

更新:我希望实现以下目标:

@Value("${logging.level.root}")
private String loggingLevelRoot;

@Value("${logging.level.myApp}")
private String loggingLevelMyApp;

@Value("${logging.file}")
private boolean fileAppenderEnabled;

....

setLevel(Logger.ROOT_LOGGER_NAME, Level.toLevel(loggingLevelRoot)));
setLevel("com.myapp", Level.toLevel(loggingLevelMyApp)));
setLevel("org.springframework", Level.WARN);
setLevel("org.apache.coyote", Level.INFO);
setLevel("org.apache.catalina", Level.INFO);
setLevel("org.apache.catalina.startup.DigesterFactory", Level.ERROR);
setLevel("org.apache.catalina.util.LifecycleMBeanBase", Level.ERROR);

Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
logger.addAppender(createConsoleAppender());
if (fileAppenderEnabled) {
    logger.addAppender(createFileAppender());
}

我所拥有的每个环境都是:

  • logging.level.root = [INFO,DEBUG,..]
  • logging.level.myApp = [INFO,DEBUG,..]
  • logging.file = [true |假]

没有重复的XML,Groovy和其他我真正不想处理的格式。

在一天结束时,这实际上是为了实现与Spring JavaConfig对bean相同的日志记录灵活性。 XML或其他文件格式过于静态,需要过多的重复,并且与应用程序的其余配置集成得不够好。

为什么日志记录的配置应该与其他任何bean或服务不同?没有意义。

1 个答案:

答案 0 :(得分:16)

我不确定您是否需要或者需要禁用日志记录系统的默认XML配置,但您确实希望在之后执行自定义调用。幸运的是,这很容易,因为它在SpringApplication的初始化链中尽早完成。放置代码的最简单的地方可能是SpringApplicationInitializer(它必须实现ApplicationContextInitializer,因此可以将其添加到SpringApplication)。 E.g。

SpringApplication application = new SpringApplication(MySources.class);
application.addInitializers(new LoggingInitializer());
application.run(args);

如果以这种方式执行,您将无法对初始化程序执行依赖项注入,但它将确保在生命周期中尽早调用它。如果初始化程序实现了EnvironmentAware,那么在调用Environment之前,您还将传递SpringApplicationInitializer.initialize()的实例 - 使用它可以解析样本中依赖于环境的部分,例如

String loggingLevelRoot = environment.getProperty("logging.level.root");

一旦你有了它的工作,为了避免对所有应用程序做同样的事情你可以通过添加一个包含你的初始化类的META-INF/spring.factories来声明它:

org.springframework.context.ApplicationContextInitializer=\
my.pkg.for.LoggingInitializer

如果您确实需要依赖注入和@Value解析,我认为您必须接受ApplicationContext将在您有机会配置任何内容之前完全刷新。如果这是可接受的折衷方案,我建议您只在您的上下文中添加LoggingInitializer并让其实施CommandLineRunner