在开发和测试环境下,ROOT记录器级别为DEBUG或INFO。应用程序启动时会显示spring-boot标题:
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
但是在生产环境中运行时,我的ROOT记录器级别通常是WARN。这会导致横幅打印不出来。
如何配置回溯以便横幅广告也会在制作中显示?
我的猜测是添加另一个记录器,但以下(和相似的配置)不起作用:
<logger name="org.springframework.web" level="INFO" additivity="false">
<appender-ref ref="FILE"/>
</logger>
这是我的配置
application.properties:
spring.main.banner-mode=log
application-devel.properties:
logging.config=classpath:logging-spring-devel.xml
application-production.properties:
logging.config=classpath:logging-spring-production.xml
logging-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>
logging-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>
答案 0 :(得分:6)
在打印横幅时,Spring Boot使用org.springframework.boot.SpringApplication
等级为INFO
的记录器。
简单的解决方案是为此特定类启用INFO
级别:
<logger name="org.springframework.boot.SpringApplication"
level="INFO" additivity="false">
<appender-ref ref="FILE"/>
</logger>
答案 1 :(得分:1)
我遇到了同样的问题,只是在application.properties
中设置了此属性:
spring.main.banner-mode=LOG
现在,它以日志级别INFO打印到控制台和文件。只要您已将根日志级别和附加程序设置为接受INFO,就可以看到它。
<root level="info">
<appender-ref ref="RollingFile" />
<appender-ref ref="Console" />
</root>
答案 2 :(得分:0)
这就是我想出的。它包含了在常规实现中更换记录器的想法。
使用默认日志实现的问题是通过slf4j bridge调整commons-logging的方式。
这可能是最活跃的代码之一,所以希望我们会在即将发布的spring-boot发行版中看到修复...
步骤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;
}
}
答案 3 :(得分:0)
首先,我必须承认我没有对此进行测试,但至少它可能会给你一些想法。
您可以删除var results = Regex.Matches(s, @"(?<!{){{{([^{}]*)}}}(?!})")
.Cast<Match>()
.Select(m => m.Groups[1].Value)
.ToList();
并提供自己的包装器实现,该实现将使用记录器而不是提供的输出流。代码看起来像这样:
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.info
,或者您可以为此记录器创建特定的其他配置:
logger.warn
根据documentation,您可以使用<logger name="your.package.name.BannerLoggerWrapper" level="INFO" additivity="false">
<appender-ref ref="FILE"/>
</logger>
配置Spring Boot以使用Banner实施。