Skip to content

Commit 733b22f

Browse files
Taylor WicksellDave Syer
authored andcommitted
gh-1331 defaulting 404 response metrics to "unkownPath" when no matching handler can be found
Fixes gh-1331, Fixes gh-1333
1 parent c6f5961 commit 733b22f

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricFilterAutoConfiguration.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import org.springframework.context.annotation.Configuration;
3838
import org.springframework.core.Ordered;
3939
import org.springframework.core.annotation.Order;
40+
import org.springframework.http.HttpStatus;
4041
import org.springframework.util.StopWatch;
4142
import org.springframework.web.filter.OncePerRequestFilter;
4243
import org.springframework.web.servlet.HandlerMapping;
@@ -56,6 +57,7 @@
5657
public class MetricFilterAutoConfiguration {
5758

5859
private static final int UNDEFINED_HTTP_STATUS = 999;
60+
private static final String UNKNOWN_PATH_SUFFIX = "/unknownPath";
5961

6062
@Autowired
6163
private CounterService counterService;
@@ -91,6 +93,10 @@ protected void doFilterInternal(HttpServletRequest request,
9193
{
9294
suffix = request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE).toString().replaceAll("[{}]", "-");
9395
}
96+
else if(getStatus(response) == HttpStatus.NOT_FOUND.value())
97+
{
98+
suffix=UNKNOWN_PATH_SUFFIX;
99+
}
94100
String gaugeKey = getKey("response" + suffix);
95101
MetricFilterAutoConfiguration.this.gaugeService.submit(gaugeKey,
96102
stopWatch.getTotalTimeMillis());

spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/MetricFilterAutoConfigurationTests.java

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import static org.mockito.Matchers.anyDouble;
2323
import static org.mockito.Matchers.eq;
2424
import static org.mockito.Mockito.mock;
25+
import static org.mockito.Mockito.times;
2526
import static org.mockito.Mockito.verify;
2627
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
2728
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@@ -37,11 +38,15 @@
3738
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
3839
import org.springframework.context.annotation.Bean;
3940
import org.springframework.context.annotation.Configuration;
41+
import org.springframework.http.HttpStatus;
4042
import org.springframework.mock.web.MockHttpServletRequest;
4143
import org.springframework.mock.web.MockHttpServletResponse;
4244
import org.springframework.test.web.servlet.MockMvc;
4345
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
46+
import org.springframework.web.bind.annotation.PathVariable;
4447
import org.springframework.web.bind.annotation.RequestMapping;
48+
import org.springframework.web.bind.annotation.ResponseBody;
49+
import org.springframework.web.bind.annotation.ResponseStatus;
4550
import org.springframework.web.bind.annotation.RestController;
4651

4752
/**
@@ -89,6 +94,39 @@ public void recordsHttpInteractionsWithTemplateVariable() throws Exception {
8994
anyDouble());
9095
context.close();
9196
}
97+
98+
@Test
99+
public void recordsKnown404HttpInteractionsAsSingleMetricWithPathAndTemplateVariable() throws Exception {
100+
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
101+
Config.class, MetricFilterAutoConfiguration.class);
102+
Filter filter = context.getBean(Filter.class);
103+
MockMvc mvc = MockMvcBuilders.standaloneSetup(new MetricFilterTestController()).addFilter(filter).build();
104+
mvc.perform(get("/knownPath/foo"))
105+
.andExpect(status().isNotFound());
106+
107+
verify(context.getBean(CounterService.class)).increment("status.404.knownPath.-someVariable-");
108+
verify(context.getBean(GaugeService.class)).submit(eq("response.knownPath.-someVariable-"),
109+
anyDouble());
110+
context.close();
111+
}
112+
113+
@Test
114+
public void records404HttpInteractionsAsSingleMetric() throws Exception {
115+
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
116+
Config.class, MetricFilterAutoConfiguration.class);
117+
Filter filter = context.getBean(Filter.class);
118+
MockMvc mvc = MockMvcBuilders.standaloneSetup(new MetricFilterTestController()).addFilter(filter).build();
119+
mvc.perform(get("/unknownPath/1"))
120+
.andExpect(status().isNotFound());
121+
122+
mvc.perform(get("/unknownPath/2"))
123+
.andExpect(status().isNotFound());
124+
125+
verify(context.getBean(CounterService.class), times(2)).increment("status.404.unknownPath");
126+
verify(context.getBean(GaugeService.class), times(2)).submit(eq("response.unknownPath"),
127+
anyDouble());
128+
context.close();
129+
}
92130

93131
@Test
94132
public void skipsFilterIfMissingServices() throws Exception {
@@ -121,7 +159,15 @@ class MetricFilterTestController
121159
{
122160

123161
@RequestMapping("templateVarTest/{someVariable}")
124-
public String testTemplateVariableResolution(String someVariable)
162+
public String testTemplateVariableResolution(@PathVariable String someVariable)
163+
{
164+
return someVariable;
165+
}
166+
167+
@RequestMapping("knownPath/{someVariable}")
168+
@ResponseStatus(HttpStatus.NOT_FOUND)
169+
@ResponseBody
170+
public String testKnownPathWith404Response(@PathVariable String someVariable)
125171
{
126172
return someVariable;
127173
}

0 commit comments

Comments
 (0)