弹簧引导编程日志记录配置

2022-09-04 02:12:59

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

使用 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 | false]

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

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

为什么日志记录的配置应与任何其他 Bean 或服务不同?这是没有道理的。


答案 1

我不确定您是否希望或需要禁用日志记录系统的默认 XML 配置,但您确实希望在完成后执行自定义调用。幸运的是,这很容易,因为它是在 初始值设定项链中尽早完成的。放置代码的最简单位置可能是 a(它还必须实现,以便可以将其添加到 )。例如:SpringApplicationSpringApplicationInitializerApplicationContextInitializerSpringApplication

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

如果这样做,您将无法将依赖项注入到初始值设定项中,但它将确保在生命周期中尽早调用它。如果您的初始值设定项实现,那么您还将在调用之前传递一个实例 - 使用该实例,您可以解析示例中与环境相关的部分,例如EnvironmentAwareEnvironmentSpringApplicationInitializer.initialize()

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

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

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

如果你真的需要依赖注入和分辨率,我认为在你有机会配置任何东西之前,你将不得不接受已经完全刷新。如果这是一个可以接受的折衷方案,我建议只需将 a 添加到您的上下文中并让它实现。@ValueApplicationContextLoggingInitializerCommandLineRunner


答案 2

推荐