在日志系统中打印请求信息是很有用的功能,在开发中可以方便调试,在生产中可以快速定位问题,同时这些日志信息可以同步给大数据系统进行数据挖掘与分析。
在Spring中实现打印请求日志很简单,直接使用CommonsRequestLoggingFilter就行了,但是这个filter有个问题就是不打印请求method(GET,POST等),像restful风格的接口都是通过method来区分接口的,还有就是无法定制信息,比如想打印用户名什么的也无法实现,这个时候就需要改造下了。
看spring源码我们发现这个类组装打印信息是createMessage方法,只要覆盖这个方法就行了。
static class MyRequestLoggingFilter extends CommonsRequestLoggingFilter {
@Override
protected String createMessage(HttpServletRequest request, String prefix, String suffix) {
StringBuilder msg = new StringBuilder();
msg.append(prefix);
msg.append(StrUtil.format("method={};", request.getMethod().toLowerCase()));
msg.append("uri=").append(request.getRequestURI());
if (isIncludeQueryString()) {
String queryString = request.getQueryString();
if (queryString != null) {
msg.append('?').append(queryString);
}
}
if (isIncludeClientInfo()) {
String client = request.getRemoteAddr();
if (StringUtils.hasLength(client)) {
msg.append(";client=").append(client);
}
HttpSession session = request.getSession(false);
if (session != null) {
msg.append(";session=").append(session.getId());
}
String user = request.getRemoteUser();
if (user != null) {
msg.append(";user=").append(user);
}
}
if (isIncludeHeaders()) {
msg.append(";headers=").append(new ServletServerHttpRequest(request).getHeaders());
}
if (isIncludePayload()) {
String payload = getMessagePayload(request);
if (payload != null) {
msg.append(";payload=").append(payload);
}
}
msg.append(suffix);
return msg.toString();
}
}
然后注册下这个过滤器就可以了
@Bean
public FilterRegistrationBean logFilterRegistration() {
CommonsRequestLoggingFilter filter = new MyRequestLoggingFilter();
filter.setIncludeQueryString(true);
filter.setIncludePayload(true);
filter.setIncludeClientInfo(true);
filter.setMaxPayloadLength(256);
FilterRegistrationBean registration = new FilterRegistrationBean(filter);
registration.addUrlPatterns("/*");
registration.setName("commonsRequestLoggingFilter");
return registration;
}
演示
2021-08-16 10:07:29:260|DEBUG| Before request [method=get;uri=/user/11;client=0:0:0:0:0:0:0:1] |com.wkt.config.filter.FilterConfig$MyRequestLoggingFilter:47 |http-nio-8087-exec-9
2021-08-16 10:07:29:270|DEBUG| Using 'application/json', given [*/*] and supported [application/json, application/*+json, application/json, application/*+json] |org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor:265 |http-nio-8087-exec-9
2021-08-16 10:07:29:270|DEBUG| Writing [Result{status=200, message='操作成功'}] |org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor:91 |http-nio-8087-exec-9
2021-08-16 10:07:29:273|DEBUG| After request [method=get;uri=/user/11;client=0:0:0:0:0:0:0:1] |com.wkt.config.filter.FilterConfig$MyRequestLoggingFilter:55 |http-nio-8087-exec-9
可以看到日志中把请求路径,请求参数,客户端ip,响应数据都打印出来了
参考项目(模块: SpringBoot-HelloWorld): https://gitee.com/huatin/java-test