perf(log/httptrace-pro): 优化日志过滤器,仅在需要记录请求体、响应体时进行过滤

This commit is contained in:
2024-01-03 21:25:31 +08:00
parent eb290787ce
commit d68d88db21
3 changed files with 58 additions and 13 deletions

View File

@@ -45,11 +45,11 @@ import top.charles7c.continew.starter.log.httptracepro.handler.LogInterceptor;
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
public class LogAutoConfiguration implements WebMvcConfigurer {
private final LogProperties properties;
private final LogProperties logProperties;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LogInterceptor(logDao(), properties));
registry.addInterceptor(new LogInterceptor(logDao(), logProperties));
}
/**
@@ -58,7 +58,7 @@ public class LogAutoConfiguration implements WebMvcConfigurer {
@Bean
@ConditionalOnMissingBean
public LogFilter logFilter() {
return new LogFilter();
return new LogFilter(logProperties);
}
/**

View File

@@ -27,11 +27,14 @@ import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;
import org.springframework.web.util.WebUtils;
import top.charles7c.continew.starter.log.common.enums.Include;
import top.charles7c.continew.starter.log.httptracepro.autoconfigure.LogProperties;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Objects;
import java.util.Set;
/**
* 日志过滤器
@@ -47,6 +50,8 @@ import java.util.Objects;
@RequiredArgsConstructor
public class LogFilter extends OncePerRequestFilter implements Ordered {
private final LogProperties logProperties;
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE - 10;
@@ -59,18 +64,28 @@ public class LogFilter extends OncePerRequestFilter implements Ordered {
filterChain.doFilter(request, response);
return;
}
// 包装输入、输出流,可重复读取
if (!(request instanceof ContentCachingRequestWrapper)) {
// 包装输入流,可重复读取
if (isRequestWrapper(request)) {
request = new ContentCachingRequestWrapper(request);
}
if (!(response instanceof ContentCachingResponseWrapper)) {
// 包装输出流,可重复读取
boolean isResponseWrapper = isResponseWrapper(response);
if (isResponseWrapper) {
response = new ContentCachingResponseWrapper(response);
}
filterChain.doFilter(request, response);
// 更新响应(不操作这一步,会导致接口响应空白)
updateResponse(response);
if (isResponseWrapper) {
updateResponse(response);
}
}
/**
* 请求是否有效
*
* @param request 请求对象
* @return truefalse
*/
private boolean isRequestValid(HttpServletRequest request) {
try {
new URI(request.getRequestURL().toString());
@@ -80,6 +95,36 @@ public class LogFilter extends OncePerRequestFilter implements Ordered {
}
}
/**
* 是否需要包装输入流
*
* @param request 请求对象
* @return truefalse
*/
private boolean isRequestWrapper(HttpServletRequest request) {
Set<Include> includeSet = logProperties.getInclude();
return !(request instanceof ContentCachingRequestWrapper)
&& (includeSet.contains(Include.REQUEST_BODY) || includeSet.contains(Include.REQUEST_PARAM));
}
/**
* 是否需要包装输出流
*
* @param response 响应对象
* @return truefalse
*/
private boolean isResponseWrapper(HttpServletResponse response) {
Set<Include> includeSet = logProperties.getInclude();
return !(response instanceof ContentCachingResponseWrapper)
&& (includeSet.contains(Include.RESPONSE_BODY) || includeSet.contains(Include.RESPONSE_PARAM));
}
/**
* 更新响应
*
* @param response 响应对象
* @throws IOException /
*/
private void updateResponse(HttpServletResponse response) throws IOException {
ContentCachingResponseWrapper responseWrapper =
WebUtils.getNativeResponse(response, ContentCachingResponseWrapper.class);

View File

@@ -49,8 +49,8 @@ import java.util.Set;
@RequiredArgsConstructor
public class LogInterceptor implements HandlerInterceptor {
private final LogDao dao;
private final LogProperties properties;
private final LogDao logDao;
private final LogProperties logProperties;
private final TransmittableThreadLocal<LogRecord.Started> timestampTtl = new TransmittableThreadLocal<>();
@Override
@@ -58,7 +58,7 @@ public class LogInterceptor implements HandlerInterceptor {
@NonNull Object handler) {
Clock timestamp = Clock.systemUTC();
if (this.isRequestRecord(handler, request)) {
if (Boolean.TRUE.equals(properties.getIsPrint())) {
if (Boolean.TRUE.equals(logProperties.getIsPrint())) {
log.info("[{}] {}", request.getMethod(), request.getRequestURI());
}
LogRecord.Started startedLogRecord = LogRecord.start(timestamp, new RecordableServletHttpRequest(request));
@@ -75,7 +75,7 @@ public class LogInterceptor implements HandlerInterceptor {
return;
}
timestampTtl.remove();
Set<Include> includeSet = properties.getInclude();
Set<Include> includeSet = logProperties.getInclude();
try {
LogRecord finishedLogRecord = startedLogRecord.finish(new RecordableServletHttpResponse(response, response.getStatus()), includeSet);
HandlerMethod handlerMethod = (HandlerMethod) handler;
@@ -87,11 +87,11 @@ public class LogInterceptor implements HandlerInterceptor {
if (includeSet.contains(Include.MODULE)) {
this.logModule(finishedLogRecord, handlerMethod);
}
if (Boolean.TRUE.equals(properties.getIsPrint())) {
if (Boolean.TRUE.equals(logProperties.getIsPrint())) {
LogResponse logResponse = finishedLogRecord.getResponse();
log.info("[{}] {} {} {}ms", request.getMethod(), request.getRequestURI(), logResponse.getStatus(), finishedLogRecord.getTimeTaken().toMillis());
}
dao.add(finishedLogRecord);
logDao.add(finishedLogRecord);
} catch (Exception ex) {
log.error("Logging http log occurred an error: {}.", ex.getMessage(), ex);
}