package io.dropwizard.servlets;
import com.google.common.annotations.VisibleForTesting;
import io.dropwizard.util.Duration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.function.Supplier;
import static io.dropwizard.servlets.Servlets.getFullUrl;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
A servlet filter which logs the methods and URIs of requests which take longer than a given
duration of time to complete.
/**
* A servlet filter which logs the methods and URIs of requests which take longer than a given
* duration of time to complete.
*/
@SuppressWarnings("UnusedDeclaration")
public class SlowRequestFilter implements Filter {
private final long threshold;
private Supplier<Long> currentTimeProvider = System::nanoTime;
private Logger logger = LoggerFactory.getLogger(SlowRequestFilter.class);
Creates a filter which logs requests which take longer than 1 second.
/**
* Creates a filter which logs requests which take longer than 1 second.
*/
public SlowRequestFilter() {
this(Duration.seconds(1));
}
Creates a filter which logs requests which take longer than the given duration.
Params: - threshold – the threshold for considering a request slow
/**
* Creates a filter which logs requests which take longer than the given duration.
*
* @param threshold the threshold for considering a request slow
*/
public SlowRequestFilter(Duration threshold) {
this.threshold = threshold.toNanoseconds();
}
@VisibleForTesting
void setCurrentTimeProvider(Supplier<Long> currentTimeProvider) {
this.currentTimeProvider = currentTimeProvider;
}
@VisibleForTesting
void setLogger(Logger logger) {
this.logger = logger;
}
@Override
public void init(FilterConfig filterConfig) throws ServletException { /* unused */ }
@Override
public void destroy() { /* unused */ }
@Override
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain) throws IOException, ServletException {
final HttpServletRequest req = (HttpServletRequest) request;
final long startTime = currentTimeProvider.get();
try {
chain.doFilter(request, response);
} finally {
final long elapsedNS = currentTimeProvider.get() - startTime;
final long elapsedMS = NANOSECONDS.toMillis(elapsedNS);
if (elapsedNS >= threshold) {
logger.warn("Slow request: {} {} ({}ms)",
req.getMethod(),
getFullUrl(req), elapsedMS);
}
}
}
}