Handle request mappings with regular expressions in MetricsFilter
Closes gh-7503
This commit is contained in:
parent
d9b8fc960c
commit
356edc725c
|
|
@ -20,7 +20,6 @@ import java.io.IOException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import javax.servlet.FilterChain;
|
import javax.servlet.FilterChain;
|
||||||
|
|
@ -67,7 +66,7 @@ final class MetricsFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
Set<PatternReplacer> replacements = new LinkedHashSet<PatternReplacer>();
|
Set<PatternReplacer> replacements = new LinkedHashSet<PatternReplacer>();
|
||||||
replacements.add(new PatternReplacer("[{}]", 0, "-"));
|
replacements.add(new PatternReplacer("\\{(.+?)(?::.+)?\\}", 0, "-$1-"));
|
||||||
replacements.add(new PatternReplacer("**", Pattern.LITERAL, "-star-star-"));
|
replacements.add(new PatternReplacer("**", Pattern.LITERAL, "-star-star-"));
|
||||||
replacements.add(new PatternReplacer("*", Pattern.LITERAL, "-star-"));
|
replacements.add(new PatternReplacer("*", Pattern.LITERAL, "-star-"));
|
||||||
replacements.add(new PatternReplacer("/-", Pattern.LITERAL, "/"));
|
replacements.add(new PatternReplacer("/-", Pattern.LITERAL, "/"));
|
||||||
|
|
@ -140,13 +139,13 @@ final class MetricsFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
private void recordMetrics(HttpServletRequest request, String path, int status,
|
private void recordMetrics(HttpServletRequest request, String path, int status,
|
||||||
long time) {
|
long time) {
|
||||||
String suffix = getFinalStatus(request, path, status);
|
String suffix = determineMetricNameSuffix(request, path, status);
|
||||||
submitMetrics(MetricsFilterSubmission.MERGED, request, status, time, suffix);
|
submitMetrics(MetricsFilterSubmission.MERGED, request, status, time, suffix);
|
||||||
submitMetrics(MetricsFilterSubmission.PER_HTTP_METHOD, request, status, time,
|
submitMetrics(MetricsFilterSubmission.PER_HTTP_METHOD, request, status, time,
|
||||||
suffix);
|
suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getFinalStatus(HttpServletRequest request, String path, int status) {
|
private String determineMetricNameSuffix(HttpServletRequest request, String path, int status) {
|
||||||
Object bestMatchingPattern = request
|
Object bestMatchingPattern = request
|
||||||
.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
|
.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
|
||||||
if (bestMatchingPattern != null) {
|
if (bestMatchingPattern != null) {
|
||||||
|
|
@ -242,8 +241,7 @@ final class MetricsFilter extends OncePerRequestFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String apply(String input) {
|
public String apply(String input) {
|
||||||
return this.pattern.matcher(input)
|
return this.pattern.matcher(input).replaceAll(this.replacement);
|
||||||
.replaceAll(Matcher.quoteReplacement(this.replacement));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,51 @@ public class MetricFilterAutoConfigurationTests {
|
||||||
context.close();
|
context.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void recordsHttpInteractionsWithRegexTemplateVariable() throws Exception {
|
||||||
|
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||||
|
Config.class, MetricFilterAutoConfiguration.class);
|
||||||
|
Filter filter = context.getBean(Filter.class);
|
||||||
|
MockMvc mvc = MockMvcBuilders.standaloneSetup(new MetricFilterTestController())
|
||||||
|
.addFilter(filter).build();
|
||||||
|
mvc.perform(get("/templateVarRegexTest/foo")).andExpect(status().isOk());
|
||||||
|
verify(context.getBean(CounterService.class))
|
||||||
|
.increment("status.200.templateVarRegexTest.someVariable");
|
||||||
|
verify(context.getBean(GaugeService.class))
|
||||||
|
.submit(eq("response.templateVarRegexTest.someVariable"), anyDouble());
|
||||||
|
context.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void recordsHttpInteractionsWithWilcardMapping() throws Exception {
|
||||||
|
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||||
|
Config.class, MetricFilterAutoConfiguration.class);
|
||||||
|
Filter filter = context.getBean(Filter.class);
|
||||||
|
MockMvc mvc = MockMvcBuilders.standaloneSetup(new MetricFilterTestController())
|
||||||
|
.addFilter(filter).build();
|
||||||
|
mvc.perform(get("/wildcardMapping/foo")).andExpect(status().isOk());
|
||||||
|
verify(context.getBean(CounterService.class))
|
||||||
|
.increment("status.200.wildcardMapping.star");
|
||||||
|
verify(context.getBean(GaugeService.class))
|
||||||
|
.submit(eq("response.wildcardMapping.star"), anyDouble());
|
||||||
|
context.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void recordsHttpInteractionsWithDoubleWildcardMapping() throws Exception {
|
||||||
|
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||||
|
Config.class, MetricFilterAutoConfiguration.class);
|
||||||
|
Filter filter = context.getBean(Filter.class);
|
||||||
|
MockMvc mvc = MockMvcBuilders.standaloneSetup(new MetricFilterTestController())
|
||||||
|
.addFilter(filter).build();
|
||||||
|
mvc.perform(get("/doubleWildcardMapping/foo/bar/baz")).andExpect(status().isOk());
|
||||||
|
verify(context.getBean(CounterService.class))
|
||||||
|
.increment("status.200.doubleWildcardMapping.star-star.baz");
|
||||||
|
verify(context.getBean(GaugeService.class))
|
||||||
|
.submit(eq("response.doubleWildcardMapping.star-star.baz"), anyDouble());
|
||||||
|
context.close();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void recordsKnown404HttpInteractionsAsSingleMetricWithPathAndTemplateVariable()
|
public void recordsKnown404HttpInteractionsAsSingleMetricWithPathAndTemplateVariable()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
|
@ -429,6 +474,22 @@ public class MetricFilterAutoConfigurationTests {
|
||||||
return someVariable;
|
return someVariable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequestMapping("wildcardMapping/*")
|
||||||
|
public String testWildcardMapping() {
|
||||||
|
return "wildcard";
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("doubleWildcardMapping/**/baz")
|
||||||
|
public String testDoubleWildcardMapping() {
|
||||||
|
return "doubleWildcard";
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("templateVarRegexTest/{someVariable:[a-z]+}")
|
||||||
|
public String testTemplateVariableRegexResolution(
|
||||||
|
@PathVariable String someVariable) {
|
||||||
|
return someVariable;
|
||||||
|
}
|
||||||
|
|
||||||
@RequestMapping("knownPath/{someVariable}")
|
@RequestMapping("knownPath/{someVariable}")
|
||||||
@ResponseStatus(HttpStatus.NOT_FOUND)
|
@ResponseStatus(HttpStatus.NOT_FOUND)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue