需求:打印系统的controller的请求日志和返回结果,以及接口耗时,方便后续排查问题;
可以使用filter来做,也可以使用切面,倾向于使用切面;
代码如下:
@Aspect @Component public class WebLogAspect { private static final Logger logger = LoggerFactory.getLogger(WebLogAspect.class); /** * 请求参数/返回结果的日志打印最大长度 */ private final static int RESPONSE_LOG_MAX_LENGTH = 2000; /** * 以 iface 包下定义的所有请求为切入点 */ @Pointcut("(@within(org.springframework.stereotype.Controller) || @within(org.springframework.web.bind.annotation.RestController))" + "&& within(com.xxx.*)"+ " &&! @annotation(org.springframework.scheduling.annotation.Async) ") public void webLog() { } /** * 在切点之前织入 * * @param joinPoint * @throws Throwable */ @Before("webLog()") public void doBefore(JoinPoint joinPoint) throws Throwable { // 开始打印请求日志 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); StringBuilder responseContext = !ObjectUtils.isEmpty(joinPoint.getArgs()) ? new StringBuilder(JsonUtil.parseObjToJsonStr(joinPoint.getArgs())) : new StringBuilder(Strings.EMPTY); // 打印请求相关参数 logger.info("request URL:{}, Class Method:{}.{}, IP:{}, Args:{}", request.getRequestURL().toString() , joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName(), request.getRemoteAddr(), checkLengthAndCut(responseContext)); } /** * 在切点之后织入 * * @throws Throwable */ @After("webLog()") public void doAfter() throws Throwable { } /** * 环绕 * * @param proceedingJoinPoint * @return * @throws Throwable */ @Around("webLog()") public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { long startTime = System.currentTimeMillis(); Object result = proceedingJoinPoint.proceed(); if (result != null) { StringBuilder stringBuilder = new StringBuilder(JsonUtil.parseObjToJsonStr(result)); long timeSpend = System.currentTimeMillis() - startTime; logger.info("Response Time-Consuming:{} ms,content : {}", timeSpend, checkLengthAndCut(stringBuilder)); } return result; } /** * 判断长度并截取 * * @param stringBuilder * @return */ private String checkLengthAndCut(StringBuilder stringBuilder) { if (Objects.isNull(stringBuilder)) { return Strings.EMPTY; } if (stringBuilder.length() > RESPONSE_LOG_MAX_LENGTH) { return stringBuilder.substring(0, RESPONSE_LOG_MAX_LENGTH); } else { return stringBuilder.toString(); } }