Make sure the MetricsFilter uses committed response's status
Previously, if an exception was thrown during request handling after the response had been committed, i.e. after the status and headers had been written, the metrics filter would assume that it was a 500 response. This was potentially inaccurate as the status had already been sent to the client and before the exception was thrown and it may have been something other than a 500. This commit updates MetricsFilter so that it will use the status from the response if the response has been committed even when an exception is thrown. Closes gh-7277
This commit is contained in:
parent
6a87df8e46
commit
97e5e32496
|
|
@ -109,6 +109,9 @@ final class MetricsFilter extends OncePerRequestFilter {
|
|||
}
|
||||
finally {
|
||||
if (!request.isAsyncStarted()) {
|
||||
if (response.isCommitted()) {
|
||||
status = getStatus(response);
|
||||
}
|
||||
stopWatch.stop();
|
||||
request.removeAttribute(ATTRIBUTE_STOP_WATCH);
|
||||
recordMetrics(request, path, status, stopWatch.getTotalTimeMillis());
|
||||
|
|
|
|||
|
|
@ -365,6 +365,37 @@ public class MetricFilterAutoConfigurationTests {
|
|||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenExceptionIsThrownResponseStatusIsUsedWhenResponseHasBeenCommitted()
|
||||
throws Exception {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
context.register(Config.class, MetricFilterAutoConfiguration.class);
|
||||
context.refresh();
|
||||
Filter filter = context.getBean(Filter.class);
|
||||
final MockHttpServletRequest request = new MockHttpServletRequest("GET",
|
||||
"/test/path");
|
||||
final MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
FilterChain chain = mock(FilterChain.class);
|
||||
willAnswer(new Answer<Object>() {
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||
response.setStatus(200);
|
||||
response.setCommitted(true);
|
||||
throw new IOException();
|
||||
}
|
||||
}).given(chain).doFilter(request, response);
|
||||
try {
|
||||
filter.doFilter(request, response, chain);
|
||||
fail();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
// Continue
|
||||
}
|
||||
verify(context.getBean(CounterService.class))
|
||||
.increment(eq("status.200.test.path"));
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class Config {
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue