package cn.timer.api.aspect; import java.io.PrintWriter; import java.io.StringWriter; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Enumeration; import java.util.TimeZone; import javax.servlet.http.HttpServletRequest; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.core.annotation.Order; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import cn.timer.api.config.exception.CustomException; import lombok.extern.slf4j.Slf4j; /** * 拦截输出异常堆栈(改用fluentd方式) * * @author Rex.Tan * @date 2018年12月13日 上午9:18:58 */ @Slf4j @Aspect @Component @Order(999) public class RequestAop { @Pointcut("execution(* cn.timer..*.*Controller.*(..))") public void init() { } @Before("init()") public void beforeAdvice(JoinPoint joinPoint) { // 进入方法前拦截 } @Around("init()") public Object around(ProceedingJoinPoint pjp) { long startTime = System.currentTimeMillis(); HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); String url = request.getRequestURI(); /** * 输出url */ Object obj = null; String bodyArgs = this.bodyArgs2String(request, pjp.getArgs(), url); JSONObject urlArgs = this.urlArgs2String(request, request.getParameterNames(), url); try { obj = pjp.proceed(); long endTime = System.currentTimeMillis(); this.logInfo2Kafka(request, url, bodyArgs, urlArgs, "success", 0, endTime - startTime, true); } catch (Throwable e) { e.printStackTrace(); long endTime = System.currentTimeMillis(); if (e instanceof CustomException) { /** * 拦截到主动抛出的异常 */ CustomException ex = (CustomException) e; this.logInfo2Kafka(request, url, bodyArgs, urlArgs, ex.getMessage(), 400, endTime - startTime, false); throw ex; } else { /** * 拦截到未知异常 */ StringWriter stringWriter = new StringWriter(); e.printStackTrace(new PrintWriter(stringWriter)); this.logInfo2Kafka(request, url, bodyArgs, urlArgs, "未捕获异常: " + stringWriter.toString(), 500, endTime - startTime, false); throw new CustomException("未捕获异常," + e.getMessage()); } } finally { } return obj; } /** * 请录请求耗时 * * @author Rex.Tan * @date 2018年12月13日 下午2:51:31 * @param url 请求地址 * @param args requestBody中的参数 * @param args2 url中的参数 * @param message 消息 * @param status 接口调用返回状态 * @param executionTime 执行耗时 * @param isSuccess 是否调用成功 */ @Async public void logInfo2Kafka(HttpServletRequest request, String url, String bodyArgs, JSONObject urlArgs, String message, Integer status, long executionTime, boolean isSuccess) { JSONObject json = new JSONObject(); json.put("logType", "___rest___"); // if (UserContext.get() != null) { // json.put("userName", UserContext.get().getUsername()); // } json.put("url", url); json.put("timestamp", System.currentTimeMillis()); json.put("visitTime", now2String()); json.put("message", message); json.put("status", status); json.put("executionTime", executionTime); json.put("channel", request.getHeader("channel")); json.put("projectName", "8timer"); json.put("requestType", request.getMethod()); /** * 1.requestBody中的参数 */ json.put("bodyArgs", bodyArgs); /** * 2.url中的参数 */ json.put("urlArgs", urlArgs); /** * 3.如果请求状态不为0, 在控制台输入请求信息 */ if (status != 0) { log.error("\r\n" + json.toJSONString()); } else { log.info("\r\n" + json.toJSONString()); } } /** * 读取requestBody中的参数 * * @author Rex.Tan * @date 2018年12月13日 下午2:54:31 * @param bodyArgs * @param url * @return */ private String bodyArgs2String(HttpServletRequest request, Object[] bodyArgs, String url) { if ("GET".equals(request.getMethod())) { return ""; } if (url != null && url.indexOf("/upload")!=-1) { return ""; } if (url != null && url.indexOf("/image")!=-1) { return ""; } try { if (bodyArgs != null && bodyArgs.length > 0) { String body = JSONArray.toJSONString(bodyArgs); if (body.indexOf("/image")!=-1) { return ""; } return body; } } catch (Exception e) { log.error("=============序列化requestBody中的参数出错, " + url); } return ""; } /** * 读取url中的参数 * * @author Rex.Tan * @date 2019年9月12日 下午2:54:40 * @param request * @param urlArgs * @param url * @return */ private JSONObject urlArgs2String(HttpServletRequest request, Enumeration<String> urlArgs, String url) { JSONObject urlArgsJson = new JSONObject(); try { if (urlArgs != null) { while (urlArgs.hasMoreElements()) { try { String paraName = (String) urlArgs.nextElement(); urlArgsJson.put(paraName, request.getParameter(paraName)); } catch (Exception e) { log.error("=============记录url中的参数出错", url); break; } } } } catch (Exception e) { log.error("=============记录url中的参数出错, " + url); } return urlArgsJson; } private static String now2String() { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); Date now = new Date(); return sdf.format(now); } }