我使用spring boot实现了一个API,我想跟踪不同API调用的响应时间(GET,POST,DELETE,PUT)。
目前我一直在尝试使用以下代码作为过滤器
@Component
public class timeFilter implements Filter {
private static final Logger LOGGER = LoggerFactory.getLogger(timeFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// empty
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
long time = System.currentTimeMillis();
try {
chain.doFilter(req, resp);
} finally {
time = System.currentTimeMillis() - time;
LOGGER.trace("{}: {} ms ", ((HttpServletRequest) req).getRequestURI(), time);
}
}
@Override
public void destroy() {
// empty
}
}
但是,这只会跟踪从我的存储库中检索所有学生的GET调用的响应时间。
有没有办法可以跟踪其他调用的响应时间,以及我需要在图表上绘制每个调用的响应时间。还有一个原因是我的第一个GET呼叫的响应时间大约为200-300 MS,但之后的任何呼叫的响应时间都在0-20之间?
答案 0 :(得分:0)
你应该使用spring的OncePerRequestFilter,它应该完成工作 确保扫描此组件。
请注意,我还有动态属性testproject.logging.includeQueryParams,如果你需要包含查询参数,你可以控制它们,对于标题等也是如此。
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
/**
* Implementation of Spring's {@link OncePerRequestFilter} to log each request
* including the URI, query String and execution time.
*/
@Component
public class RequestLoggingInterceptor extends OncePerRequestFilter {
/** {@code Logger} instance. */
private final Logger logger = LoggerFactory.getLogger(RequestLoggingInterceptor.class);
/** {@code true} if query parameters should be logged. */
private boolean includeQueryParams = true;
/** {@code true} if client address should be logged. */
private boolean includeClient = true;
/** {@code true} if request headers should be logged. */
private boolean includeHeaders = true;
@Override
protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response, final FilterChain filterChain) throws ServletException, IOException {
final long start = System.nanoTime();
try {
filterChain.doFilter(request, response);
} finally {
if( logger.isInfoEnabled() ) {
final long end = System.nanoTime();
logger.info(buildMessage(request, end - start));
}
}
}
/**
* Builds the message to log from the specified {@code request} including
* the {@code executionTime}.
*
* @param request
* @param executionTime in nanoseconds
* @return log message
*/
private String buildMessage(final HttpServletRequest request, final long executionTime) {
final StringBuilder buffer = new StringBuilder();
buffer.append("method=").append(request.getMethod());
buffer.append(" uri=").append(request.getRequestURI());
if( includeQueryParams && request.getQueryString() != null ) {
buffer.append('?').append(request.getQueryString());
}
buffer.append(" executionTime=").append(executionTime);
return buffer.toString();
}
/**
* Sets whether to {@code include} the query parameter String when logging
* the request URI.
*
* @param include
*/
@Value("${testproject.logging.includeQueryParams:true}")
public void setIncludeQueryParams(final boolean include) {
includeQueryParams = include;
}
}
答案 1 :(得分:0)
万一有人觉得有用,这是使用反应式WebFilter的一种方法
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;
@Component
public class RequestTimingFilter implements WebFilter {
private static final Logger LOGGER = LoggerFactory.getLogger(RequestTimingFilter.class);
private final boolean logParameters;
@Autowired
RequestTimingFilter(@Value("${flags.log.parameters:false}") boolean logParameters) {
this.logParameters = logParameters;
}
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
long start = System.currentTimeMillis();
String path = exchange.getRequest().getPath().toString();
StringBuilder params = new StringBuilder();
if (this.logParameters) {
String pairs = exchange.getRequest().getQueryParams().toSingleValueMap()
.entrySet()
.stream()
.map(em -> String.format("%s=%s", em.getKey(), em.getValue()))
.collect(Collectors.joining(", "));
params.append(pairs.isEmpty() ? "" : ", ").append(pairs);
}
return chain.filter(exchange)
.doOnSuccess(v -> {
long endTime = System.currentTimeMillis();
if (LOGGER.isInfoEnabled()) {
LOGGER.info("tag={}, uri=\"{}\", time={}, unit=ms{}", "request-timing",
path, (endTime - start), params.toString());
}
});
}
}