Skip to content

Commit 3ec0452

Browse files
committed
Dedicated, "_"-prefixed log category for request mappings
Closes gh-26539
1 parent cb3af52 commit 3ec0452

File tree

13 files changed

+122
-39
lines changed

13 files changed

+122
-39
lines changed

spring-core/src/main/java/org/springframework/core/log/LogDelegateFactory.java

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -63,15 +63,28 @@ public static Log getCompositeLog(Log primaryLogger, Log secondaryLogger, Log...
6363
}
6464

6565
/**
66-
* Create a "hidden" logger whose name is intentionally prefixed with "_"
67-
* because its output is either too verbose or otherwise deemed as optional
68-
* or unnecessary to see at any log level by default under the normal package
69-
* based log hierarchy.
66+
* Create a "hidden" logger with a category name prefixed with "_", thus
67+
* precluding it from being enabled together with other log categories from
68+
* the same package. This is useful for specialized output that is either
69+
* too verbose or otherwise optional or unnecessary to see all the time.
7070
* @param clazz the class for which to create a logger
71-
* @return a logger for the hidden category ("_" + fully-qualified class name)
71+
* @return a Log with the category {@code "_" + fully-qualified class name}
7272
*/
7373
public static Log getHiddenLog(Class<?> clazz) {
74-
return LogFactory.getLog("_" + clazz.getName());
74+
return getHiddenLog(clazz.getName());
75+
}
76+
77+
/**
78+
* Create a "hidden" logger with a category name prefixed with "_", thus
79+
* precluding it from being enabled together with other log categories from
80+
* the same package. This is useful for specialized output that is either
81+
* too verbose or otherwise optional or unnecessary to see all the time.
82+
* @param category the log category to use
83+
* @return a Log with the category {@code "_" + category}
84+
* @since 5.3.5
85+
*/
86+
public static Log getHiddenLog(String category) {
87+
return LogFactory.getLog("_" + category);
7588
}
7689

7790
}

spring-webflux/src/main/java/org/springframework/web/reactive/function/server/support/RouterFunctionMapping.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -128,12 +128,15 @@ private List<RouterFunction<?>> routerFunctions() {
128128
}
129129

130130
private void logRouterFunctions(List<RouterFunction<?>> routerFunctions) {
131-
if (logger.isDebugEnabled()) {
131+
if (mappingsLogger.isDebugEnabled()) {
132+
routerFunctions.forEach(function -> mappingsLogger.debug("Mapped " + function));
133+
}
134+
else if (logger.isDebugEnabled()) {
132135
int total = routerFunctions.size();
133136
String message = total + " RouterFunction(s) in " + formatMappingName();
134137
if (logger.isTraceEnabled()) {
135138
if (total > 0) {
136-
routerFunctions.forEach(routerFunction -> logger.trace("Mapped " + routerFunction));
139+
routerFunctions.forEach(function -> logger.trace("Mapped " + function));
137140
}
138141
else {
139142
logger.trace(message);

spring-webflux/src/main/java/org/springframework/web/reactive/handler/AbstractHandlerMapping.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@
1818

1919
import java.util.Map;
2020

21+
import org.apache.commons.logging.Log;
2122
import reactor.core.publisher.Mono;
2223

2324
import org.springframework.beans.factory.BeanNameAware;
2425
import org.springframework.context.support.ApplicationObjectSupport;
2526
import org.springframework.core.Ordered;
27+
import org.springframework.core.log.LogDelegateFactory;
2628
import org.springframework.http.server.reactive.ServerHttpRequest;
2729
import org.springframework.lang.Nullable;
2830
import org.springframework.util.Assert;
@@ -51,6 +53,10 @@ public abstract class AbstractHandlerMapping extends ApplicationObjectSupport
5153

5254
private static final WebHandler NO_OP_HANDLER = exchange -> Mono.empty();
5355

56+
/** Dedicated "hidden" logger for request mappings. */
57+
protected final Log mappingsLogger =
58+
LogDelegateFactory.getHiddenLog(HandlerMapping.class.getName() + ".Mappings");
59+
5460

5561
private final PathPatternParser patternParser;
5662

spring-webflux/src/main/java/org/springframework/web/reactive/handler/SimpleUrlHandlerMapping.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -158,9 +158,16 @@ protected void registerHandlers(Map<String, Object> urlMap) throws BeansExceptio
158158
}
159159
registerHandler(url, handler);
160160
}
161-
if (logger.isDebugEnabled()) {
162-
logger.debug("Patterns " + getHandlerMap().keySet() + " in " + formatMappingName());
163-
}
161+
logMappings();
162+
}
163+
}
164+
165+
private void logMappings() {
166+
if (mappingsLogger.isDebugEnabled()) {
167+
mappingsLogger.debug(formatMappingName() + " " + getHandlerMap());
168+
}
169+
else if (logger.isDebugEnabled()) {
170+
logger.debug("Patterns " + getHandlerMap().keySet() + " in " + formatMappingName());
164171
}
165172
}
166173

spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceWebHandler.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,9 @@ private Object formatLocations() {
619619
return this.locationValues.stream().collect(Collectors.joining("\", \"", "[\"", "\"]"));
620620
}
621621
else if (!this.locations.isEmpty()) {
622-
return "[" + this.locations + "]";
622+
return "[" + this.locations.toString()
623+
.replaceAll("class path resource", "Classpath")
624+
.replaceAll("ServletContext resource", "ServletContext") + "]";
623625
}
624626
return Collections.emptyList();
625627
}

