Add support for LOG_LEVEL_PATTERN replacing the default level pattern
For logback we also support logging.pattern.level as a synonym. Fixes gh-4062
This commit is contained in:
parent
eeaa1df1dd
commit
cad2666522
|
@ -63,6 +63,7 @@ content into your application; rather pick only the properties that you need.
|
|||
logging.path=/var/log
|
||||
logging.pattern.console= # appender pattern for output to the console (only supported with the default logback setup)
|
||||
logging.pattern.file= # appender pattern for output to the file (only supported with the default logback setup)
|
||||
logging.pattern.level= # appender pattern for the log level (default %5p, only supported with the default logback setup)
|
||||
|
||||
# IDENTITY ({sc-spring-boot}/context/ContextIdApplicationContextInitializer.{sc-ext}[ContextIdApplicationContextInitializer])
|
||||
spring.application.name=
|
||||
|
|
|
@ -1085,6 +1085,18 @@ To help with the customization some other properties are transferred from the Sp
|
|||
|`LOG_PATH`
|
||||
|Used in default log configuration if defined.
|
||||
|
||||
|`logging.pattern.console`
|
||||
|`CONSOLE_LOG_PATTERN`
|
||||
|The log pattern to use on the console (stdout). (Not supported with JDK logger.)
|
||||
|
||||
|`logging.pattern.file`
|
||||
|`FILE_LOG_PATTERN`
|
||||
|The log pattern to use in a file (if LOG_FILE enabled). (Not supported with JDK logger.)
|
||||
|
||||
|`logging.pattern.level`
|
||||
|`LOG_LEVEL_PATTERN`
|
||||
|The format to use to render the log level (default `%5p`). (The `logging.pattern.level` form is only supported by Logback.)
|
||||
|
||||
|`PID`
|
||||
|`PID`
|
||||
|The current process ID (discovered if possible and when not already defined as an OS
|
||||
|
@ -1095,6 +1107,20 @@ To help with the customization some other properties are transferred from the Sp
|
|||
All the logging systems supported can consult System properties when parsing their
|
||||
configuration files. See the default configurations in `spring-boot.jar` for examples.
|
||||
|
||||
[TIP]
|
||||
====
|
||||
|
||||
You can add MDC and other ad-hoc content to log lines by overriding
|
||||
only the `LOG_LEVEL_PATTERN` (or `logging.pattern.level` with
|
||||
Logback). For example, if you use `logging.pattern.level=user:%X{user}
|
||||
%5p` then the default log format will contain an MDC entry for "user"
|
||||
if it exists, e.g.
|
||||
|
||||
----
|
||||
2015-09-30 12:30:04.031 user:juergen INFO 22174 --- [ nio-8080-exec-0] demo.Controller Handling authenticated request
|
||||
----
|
||||
====
|
||||
|
||||
|
||||
|
||||
[[boot-features-logback-extensions]]
|
||||
|
|
|
@ -46,12 +46,12 @@ import ch.qos.logback.core.util.OptionHelper;
|
|||
class DefaultLogbackConfiguration {
|
||||
|
||||
private static final String CONSOLE_LOG_PATTERN = "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} "
|
||||
+ "%clr(%5p) %clr(${PID:- }){magenta} %clr(---){faint} "
|
||||
+ "%clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} "
|
||||
+ "%clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} "
|
||||
+ "%clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%rEx}";
|
||||
|
||||
private static final String FILE_LOG_PATTERN = "%d{yyyy-MM-dd HH:mm:ss.SSS} %5p "
|
||||
+ "${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%rEx}";
|
||||
private static final String FILE_LOG_PATTERN = "%d{yyyy-MM-dd HH:mm:ss.SSS} "
|
||||
+ "${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%rEx}";
|
||||
|
||||
private static final Charset UTF8 = Charset.forName("UTF-8");
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ import ch.qos.logback.core.status.Status;
|
|||
public class LogbackLoggingSystem extends Slf4JLoggingSystem {
|
||||
|
||||
private static final Map<LogLevel, Level> LEVELS;
|
||||
|
||||
static {
|
||||
Map<LogLevel, Level> levels = new HashMap<LogLevel, Level>();
|
||||
levels.put(LogLevel.TRACE, Level.TRACE);
|
||||
|
@ -85,8 +86,8 @@ public class LogbackLoggingSystem extends Slf4JLoggingSystem {
|
|||
|
||||
@Override
|
||||
protected String[] getStandardConfigLocations() {
|
||||
return new String[] { "logback-test.groovy", "logback-test.xml",
|
||||
"logback.groovy", "logback.xml" };
|
||||
return new String[] { "logback-test.groovy", "logback-test.xml", "logback.groovy",
|
||||
"logback.xml" };
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -109,6 +110,9 @@ public class LogbackLoggingSystem extends Slf4JLoggingSystem {
|
|||
LoggerContext context = getLoggerContext();
|
||||
stopAndReset(context);
|
||||
LogbackConfigurator configurator = new LogbackConfigurator(context);
|
||||
context.putProperty("LOG_LEVEL_PATTERN",
|
||||
initializationContext.getEnvironment().resolvePlaceholders(
|
||||
"${logging.pattern.level:${LOG_LEVEL_PATTERN:%5p}}"));
|
||||
new DefaultLogbackConfiguration(initializationContext, logFile)
|
||||
.apply(configurator);
|
||||
}
|
||||
|
@ -127,8 +131,8 @@ public class LogbackLoggingSystem extends Slf4JLoggingSystem {
|
|||
ResourceUtils.getURL(location));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException("Could not initialize Logback logging from "
|
||||
+ location, ex);
|
||||
throw new IllegalStateException(
|
||||
"Could not initialize Logback logging from " + location, ex);
|
||||
}
|
||||
List<Status> statuses = loggerContext.getStatusManager().getCopyOfStatusList();
|
||||
StringBuilder errors = new StringBuilder();
|
||||
|
@ -139,8 +143,8 @@ public class LogbackLoggingSystem extends Slf4JLoggingSystem {
|
|||
}
|
||||
}
|
||||
if (errors.length() > 0) {
|
||||
throw new IllegalStateException("Logback configuration error "
|
||||
+ "detected: \n" + errors);
|
||||
throw new IllegalStateException(
|
||||
"Logback configuration error " + "detected: \n" + errors);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -197,20 +201,21 @@ public class LogbackLoggingSystem extends Slf4JLoggingSystem {
|
|||
|
||||
private ch.qos.logback.classic.Logger getLogger(String name) {
|
||||
LoggerContext factory = getLoggerContext();
|
||||
return factory.getLogger(StringUtils.isEmpty(name) ? Logger.ROOT_LOGGER_NAME
|
||||
: name);
|
||||
return factory
|
||||
.getLogger(StringUtils.isEmpty(name) ? Logger.ROOT_LOGGER_NAME : name);
|
||||
|
||||
}
|
||||
|
||||
private LoggerContext getLoggerContext() {
|
||||
ILoggerFactory factory = StaticLoggerBinder.getSingleton().getLoggerFactory();
|
||||
Assert.isInstanceOf(LoggerContext.class, factory, String.format(
|
||||
"LoggerFactory is not a Logback LoggerContext but Logback is on "
|
||||
+ "the classpath. Either remove Logback or the competing "
|
||||
+ "implementation (%s loaded from %s). If you are using "
|
||||
+ "Weblogic you will need to add 'org.slf4j' to "
|
||||
+ "prefer-application-packages in WEB-INF/weblogic.xml",
|
||||
factory.getClass(), getLocation(factory)));
|
||||
Assert.isInstanceOf(LoggerContext.class, factory,
|
||||
String.format(
|
||||
"LoggerFactory is not a Logback LoggerContext but Logback is on "
|
||||
+ "the classpath. Either remove Logback or the competing "
|
||||
+ "implementation (%s loaded from %s). If you are using "
|
||||
+ "Weblogic you will need to add 'org.slf4j' to "
|
||||
+ "prefer-application-packages in WEB-INF/weblogic.xml",
|
||||
factory.getClass(), getLocation(factory)));
|
||||
return (LoggerContext) factory;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@ log4j.rootCategory=INFO, CONSOLE, FILE
|
|||
PID=????
|
||||
LOG_PATH=${java.io.tmpdir}
|
||||
LOG_FILE=${LOG_PATH}/spring.log
|
||||
LOG_PATTERN=[%d{yyyy-MM-dd HH:mm:ss.SSS}] boot%X{context} - ${PID} %5p [%t] --- %c{1}: %m%n
|
||||
LOG_LEVEL_PATTERN=%5p
|
||||
LOG_PATTERN=[%d{yyyy-MM-dd HH:mm:ss.SSS}] boot%X{context} - ${PID} ${LOG_LEVEL_PATTERN} [%t] --- %c{1}: %m%n
|
||||
|
||||
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
|
||||
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
log4j.rootCategory=INFO, CONSOLE
|
||||
|
||||
PID=????
|
||||
LOG_PATTERN=[%d{yyyy-MM-dd HH:mm:ss.SSS}] boot%X{context} - ${PID} %5p [%t] --- %c{1}: %m%n
|
||||
LOG_LEVEL_PATTERN=%5p
|
||||
LOG_PATTERN=[%d{yyyy-MM-dd HH:mm:ss.SSS}] boot%X{context} - ${PID} ${LOG_LEVEL_PATTERN} [%t] --- %c{1}: %m%n
|
||||
|
||||
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
|
||||
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
<Properties>
|
||||
<Property name="PID">????</Property>
|
||||
<Property name="LOG_EXCEPTION_CONVERSION_WORD">%rEx</Property>
|
||||
<Property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${sys:PID} --- [%t] %-40.40c{1.} : %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}</Property>
|
||||
<Property name="LOG_LEVEL_PATTERN">%5p</Property>
|
||||
<Property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} ${LOG_LEVEL_PATTERN} ${sys:PID} --- [%t] %-40.40c{1.} : %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}</Property>
|
||||
</Properties>
|
||||
<Appenders>
|
||||
<Console name="Console" target="SYSTEM_OUT" follow="true">
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
<Properties>
|
||||
<Property name="PID">????</Property>
|
||||
<Property name="LOG_EXCEPTION_CONVERSION_WORD">%rEx</Property>
|
||||
<Property name="LOG_PATTERN">%clr{%d{yyyy-MM-dd HH:mm:ss.SSS}}{faint} %clr{%5p} %clr{${sys:PID}}{magenta} %clr{---}{faint} %clr{[%15.15t]}{faint} %clr{%-40.40c{1.}}{cyan} %clr{:}{faint} %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}</Property>
|
||||
<Property name="LOG_LEVEL_PATTERN">%5p</Property>
|
||||
<Property name="LOG_PATTERN">%clr{%d{yyyy-MM-dd HH:mm:ss.SSS}}{faint} %clr{${LOG_LEVEL_PATTERN}} %clr{${sys:PID}}{magenta} %clr{---}{faint} %clr{[%15.15t]}{faint} %clr{%-40.40c{1.}}{cyan} %clr{:}{faint} %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}</Property>
|
||||
</Properties>
|
||||
<Appenders>
|
||||
<Console name="Console" target="SYSTEM_OUT" follow="true">
|
||||
|
|
|
@ -9,8 +9,8 @@ initialization performed by Boot
|
|||
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
|
||||
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
|
||||
|
||||
<property name="CONSOLE_LOG_PATTERN" value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%rEx}"/>
|
||||
<property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%rEx}"/>
|
||||
<property name="CONSOLE_LOG_PATTERN" value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%rEx}"/>
|
||||
<property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%rEx}"/>
|
||||
|
||||
<appender name="DEBUG_LEVEL_REMAPPER" class="org.springframework.boot.logging.logback.LevelRemappingAppender">
|
||||
<destinationLogger>org.springframework.boot</destinationLogger>
|
||||
|
|
|
@ -16,6 +16,16 @@
|
|||
|
||||
package org.springframework.boot.logging.logback;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.util.logging.Handler;
|
||||
|
@ -44,16 +54,6 @@ import org.springframework.util.StringUtils;
|
|||
import ch.qos.logback.classic.Logger;
|
||||
import ch.qos.logback.classic.LoggerContext;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Tests for {@link LogbackLoggingSystem}.
|
||||
*
|
||||
|
@ -237,6 +237,19 @@ public class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
|
|||
getLineWithText(output, "Hello world").contains("INFO"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLevelPatternProperty() {
|
||||
MockEnvironment environment = new MockEnvironment();
|
||||
environment.setProperty("logging.pattern.level", "X%clr(%p)X");
|
||||
LoggingInitializationContext loggingInitializationContext = new LoggingInitializationContext(
|
||||
environment);
|
||||
this.loggingSystem.initialize(loggingInitializationContext, null, null);
|
||||
this.logger.info("Hello world");
|
||||
String output = this.output.toString().trim();
|
||||
assertTrue("Wrong output pattern:\n" + output,
|
||||
getLineWithText(output, "Hello world").contains("XINFOX"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFilePatternProperty() throws Exception {
|
||||
MockEnvironment environment = new MockEnvironment();
|
||||
|
|
Loading…
Reference in New Issue