Java Spring Boot 编程日志配置
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20507341/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring Boot programmatic logging configuration
提问by Axel Fontaine
How can I configure logging programmaticallyin a spring boot application?
如何在 Spring Boot 应用程序中以编程方式配置日志记录?
Using an xml or properties file is not flexible enough for my needs.
使用 xml 或属性文件不足以满足我的需要。
Update:I want to achieve something like this:
更新:我想实现这样的目标:
@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());
}
All I have per environment is:
我每个环境所拥有的只是:
- logging.level.root=[INFO, DEBUG, ..]
- logging.level.myApp=[INFO, DEBUG, ..]
- logging.file=[true | false]
- logging.level.root=[信息,调试,..]
- logging.level.myApp=[信息,调试,..]
- logging.file=[真| 错误的]
No duplication of XML, Groovy and other formats I really don't want to deal with.
没有重复的 XML、Groovy 和其他我真的不想处理的格式。
At the end of the day, this is really about achieving the same flexibility for logging as Spring JavaConfig did for beans. XML or other file formats are simply too static, require too much duplication and not integrated well enough with the rest of the configuration of the application.
归根结底,这实际上是为了实现与 Spring JavaConfig 为 bean 所做的相同的日志记录灵活性。XML 或其他文件格式太静态,需要太多重复,并且与应用程序的其余配置集成得不够好。
Why should logging be configured differently than any other bean or service?It makes no sense.
为什么日志记录的配置应该与任何其他 bean 或服务不同?这没有道理。
采纳答案by Dave Syer
I'm not sure you want or need to disable the default XML configuration of the logging system, but you do want to execute your customization calls afterthat was done. Fortunately that's pretty easy as it's done as early as possible in the initializer chain for a SpringApplication
. The easiest place to put your code is probably a SpringApplicationInitializer
(it has to implement ApplicationContextInitializer
as well so it can be added to the SpringApplication
). E.g.
我不确定您是否想要或需要禁用日志系统的默认 XML 配置,但您确实希望在完成后执行自定义调用。幸运的是,这很容易,因为它尽可能早地在SpringApplication
. 最容易放置代码的地方可能是 a SpringApplicationInitializer
(它也必须实现ApplicationContextInitializer
,以便可以添加到SpringApplication
)。例如
SpringApplication application = new SpringApplication(MySources.class);
application.addInitializers(new LoggingInitializer());
application.run(args);
You won't be able to do dependency injection into the initializer if you do it that way, but it will ensure that it gets called as early as possible in the lifecycle. If your initializer implements EnvironmentAware
then you will also be passed an instance of Environment
before the call to SpringApplicationInitializer.initialize()
- using that you can resolve the environment dependent pieces in your sample, e.g.
如果这样做,您将无法对初始化程序进行依赖注入,但它会确保在生命周期中尽早调用它。如果您的初始值设定项实现,EnvironmentAware
那么您还将Environment
在调用之前传递一个实例SpringApplicationInitializer.initialize()
- 使用它您可以解析示例中的环境相关部分,例如
String loggingLevelRoot = environment.getProperty("logging.level.root");
Once you have it working, to avoid having to do the same thing for all apps you can make it declarative by adding a META-INF/spring.factories
containing your initializer class:
一旦你让它工作,为了避免对所有应用程序做同样的事情,你可以通过添加一个META-INF/spring.factories
包含你的初始化器类来使其声明性:
org.springframework.context.ApplicationContextInitializer=\
my.pkg.for.LoggingInitializer
If you really need dependency injection and @Value
resolution I think you are going to have to accept that the ApplicationContext
will have fully refreshed before you get a chance to configure anything. If that's an acceptable compromise I recommend just adding a LoggingInitializer
to your context and have it implement CommandLineRunner
.
如果你真的需要依赖注入和@Value
解析,我认为你将不得不接受ApplicationContext
在你有机会配置任何东西之前已经完全刷新。如果这是一个可以接受的妥协,我建议只LoggingInitializer
在您的上下文中添加 a并让它实现CommandLineRunner
.