spring-webflux/src/main/java/org/springframework/web/reactive/result/method/AbstractHandlerMethodMapping.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -211,6 +211,9 @@ protected void detectHandlerMethods(final Object handler) {
211211
if (logger.isTraceEnabled()) {
212212
logger.trace(formatMappings(userType, methods));
213213
}
214+
else if (mappingsLogger.isDebugEnabled()) {
215+
mappingsLogger.debug(formatMappings(userType, methods));
216+
}
214217
methods.forEach((method, mapping) -> {
215218
Method invocableMethod = AopUtils.selectInvocableMethod(method, userType);
216219
registerHandlerMethod(handler, invocableMethod, mapping);

spring-webmvc/src/main/java/org/springframework/web/servlet/function/support/RouterFunctionMapping.java

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -153,14 +153,31 @@ private void initRouterFunction() {
153153
(this.detectHandlerFunctionsInAncestorContexts ?
154154
BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, RouterFunction.class) :
155155
applicationContext.getBeansOfType(RouterFunction.class));
156-
157156
List<RouterFunction> routerFunctions = new ArrayList<>(beans.values());
158-
if (!CollectionUtils.isEmpty(routerFunctions) && logger.isInfoEnabled()) {
159-
routerFunctions.forEach(routerFunction -> logger.info("Mapped " + routerFunction));
157+
this.routerFunction = routerFunctions.stream().reduce(RouterFunction::andOther).orElse(null);
158+
logRouterFunctions(routerFunctions);
159+
}
160+
161+
@SuppressWarnings("rawtypes")
162+
private void logRouterFunctions(List<RouterFunction> routerFunctions) {
163+
if (mappingsLogger.isDebugEnabled()) {
164+
routerFunctions.forEach(function -> mappingsLogger.debug("Mapped " + function));
165+
}
166+
else if (logger.isDebugEnabled()) {
167+
int total = routerFunctions.size();
168+
String message = total + " RouterFunction(s) in " + formatMappingName();
169+
if (logger.isTraceEnabled()) {
170+
if (total > 0) {
171+
routerFunctions.forEach(function -> logger.trace("Mapped " + function));
172+
}
173+
else {
174+
logger.trace(message);
175+
}
176+
}
177+
else if (total > 0) {
178+
logger.debug(message);
179+
}
160180
}
161-
this.routerFunction = routerFunctions.stream()
162-
.reduce(RouterFunction::andOther)
163-
.orElse(null);
164181
}
165182

166183
/**

spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractDetectingUrlHandlerMapping.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -82,7 +82,10 @@ protected void detectHandlers() throws BeansException {
8282
}
8383
}
8484

85-
if ((logger.isDebugEnabled() && !getHandlerMap().isEmpty()) || logger.isTraceEnabled()) {
85+
if (mappingsLogger.isDebugEnabled()) {
86+
mappingsLogger.debug(formatMappingName() + " " + getHandlerMap());
87+
}
88+
else if ((logger.isDebugEnabled() && !getHandlerMap().isEmpty()) || logger.isTraceEnabled()) {
8689
logger.debug("Detected " + getHandlerMap().size() + " mappings in " + formatMappingName());
8790
}
8891
}

spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMapping.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,13 @@
2626
import javax.servlet.http.HttpServletRequest;
2727
import javax.servlet.http.HttpServletResponse;
2828

29+
import org.apache.commons.logging.Log;
30+
2931
import org.springframework.beans.BeansException;
3032
import org.springframework.beans.factory.BeanFactoryUtils;
3133
import org.springframework.beans.factory.BeanNameAware;
3234
import org.springframework.core.Ordered;
35+
import org.springframework.core.log.LogDelegateFactory;
3336
import org.springframework.http.server.RequestPath;
3437
import org.springframework.lang.Nullable;
3538
import org.springframework.util.AntPathMatcher;
@@ -75,6 +78,11 @@
7578
public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport
7679
implements HandlerMapping, Ordered, BeanNameAware {
7780

81+
/** Dedicated "hidden" logger for request mappings. */
82+
protected final Log mappingsLogger =
83+
LogDelegateFactory.getHiddenLog(HandlerMapping.class.getName() + ".Mappings");
84+
85+
7886
@Nullable
7987
private Object defaultHandler;
8088

@@ -358,7 +366,7 @@ public void setBeanName(String name) {
358366
}
359367

360368
protected String formatMappingName() {
361-
return this.beanName != null ? "'" + this.beanName + "'" : "<unknown>";
369+
return this.beanName != null ? "'" + this.beanName + "'" : getClass().getName();
362370
}
363371

364372

spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,9 @@ protected void detectHandlerMethods(Object handler) {
290290
if (logger.isTraceEnabled()) {
291291
logger.trace(formatMappings(userType, methods));
292292
}
293+
else if (mappingsLogger.isDebugEnabled()) {
294+
mappingsLogger.debug(formatMappings(userType, methods));
295+
}
293296
methods.forEach((method, mapping) -> {
294297
Method invocableMethod = AopUtils.selectInvocableMethod(method, userType);
295298
registerHandlerMethod(handler, invocableMethod, mapping);

spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ protected Object lookupHandler(
206206
if (matches.size() > 1) {
207207
matches.sort(PathPattern.SPECIFICITY_COMPARATOR);
208208
if (logger.isTraceEnabled()) {
209-
logger.debug("Matching patterns " + matches);
209+
logger.trace("Matching patterns " + matches);
210210
}
211211
}
212212
PathPattern pattern = matches.get(0);

spring-webmvc/src/main/java/org/springframework/web/servlet/handler/SimpleUrlHandlerMapping.java

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -161,17 +161,31 @@ protected void registerHandlers(Map<String, Object> urlMap) throws BeansExceptio
161161
}
162162
registerHandler(url, handler);
163163
});
164-
if (logger.isDebugEnabled()) {
165-
List<String> patterns = new ArrayList<>();
166-
if (getRootHandler() != null) {
167-
patterns.add("/");
168-
}
169-
if (getDefaultHandler() != null) {
170-
patterns.add("/**");
171-
}
172-
patterns.addAll(getHandlerMap().keySet());
173-
logger.debug("Patterns " + patterns + " in " + formatMappingName());
164+
logMappings();
165+
}
166+
}
167+
168+
private void logMappings() {
169+
if (mappingsLogger.isDebugEnabled()) {
170+
Map<String, Object> map = new LinkedHashMap<>(getHandlerMap());
171+
if (getRootHandler() != null) {
172+
map.put("/", getRootHandler());
173+
}
174+
if (getDefaultHandler() != null) {
175+
map.put("/**", getDefaultHandler());
176+
}
177+
mappingsLogger.debug(formatMappingName() + " " + map);
178+
}
179+
else if (logger.isDebugEnabled()) {
180+
List<String> patterns = new ArrayList<>();
181+
if (getRootHandler() != null) {
182+
patterns.add("/");
183+
}
184+
if (getDefaultHandler() != null) {
185+
patterns.add("/**");
174186
}
187+
patterns.addAll(getHandlerMap().keySet());
188+
logger.debug("Patterns " + patterns + " in " + formatMappingName());
175189
}
176190
}
177191

spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,10 @@ protected void setHeaders(HttpServletResponse response, Resource resource, @Null
800800

801801
@Override
802802
public String toString() {
803-
return "ResourceHttpRequestHandler " + getLocations();
803+
return "ResourceHttpRequestHandler " +
804+
getLocations().toString()
805+
.replaceAll("class path resource", "Classpath")
806+
.replaceAll("ServletContext resource", "ServletContext");
804807
}
808+
805809
}

0 commit comments

Comments
 (0)