From 5490e73922b37a7f0bdde43eb318cb1038b45d60 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Wed, 22 Nov 2023 16:29:41 +0100 Subject: [PATCH] Improve Tags generation for methods names This commit optimizes the `Tag` generation for method names by only allocating new `Tag` instances for well-known method names. Others will be marked as "UNKNOWN". --- .../web/reactive/server/WebFluxTags.java | 11 +++++++++-- .../actuate/metrics/web/servlet/WebMvcTags.java | 11 +++++++++-- .../endpoint/web/servlet/WebMvcTagsTests.java | 16 +++++++++++++++- .../web/reactive/server/WebFluxTagsTests.java | 17 ++++++++++++++--- 4 files changed, 47 insertions(+), 8 deletions(-) diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTags.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTags.java index 622877ca5331..6d11a514338a 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTags.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTags.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import io.micrometer.core.instrument.Tag; import org.springframework.boot.actuate.metrics.http.Outcome; +import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.util.StringUtils; @@ -53,6 +54,8 @@ public final class WebFluxTags { private static final Tag EXCEPTION_NONE = Tag.of("exception", "None"); + private static final Tag METHOD_UNKNOWN = Tag.of("method", "UNKNOWN"); + private static final Pattern FORWARD_SLASHES_PATTERN = Pattern.compile("//+"); private static final Set DISCONNECTED_CLIENT_EXCEPTIONS = new HashSet<>( @@ -70,7 +73,11 @@ private WebFluxTags() { * @return the method tag whose value is a capitalized method (e.g. GET). */ public static Tag method(ServerWebExchange exchange) { - return Tag.of("method", exchange.getRequest().getMethodValue()); + HttpMethod httpMethod = exchange.getRequest().getMethod(); + if (httpMethod != null) { + return Tag.of("method", httpMethod.name()); + } + return METHOD_UNKNOWN; } /** diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcTags.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcTags.java index e5e2147bf8bb..9f92c1ce33f3 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcTags.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcTags.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import io.micrometer.core.instrument.Tag; import org.springframework.boot.actuate.metrics.http.Outcome; +import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.util.StringUtils; import org.springframework.web.servlet.HandlerMapping; @@ -71,7 +72,13 @@ private WebMvcTags() { * @return the method tag whose value is a capitalized method (e.g. GET). */ public static Tag method(HttpServletRequest request) { - return (request != null) ? Tag.of("method", request.getMethod()) : METHOD_UNKNOWN; + if (request != null) { + HttpMethod httpMethod = HttpMethod.resolve(request.getMethod()); + if (httpMethod != null) { + return Tag.of("method", httpMethod.name()); + } + } + return METHOD_UNKNOWN; } /** diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcTagsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcTagsTests.java index 36ba42db687b..47215d74317c 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcTagsTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcTagsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -179,4 +179,18 @@ void outcomeTagIsUnknownWhenResponseStatusIsInUnknownSeries() { assertThat(tag.getValue()).isEqualTo("UNKNOWN"); } + @Test + void methodTagIsWellKnownHttpMethod() { + this.request.setMethod("GET"); + Tag tag = WebMvcTags.method(this.request); + assertThat(tag.getValue()).isEqualTo("GET"); + } + + @Test + void methodTagForUnknownHttpMethods() { + this.request.setMethod("TEST"); + Tag tag = WebMvcTags.method(this.request); + assertThat(tag.getValue()).isEqualTo("UNKNOWN"); + } + } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTagsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTagsTests.java index 90bf64e7ba08..9d245ea306e6 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTagsTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTagsTests.java @@ -22,6 +22,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; @@ -130,13 +131,23 @@ void uriTagValueIsUnknownWhenRequestHasNoPatternAndNonRootPathInfo() { } @Test - void methodTagToleratesNonStandardHttpMethods() { + void methodTagValueIsHttpMethod() { ServerWebExchange exchange = mock(ServerWebExchange.class); ServerHttpRequest request = mock(ServerHttpRequest.class); given(exchange.getRequest()).willReturn(request); - given(request.getMethodValue()).willReturn("CUSTOM"); + given(request.getMethod()).willReturn(HttpMethod.GET); Tag tag = WebFluxTags.method(exchange); - assertThat(tag.getValue()).isEqualTo("CUSTOM"); + assertThat(tag.getValue()).isEqualTo("GET"); + } + + @Test + void methodTagMarksNonStandardHttpMethodsAsUnknown() { + ServerWebExchange exchange = mock(ServerWebExchange.class); + ServerHttpRequest request = mock(ServerHttpRequest.class); + given(exchange.getRequest()).willReturn(request); + given(request.getMethod()).willReturn(null); + Tag tag = WebFluxTags.method(exchange); + assertThat(tag.getValue()).isEqualTo("UNKNOWN"); } @Test