springboot 打印http请求和处理系统异常日志
@Configuration
public class YuncaiRequestLoggingFilter {
private static final int MAX_PAYLOAD_LENGTH = 10000;
@Autowired
private CustomServletContextRequestLoggingFilter customServletContextRequestLoggingFilter;
@Bean
public ServletContextRequestLoggingFilter requestLoggingFilter() {
ServletContextRequestLoggingFilter loggingFilter = customServletContextRequestLoggingFilter;
loggingFilter.setIncludeClientInfo(true);
loggingFilter.setIncludeQueryString(true);
loggingFilter.setIncludePayload(true);
loggingFilter.setIncludeHeaders(true);
loggingFilter.setMaxPayloadLength(MAX_PAYLOAD_LENGTH);
return loggingFilter;
}
}
@Slf4j
@Component
public class CustomServletContextRequestLoggingFilter extends ServletContextRequestLoggingFilter {
@Autowired
private EmailLogService emailLogService;
private void sendLogEmail(String exceptionMessage, String requestMessage) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Timestamp: ").append(System.currentTimeMillis()).append("\n").append("Time: ")
.append(LocalDateTime.now().toString()).append("\n").append("Thread Id: ")
.append(Thread.currentThread().getId()).append("\n").append("Thread Name: ")
.append(Thread.currentThread().getName()).append("\n").append("Request: \n").append(requestMessage)
.append("\n").append("Exception: \n").append(exceptionMessage).append("\n");
emailLogService.sendMail(stringBuilder.toString());
}
@Override
protected void afterRequest(HttpServletRequest request, String message) {
super.afterRequest(request, message);
if (ExceptionContext.getExceptionMessage() != null) {
try {
// ExceptionMessage exceptionMessage = new ExceptionMessage();
// //TODO 异常消息发送
// exceptionSendComponent.sendExceptionMessage(exceptionMessage);
sendLogEmail(ExceptionContext.getExceptionMessage(), message);
ExceptionContext.destroy();
} catch (Exception e) {
log.error("error", e);
}
}
}
}
2018-04-26 15:14:57.952 INFO 1464 --- [http-nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : After request [uri=/scan?code=111111111&uid=111111111&userId=1&payType=0;client=0:0:0:0:0:0:0:1;headers={host=[localhost:8080], connection=[keep-alive], accept=[*/*], user-agent=[Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36], privatetenantcode=[zyd], referer=[http://localhost:8080/swagger-ui.html], accept-encoding=[gzip, deflate, br], accept-language=[zh-CN,zh;q=0.9,en;q=0.8]}]
AbstractRequestLoggingFilter类定义了两个方法beforeRequest和afterRequest分别用于设定过滤前后执行的操作,它有三个子类,分别是CommonsRequestLoggingFilter、ServletContextRequestLoggingFilter和Log4jNestedDiagnosticContextFilter,这三个子类分别实现了各自的beforeRequest和afterRequest。其中,CommonsRequestLoggingFilter在过滤前后分别打印出一段debug的信息;ServletContextRequestLoggingFilter在过滤前后分别向日志文件中写入一段日志信息,日志文件可由log4j.properties等指定;Log4jNestedDiagnosticContextFilter则将日志信息存储到NDC中,NDC采用了一个类似栈的机制来push和pot上下文信息,每一个线程都独立地储存上下文信息,比如说一个servlet就可以针对 每一个request创建对应的NDC,储存客户端地址等信息。