17
17
package org .springframework .boot .context .logging ;
18
18
19
19
import java .util .Collections ;
20
+ import java .util .LinkedHashMap ;
20
21
import java .util .List ;
21
22
import java .util .Locale ;
22
23
import java .util .Map ;
49
50
import org .springframework .core .env .Environment ;
50
51
import org .springframework .util .LinkedMultiValueMap ;
51
52
import org .springframework .util .MultiValueMap ;
53
+ import org .springframework .util .ObjectUtils ;
52
54
import org .springframework .util .ResourceUtils ;
53
55
import org .springframework .util .StringUtils ;
54
56
55
57
/**
56
58
* An {@link ApplicationListener} that configures the {@link LoggingSystem}. If the
57
59
* environment contains a {@code logging.config} property it will be used to bootstrap the
58
60
* logging system, otherwise a default configuration is used. Regardless, logging levels
59
- * will be customized if the environment contains {@code logging.level.*} entries.
61
+ * will be customized if the environment contains {@code logging.level.*} entries and
62
+ * logging groups can be defined with {@code logging.group} .
60
63
* <p>
61
64
* Debug and trace logging for Spring, Tomcat, Jetty and Hibernate will be enabled when
62
65
* the environment contains {@code debug} or {@code trace} properties that aren't set to
@@ -88,6 +91,9 @@ public class LoggingApplicationListener implements GenericApplicationListener {
88
91
private static final Bindable <Map <String , String >> STRING_STRING_MAP = Bindable
89
92
.mapOf (String .class , String .class );
90
93
94
+ private static final Bindable <Map <String , String []>> STRING_STRINGS_MAP = Bindable
95
+ .mapOf (String .class , String [].class );
96
+
91
97
/**
92
98
* The default order for the LoggingApplicationListener.
93
99
*/
@@ -111,19 +117,30 @@ public class LoggingApplicationListener implements GenericApplicationListener {
111
117
*/
112
118
public static final String LOGGING_SYSTEM_BEAN_NAME = "springBootLoggingSystem" ;
113
119
114
- private static final MultiValueMap <LogLevel , String > LOG_LEVEL_LOGGERS ;
120
+ private static final Map <String , List <String >> DEFAULT_GROUP_LOGGERS ;
121
+ static {
122
+ MultiValueMap <String , String > loggers = new LinkedMultiValueMap <>();
123
+ loggers .add ("web" , "org.springframework.core.codec" );
124
+ loggers .add ("web" , "org.springframework.http" );
125
+ loggers .add ("web" , "org.springframework.web" );
126
+ loggers .add ("sql" , "org.springframework.jdbc.core" );
127
+ loggers .add ("sql" , "org.hibernate.SQL" );
128
+ DEFAULT_GROUP_LOGGERS = Collections .unmodifiableMap (loggers );
129
+ }
115
130
116
- private static AtomicBoolean shutdownHookRegistered = new AtomicBoolean ( false ) ;
131
+ private static final Map < LogLevel , List < String >> LOG_LEVEL_LOGGERS ;
117
132
118
133
static {
119
- LOG_LEVEL_LOGGERS = new LinkedMultiValueMap <>();
120
- LOG_LEVEL_LOGGERS .add (LogLevel .DEBUG , "org.springframework.boot" );
121
- LOG_LEVEL_LOGGERS .add (LogLevel .DEBUG , "org.hibernate.SQL" );
122
- LOG_LEVEL_LOGGERS .add (LogLevel .TRACE , "org.springframework" );
123
- LOG_LEVEL_LOGGERS .add (LogLevel .TRACE , "org.apache.tomcat" );
124
- LOG_LEVEL_LOGGERS .add (LogLevel .TRACE , "org.apache.catalina" );
125
- LOG_LEVEL_LOGGERS .add (LogLevel .TRACE , "org.eclipse.jetty" );
126
- LOG_LEVEL_LOGGERS .add (LogLevel .TRACE , "org.hibernate.tool.hbm2ddl" );
134
+ MultiValueMap <LogLevel , String > loggers = new LinkedMultiValueMap <>();
135
+ loggers .add (LogLevel .DEBUG , "sql" );
136
+ loggers .add (LogLevel .DEBUG , "web" );
137
+ loggers .add (LogLevel .DEBUG , "org.springframework.boot" );
138
+ loggers .add (LogLevel .TRACE , "org.springframework" );
139
+ loggers .add (LogLevel .TRACE , "org.apache.tomcat" );
140
+ loggers .add (LogLevel .TRACE , "org.apache.catalina" );
141
+ loggers .add (LogLevel .TRACE , "org.eclipse.jetty" );
142
+ loggers .add (LogLevel .TRACE , "org.hibernate.tool.hbm2ddl" );
143
+ LOG_LEVEL_LOGGERS = Collections .unmodifiableMap (loggers );
127
144
}
128
145
129
146
private static final Class <?>[] EVENT_TYPES = { ApplicationStartingEvent .class ,
@@ -133,6 +150,8 @@ public class LoggingApplicationListener implements GenericApplicationListener {
133
150
private static final Class <?>[] SOURCE_TYPES = { SpringApplication .class ,
134
151
ApplicationContext .class };
135
152
153
+ private static AtomicBoolean shutdownHookRegistered = new AtomicBoolean (false );
154
+
136
155
private final Log logger = LogFactory .getLog (getClass ());
137
156
138
157
private LoggingSystem loggingSystem ;
@@ -304,8 +323,32 @@ protected void setLogLevels(LoggingSystem system, Environment environment) {
304
323
return ;
305
324
}
306
325
Binder binder = Binder .get (environment );
307
- binder .bind ("logging.level" , STRING_STRING_MAP ).orElseGet (Collections ::emptyMap )
308
- .forEach ((name , level ) -> setLogLevel (system , name , level ));
326
+ Map <String , String []> groups = getGroups (binder );
327
+ Map <String , String > levels = binder .bind ("logging.level" , STRING_STRING_MAP )
328
+ .orElseGet (Collections ::emptyMap );
329
+ levels .forEach ((name , level ) -> {
330
+ String [] groupedNames = groups .get (name );
331
+ if (ObjectUtils .isEmpty (groupedNames )) {
332
+ setLogLevel (system , name , level );
333
+ }
334
+ else {
335
+ setLogLevel (system , groupedNames , level );
336
+ }
337
+ });
338
+ }
339
+
340
+ private Map <String , String []> getGroups (Binder binder ) {
341
+ Map <String , String []> groups = new LinkedHashMap <>();
342
+ DEFAULT_GROUP_LOGGERS .forEach (
343
+ (name , loggers ) -> groups .put (name , StringUtils .toStringArray (loggers )));
344
+ binder .bind ("logging.group" , STRING_STRINGS_MAP .withExistingValue (groups ));
345
+ return groups ;
346
+ }
347
+
348
+ private void setLogLevel (LoggingSystem system , String [] names , String level ) {
349
+ for (String name : names ) {
350
+ setLogLevel (system , name , level );
351
+ }
309
352
}
310
353
311
354
private void setLogLevel (LoggingSystem system , String name , String level ) {
@@ -360,8 +403,9 @@ public void setSpringBootLogging(LogLevel springBootLogging) {
360
403
}
361
404
362
405
/**
363
- * Sets if initialization arguments should be parsed for {@literal --debug} and
364
- * {@literal --trace} options. Defaults to {@code true}.
406
+ * Sets if initialization arguments should be parsed for {@literal debug} and
407
+ * {@literal trace} properties (usually defined from {@literal --debug} or
408
+ * {@literal --trace} command line args. Defaults to {@code true}.
365
409
* @param parseArgs if arguments should be parsed
366
410
*/
367
411
public void setParseArgs (boolean parseArgs ) {
0 commit comments