public static ResponseDetailsLogger with(Object responseBody) { return new ResponseDetailsLogger(responseBody); }
/** * 创建通用的日志输出模式并绑定线程 * * @return 日志模型 */ private RequestDetailsLogger generateJsonRequestDetails() { RequestDetailsLogger logDetails = (RequestDetailsLogger) ServletContextHolder.getRequest().getAttribute(RequestAttributeConst.DETAILS_KEY); if (logDetails == null) { logDetails = new RequestDetailsLogger(); ServletContextHolder.getRequest().setAttribute(RequestAttributeConst.DETAILS_KEY, logDetails); } return logDetails; }
@Override public void handleError(ClientHttpResponse response) throws IOException { LOGGER.info("request id '{}' error response '{}'", ServletContextHolder.fetchRequestId(), response); } }
@Before(value = "within(com.github.prontera..*) " + "&& (@annotation(org.springframework.web.bind.annotation.ResponseBody)" + "|| @annotation(org.springframework.web.bind.annotation.RequestMapping))") public void before(JoinPoint joinPoint) { final String requestId = ServletContextHolder.fetchRequestId(); final HttpServletResponse response = ServletContextHolder.getResponse(); if (response.getHeader(RequestAttributeConst.REQUEST_ID) == null) { response.addHeader(RequestAttributeConst.REQUEST_ID, requestId); } }
@Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { ResettableStreamHttpServletRequest wrapperRequest = new ResettableStreamHttpServletRequest(request); byte[] body = wrapperRequest.getRequestBody(); if (body != null) { ServletContextHolder.getRequest().setAttribute(RequestAttributeConst.REQUEST_BODY_KEY, new String(body, Charsets.UTF_8)); } super.doFilter(wrapperRequest, response, filterChain); }
@Around(value = "within(com.github.prontera..*) " + "&& (@annotation(org.springframework.web.bind.annotation.ResponseBody)" + "|| @annotation(org.springframework.web.bind.annotation.RequestMapping)) " + "&& @annotation(com.github.prontera.RequestLogging)") public Object aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable { // 生成请求日志 RequestDetailsLogger requestLog = generateJsonRequestDetails(); // 获取Swagger上的API描述 injectApiOperationDescription(joinPoint, requestLog); // 执行真实请求 final Object proceed = joinPoint.proceed(); // 当响应完成时, 打印完整的'request & response'信息 requestLog.setResponseTime(OffsetDateTime.now()); LOGGER.debug("RequestLoggingAspect#\r\nREQUEST->\r\n{}\r\nRESPONSE->\r\n {}", requestLog, ResponseDetailsLogger.with(proceed)); // 放行 return proceed; }
public static String fetchRequestId() { String requestId = (String) getRequest().getAttribute(RequestAttributeConst.REQUEST_ID); if (requestId == null) { requestId = Optional.ofNullable(getRequest().getHeader(RequestAttributeConst.REQUEST_ID)).orElse("x-" + UUID.randomUUID()); getRequest().setAttribute(RequestAttributeConst.REQUEST_ID, requestId); } return requestId; } }
private void injectApiOperationDescription(ProceedingJoinPoint joinPoint, RequestDetailsLogger logDetails) { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); final ApiOperation operate = method.getAnnotation(ApiOperation.class); if (operate != null) { logDetails.setApiDesc(operate.value()); } }
/** * 获取错误的字段名, 如果被{@link JsonProperty}修饰则优先选择 * * @see JsonProperty */ private static String acquireFieldName(BindingResult result, FieldError fieldError) { Preconditions.checkNotNull(result); Preconditions.checkNotNull(fieldError); // 获取错误字段名 String errorFieldName = fieldError.getField(); // 获取校验非法的类 Class<?> clazz = result.getTarget().getClass(); final Field field; try { // 获取其字段名 field = clazz.getDeclaredField(fieldError.getField()); final JsonProperty annotation = field.getAnnotation(JsonProperty.class); // 若JsonProperty里value()不为null则覆盖该值 if (annotation != null) { errorFieldName = annotation.value(); } } catch (NoSuchFieldException e) { Throwables.throwIfUnchecked(e); LOGGER.error("request id: {}, 反射字段名时抛出异常: {}", ServletContextHolder.fetchRequestId(), e.getMessage()); } return errorFieldName; }
final String errorMessage = fieldError.getDefaultMessage(); LOGGER.debug("request id: {}, error field: {}, error msg: {}", ServletContextHolder.fetchRequestId(), errorFieldName, errorMessage); errorMap.put(errorFieldName, errorMessage);