Ensure that 5xx responses to unmapped requests produce a single metric

Previously, each 5xx response to a request that used a path variable
would result in a metric being recorded that contained the path
variable. Therefore, if a different path variable was included in each
request, a new metric would be recorded for each request. This is
problematic as it can lead to the metrics being flooded with unwanted
entries.

This commit updates MetricsFilter to treat 5xx responses sent before
mapping has occurred in the same way as 4xx and redirect responses.
A single metric, counter.status.500.unmapped, is now used.

Closes gh-4377
pull/4687/merge
Andy Wilkinson 9 years ago
parent dc9405676a
commit ee47ae4d20

@ -145,7 +145,8 @@ final class MetricsFilter extends OncePerRequestFilter {
return fixSpecialCharacters(bestMatchingPattern.toString());
}
Series series = getSeries(status);
if (Series.CLIENT_ERROR.equals(series) || Series.REDIRECTION.equals(series)) {
if (Series.CLIENT_ERROR.equals(series) || Series.SERVER_ERROR.equals(series)
|| Series.REDIRECTION.equals(series)) {
return UNKNOWN_PATH_SUFFIX;
}
return path;

@ -78,7 +78,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
*
* @author Phillip Webb
* @author Andy Wilkinson
* @@author Stephane Nicoll
* @author Stephane Nicoll
*/
public class MetricFilterAutoConfigurationTests {
@ -277,6 +277,24 @@ public class MetricFilterAutoConfigurationTests {
}
}
@Test
public void records5xxxHttpInteractionsAsSingleMetric() throws Exception {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
Config.class, MetricFilterAutoConfiguration.class,
ServiceUnavailableFilter.class);
MetricsFilter filter = context.getBean(MetricsFilter.class);
MockMvc mvc = MockMvcBuilders.standaloneSetup(new MetricFilterTestController())
.addFilter(filter)
.addFilter(context.getBean(ServiceUnavailableFilter.class)).build();
mvc.perform(get("/unknownPath/1")).andExpect(status().isServiceUnavailable());
mvc.perform(get("/unknownPath/2")).andExpect(status().isServiceUnavailable());
verify(context.getBean(CounterService.class), times(2))
.increment("status.503.unmapped");
verify(context.getBean(GaugeService.class), times(2))
.submit(eq("response.unmapped"), anyDouble());
context.close();
}
@Configuration
public static class Config {
@ -376,4 +394,18 @@ public class MetricFilterAutoConfigurationTests {
}
@Component
@Order(0)
public static class ServiceUnavailableFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
response.sendError(HttpStatus.SERVICE_UNAVAILABLE.value());
}
}
}

Loading…
Cancel
Save