Set matching pattern in reactive server observation context

This commit fixes the observation instrumentation for the reactive HTTP
server by setting the best matching pattern determined by the web
framework into the `ServerRequestObservationContext`.

This information is required by the observation convention for creating
the expected `KeyValue` for the matching pattern. Prior to this commit,
the information was missing and resulted in an UNKNOWN key value.

Fixes gh-29422
This commit is contained in:
Brian Clozel
2022-11-02 19:02:31 +01:00
parent 05c997802b
commit db79d1d2b9
5 changed files with 33 additions and 1 deletions

View File

@@ -28,6 +28,7 @@ import org.springframework.http.codec.HttpMessageReader;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
import org.springframework.web.filter.reactive.ServerHttpObservationFilter;
import org.springframework.web.reactive.function.server.HandlerFunction;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
@@ -170,6 +171,8 @@ public class RouterFunctionMapping extends AbstractHandlerMapping implements Ini
PathPattern matchingPattern = (PathPattern) attributes.get(RouterFunctions.MATCHING_PATTERN_ATTRIBUTE);
if (matchingPattern != null) {
attributes.put(BEST_MATCHING_PATTERN_ATTRIBUTE, matchingPattern);
ServerHttpObservationFilter.findObservationContext(serverRequest.exchange())
.ifPresent(context -> context.setPathPattern(matchingPattern));
}
Map<String, String> uriVariables =
(Map<String, String>) attributes.get(RouterFunctions.URI_TEMPLATE_VARIABLES_ATTRIBUTE);

View File

@@ -30,6 +30,7 @@ import org.springframework.http.server.PathContainer;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.reactive.ServerHttpObservationFilter;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.util.pattern.PathPattern;
@@ -165,6 +166,8 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping {
exchange.getAttributes().put(BEST_MATCHING_HANDLER_ATTRIBUTE, handler);
exchange.getAttributes().put(BEST_MATCHING_PATTERN_ATTRIBUTE, pattern);
ServerHttpObservationFilter.findObservationContext(exchange)
.ifPresent(context -> context.setPathPattern(pattern));
exchange.getAttributes().put(PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, pathWithinMapping);
exchange.getAttributes().put(URI_TEMPLATE_VARIABLES_ATTRIBUTE, matchInfo.getUriVariables());

View File

@@ -38,6 +38,7 @@ import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.Assert;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.filter.reactive.ServerHttpObservationFilter;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.reactive.HandlerMapping;
import org.springframework.web.reactive.result.condition.NameValueExpression;
@@ -139,6 +140,8 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
exchange.getAttributes().put(BEST_MATCHING_HANDLER_ATTRIBUTE, handlerMethod);
exchange.getAttributes().put(BEST_MATCHING_PATTERN_ATTRIBUTE, bestPattern);
ServerHttpObservationFilter.findObservationContext(exchange)
.ifPresent(context -> context.setPathPattern(bestPattern));
exchange.getAttributes().put(URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriVariables);
exchange.getAttributes().put(MATRIX_VARIABLES_ATTRIBUTE, matrixVariables);