2013-12-10 89 views
12

如何在彈簧引導應用程序中以編程方式配置日誌Spring Boot編程式日誌配置

使用xml或properties文件不夠靈活,無法滿足我的需求。

更新:我要實現的是這樣的:

@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或服務不同?它沒有任何意義。

+0

使用xml不夠靈活嗎?如果您使用Logback,則可以使用Groovy配置logback。 –

+1

@ M.Deinum不,你不能; Spring Boot(實際上,我認爲Spring Autoconfig)踩在Groovy配置上。 – chrylis

+0

我還需要爲每個環境配置不同的配置,使用不同的appender類型......所以不,XML不會削減它。 –

回答

13

我不確定您是否想要或需要禁用日誌記錄系統的默認XML配置,但您確實想在執行完之後執行您的定製調用。幸運的是,這很容易,因爲它在SpringApplication的初始化鏈中儘可能早地完成。放置代碼最簡單的地方可能是SpringApplicationInitializer(它必須實現ApplicationContextInitializer以及它可以被添加到SpringApplication)。例如。

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

你將不能夠做的依賴注入初始化,如果你這樣做,但它會確保它得到儘早在生命週期中調用。如果您的初始化程序實現了EnvironmentAware,那麼在調用SpringApplicationInitializer.initialize()之前,您還將通過Environment實例 - 使用該功能您可以解析樣本中與環境相關的部分,例如,

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

一旦你擁有了它的工作,以避免做同樣的事情,所有的應用程序,你可以通過添加一個META-INF/spring.factories包含您的初始化類,使其聲明:

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

如果你真的需要依賴注射和@Value決議我認爲你將不得不接受在你有機會配置任何東西之前ApplicationContext將完全刷新。如果這是一個可以接受的折中方案,我建議您只需在您的上下文中添加一個LoggingInitializer並讓它實現CommandLineRunner

+0

自定義的'LoggingSystem'實現也可以完成這項工作,不是嗎?但是它不會被自動檢測,因此您應該添加'-Dorg.springframework.boot.logging.LoggingSystem = '(或設置系統屬性)。 –

+0

@DaveSyer'EnvironmentAware'在這種情況下不起作用。如果您需要Environment實例,那麼最好從'initialize()'方法內的應用程序上下文實例中獲取它。 – ydrozhdzhal

+0

我發現這個解釋的替代策略非常有幫助。我確實需要參考這個問題的一個例子,如何做一些建議在這裏:https://stackoverflow.com/questions/46636599/how-do-i-set-the-logging-properties-in-一個彈簧-java的配置?noredirect = 1&LQ = 1 – user1445967