在日常的开发中,日志往往是我们用来排查问题的重要依据,请求和响应也是其中重要的组成部分。也看到了很多业务系统记录日志的方式:
今天带来的方式是基于 springboot 自带的请求缓存 ContentCachingRequestWrapper 和响应缓存 ContentCachingResponseWrapper 实现日志的详细记录,避免重复造轮子。
@Slf4j
public class ContentCachingFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
// 包装请求和响应
ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request);
ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response);
try {
// 执行过滤器链
filterChain.doFilter(requestWrapper, responseWrapper);
} finally {
// 从包装器中获取缓存的内容
String method = request.getMethod();
String requestString;
if (StringUtils.equals(method, "GET")) {
requestString = JSON.toJSONString(requestWrapper.getParameterMap());
} else {
requestString = new String(requestWrapper.getContentAsByteArray(),
request.getCharacterEncoding());
}
byte[] responseBody = responseWrapper.getContentAsByteArray();
String responseBodyString = new String(responseBody, response.getCharacterEncoding());
log.info("RequestUri:{}, Method:{}, Request: {}, Response: {}", request.getRequestURI(),
method, requestString, responseBodyString);
// 确保响应被写回客户
responseWrapper.copyBodyToResponse();
}
}
}
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<ContentCachingFilter> loggingFilter() {
FilterRegistrationBean<ContentCachingFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new ContentCachingFilter());
registrationBean.addUrlPatterns("/*");
return registrationBean;
}
}
最终的实现效果如下:
RequestUri:/api/test, Method:GET, Request: {"name":["AA"]}, Response: 47d39ffa-1b17-4aef-bbc2-0673b89883d0-AA
RequestUri:/api/test, Method:GET, Request: {}, Response: 59fe2ab5-4cac-4e1f-9e1b-88c95f7ba952-null
RequestUri:/script/execute, Method:POST, Request: {
"scriptContent": "xxxxx"
}, Response: {"success":false,"errorCode":"SYSTEM_ERROR","errorMsg":"xxx","needRetry":false}
可以看到请求响应都被完整的记录了。这种实现就是足够的简单、高效,对于业务代码的侵入性小。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。