2017-03-23 32 views
7

在開發和測試環境下,ROOT記錄器級別爲DEBUG或INFO。彈簧啓動橫幅顯示在應用程序啓動:顯示帶Root Logger的Spring-Boot Banner WARN

2017-03-23 14:31:00,322 [INFO ]     - 
:: Spring Boot ::   (v1.5.2.RELEASE) 
:: Application ::   AcMe (v1.0-SNAPSHOT) 
:: Build ::    2017-03-23 09:53 

但在生產環境中運行時,我的根記錄水平通常是WARN。這導致橫幅不被打印出來。

如何配置logback,以便在生產中顯示橫幅?

我的猜測是,添加另一個記錄儀,但以下(和相似配置)沒有工作:

<logger name="org.springframework.web" level="INFO" additivity="false"> 
    <appender-ref ref="FILE"/> 
</logger> 

這裏我的配置

application.properties:

spring.main.banner-mode=log 

應用-devel.properties:

logging.config=classpath:logging-spring-devel.xml 

application-production.properties:

測井devel.xml(橫幅顯示)

 LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}application.log}"/> 
     <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> 
      <file>${LOG_FILE}</file> 
      ... 
     </appender> 
     <root level="INFO"> 
      <appender-ref ref="FILE"/> 
     </root> 
    </configuration> 

測井production.xml(不顯示橫幅)

 LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}application.log}"/> 
     <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> 
      <file>${LOG_FILE}</file> 
      ... 
     </appender> 
     <root level="WARN"> 
      <appender-ref ref="FILE"/> 
     </root> 
    </configuration> 

回答

4

在打印過程中,Spring Boot使用類org.springframework.boot.SpringApplicationINFO級別的記錄器。

的simples的解決辦法是讓這個特殊類INFO級別:

<logger name="org.springframework.boot.SpringApplication" 
     level="INFO" additivity="false"> 
    <appender-ref ref="FILE"/> 
</logger> 
+0

更改日誌記錄級別爲一類是去照你說的最好的方式。 Spring Boot的另一種方法是通過Environment屬性,我將其作爲JVM參數傳入, -Dlogging.level.org.springframework.boot.SpringApplication = INFO – PaulNUK

+0

工作:)非常感謝。 – Hannes

0

這是,我想出了什麼。它包含了在常規實施中更換記錄器的想法。

使用默認日誌實現的問題是通過slf4j橋改編commons-logging的方式。

這可能是最醜陋的代碼活着之一,所以希望我們將看到在即將到來的春季啓動版本修復...

第1步:註冊一個新的應用程序監聽

/META-INF /spring.factory

org.springframework.context.ApplicationListener=ac.me.appevents.BannerDisplay 

步驟2:實現應用程序監聽

package ac.me.appevents; 

import org.jetbrains.annotations.NotNull; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.slf4j.Marker; 
import org.slf4j.MarkerFactory; 
import org.springframework.boot.ResourceBanner; 
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; 
import org.springframework.context.ApplicationListener; 
import org.springframework.core.env.Environment; 
import org.springframework.core.io.DefaultResourceLoader; 
import org.springframework.core.io.Resource; 
import org.springframework.core.io.ResourceLoader; 
import org.springframework.util.ClassUtils; 

import java.io.ByteArrayOutputStream; 
import java.io.PrintStream; 
import java.io.UnsupportedEncodingException; 

public class BannerDisplay implements ApplicationListener<ApplicationEnvironmentPreparedEvent> { 
    /** 
    * Banner location property key. 
    */ 
    private static final String BANNER_LOCATION_PROPERTY = "banner.location"; 

    /** 
    * Default banner location. 
    */ 
    private static final String BANNER_LOCATION_PROPERTY_VALUE = "banner.txt"; 

    private static final Logger LOG = LoggerFactory.getLogger(BannerDisplay.class); 

    private static final Marker MRK = MarkerFactory.getMarker("Banner"); 

    private ResourceLoader resourceLoader; 

    private Class<?> deduceMainApplicationClass() { 
     try { 
      StackTraceElement[] stackTrace = new RuntimeException().getStackTrace(); 
      for (StackTraceElement stackTraceElement : stackTrace) { 
       if ("main".equals(stackTraceElement.getMethodName())) { 
        return Class.forName(stackTraceElement.getClassName()); 
       } 
      } 
     } 
     catch (ClassNotFoundException ex) { 
      // Swallow and continue 
     } 
     return null; 
    } 

    @Override 
    public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) { 
     Environment environment = event.getEnvironment(); 

     String location = environment.getProperty(BANNER_LOCATION_PROPERTY, BANNER_LOCATION_PROPERTY_VALUE); 
     ResourceLoader resLoader = getResourceLoader(); 
     Resource resource = resLoader.getResource(location); 
     if (resource.exists()) { 
      ResourceBanner banner = new ResourceBanner(resource); 
      ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
      banner.printBanner(environment, deduceMainApplicationClass(), new PrintStream(baos)); 
      String charset = environment.getProperty("banner.charset", "UTF-8"); 
      try { 

       LOG.info(MRK, baos.toString(charset)); 
      } 
      catch (UnsupportedEncodingException e) { 
       LOG.warn(MRK, "Unsupported banner charset encoding.", e); 
      } 

     } 
    } 

    @NotNull 
    private ResourceLoader getResourceLoader() { 
     if (resourceLoader == null) { 
      this.resourceLoader = new DefaultResourceLoader(ClassUtils.getDefaultClassLoader()); 
     } 
     return resourceLoader; 
    } 

    public void setResourceLoader(final ResourceLoader resourceLoader) { 
     this.resourceLoader = resourceLoader; 
    } 
} 
0

首先,我必須承認,我沒有測試過這個,但至少它可能會給你一些想法。

您可以刪除spring.main.banner-mode=log並提供您自己的包裝器實現,它將使用記錄器而不是提供的輸出流。代碼應該是這個樣子:

public class BannerLoggerWrapper implements Banner { 

    private static final Log logger = LogFactory.getLog(BannerLoggerWrapper.class); 
    private Banner actual; 

    public BannerLoggerWrapper(Banner actual) { 
     this.actual = actual; 
    } 

    @Override 
    public void printBanner(Environment environment, Class<?> sourceClass, PrintStream out) { 
     try { 
      logger.info(createStringFromBanner(environment, sourceClass)); 
     } catch (UnsupportedEncodingException ex) { 
      logger.warn("Failed to create String for banner", ex); 
     } 
    } 

    private String createStringFromBanner(Environment environment, Class<?> sourceClass) throws UnsupportedEncodingException { 
     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     actual.printBanner(environment, sourceClass, new PrintStream(baos)); 
     String charset = environment.getProperty("banner.charset", "UTF-8"); 
     return baos.toString(charset); 
    } 

} 

你可以在這個類logger.warn取代logger.info也可以此logger specificaly創建額外的配置:

<logger name="your.package.name.BannerLoggerWrapper" level="INFO" additivity="false"> 
    <appender-ref ref="FILE"/> 
</logger> 

根據documentation你可以配置Spring引導到使用SpringApplication.setBanner(…​)使用Banner實現。