Lon*_*don 38 java logging spring spring-mvc
你好我一直在试图找出在我的应用程序中记录http请求的通用方法,到目前为止没有运气,这是我现在如何处理日志记录,即:
@RequestMapping(value="register", method = RequestMethod.POST)
@ResponseBody
public String register(@RequestParam(value="param1",required=false) String param1, @RequestParam("param2") String param2, @RequestParam("param3") String param3, HttpServletRequest request){
long start = System.currentTimeMillis();
logger.info("!--REQUEST START--!");
logger.info("Request URL: " + request.getRequestURL().toString());
List<String> requestParameterNames = Collections.list((Enumeration<String>)request.getParameterNames());
logger.info("Parameter number: " + requestParameterNames.size());
for (String parameterName : requestParameterNames){
logger.info("Parameter name: " + parameterName + " - Parameter value: " + request.getParameter(parameterName));
}
//Some processing logic, call to the various services/methods with different parameters, response is always String(Json)
String response = service.callSomeServiceMethods(param1,param2,param3);
logger.info("Response is: " + response);
long end = System.currentTimeMillis();
logger.info("Requested completed in: " + (end-start) + "ms");
logger.info("!--REQUEST END--!");
return response;
}
Run Code Online (Sandbox Code Playgroud)
所以我现在对不同的控制器/方法所做的就是从方法内部的开头复制所有内容,直到处理逻辑从方法到方法不同,然后复制下面的所有内容,如上面模板所示.
它有点乱,并且有很多代码重复(我不喜欢).但我需要记录所有内容.
有没有人对这种日志记录有更多的经验,谁能对此有所了解?
Dav*_*mes 44
编辑:另外,请参阅@ membersound对此答案的评论,这改进了这个答案.
Spring支持这一点.请参阅CommonsRequestLoggingFilter.如果使用Spring Boot,只需注册该类型的bean,Boot就会将其应用于过滤器链.喜欢:
@Bean
public Filter logFilter() {
CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter();
filter.setIncludeQueryString(true);
filter.setIncludePayload(true);
filter.setMaxPayloadLength(5120);
return filter;
}
Run Code Online (Sandbox Code Playgroud)
此外,此日志记录筛选器要求将日志级别设置为DEBUG.例如,在logback.xml中执行以下操作:
<logger name="org.springframework.web.filter.CommonsRequestLoggingFilter" level="DEBUG"/>
Run Code Online (Sandbox Code Playgroud)
小智 7
读取请求的主要问题是,只要输入流被消耗,它就会消失...而且无法再次读取.因此必须缓存输入流.Spring没有为缓存编写自己的类(可以在Web上的几个地方找到),而是提供了一些有用的类,即ContentCachingRequestWrapper和ContentCachingResponseWrapper.可以非常有效地利用这些类,例如,用于记录目的的过滤器.
在web.xml中定义过滤器:
<filter>
<filter-name>loggingFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>loggingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Run Code Online (Sandbox Code Playgroud)
由于过滤器声明为DelegatingFilterProxy,因此可以使用@Component或@Bean注释将其声明为bean.在loggingFilter的doFilter方法中,在将请求和响应传递给过滤器链之前,使用spring提供的类包装请求和响应:
HttpServletRequest requestToCache = new ContentCachingRequestWrapper(request);
HttpServletResponse responseToCache = new ContentCachingResponseWrapper(response);
chain.doFilter(requestToCache, responseToCache);
String requestData = getRequestData(requestToCache);
String responseData = getResponseData(responseToCache);
Run Code Online (Sandbox Code Playgroud)
一旦输入流在chain.doFilter()之后被使用,输入流将被缓存在包装的请求中.然后可以访问如下:
public static String getRequestData(final HttpServletRequest request) throws UnsupportedEncodingException {
String payload = null;
ContentCachingRequestWrapper wrapper = WebUtils.getNativeRequest(request, ContentCachingRequestWrapper.class);
if (wrapper != null) {
byte[] buf = wrapper.getContentAsByteArray();
if (buf.length > 0) {
payload = new String(buf, 0, buf.length, wrapper.getCharacterEncoding());
}
}
return payload;
}
Run Code Online (Sandbox Code Playgroud)
但是,响应的情况有点不同.由于响应在传递给过滤器链之前也被包装,因此一旦在返回的路上写入,它也将被缓存到输出流.但由于输出流也将被消耗,因此您必须使用wrapper.copyBodyToResponse()将响应复制回输出流.见下文:
public static String getResponseData(final HttpServletResponse response) throws IOException {
String payload = null;
ContentCachingResponseWrapper wrapper =
WebUtils.getNativeResponse(response, ContentCachingResponseWrapper.class);
if (wrapper != null) {
byte[] buf = wrapper.getContentAsByteArray();
if (buf.length > 0) {
payload = new String(buf, 0, buf.length, wrapper.getCharacterEncoding());
wrapper.copyBodyToResponse();
}
}
return payload;
}
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你!
这是我写的一个小库,你可以使用:spring-mvc-logger
我通过maven central提供它:
<dependency>
<groupId>com.github.isrsal</groupId>
<artifactId>spring-mvc-logger</artifactId>
<version>0.2</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
48448 次 |
| 最近记录: |