package com.nanjing.water.host.api; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import com.nanjing.water.common.enums.ELogger; import com.nanjing.water.common.util.*; import com.nanjing.water.common.util.LocalDateTimeUtil; import com.nanjing.water.common.util.LoggerUtil; import com.nanjing.water.common.util.SerializeUtil; import com.nanjing.water.common.util.StringUtil; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.AfterReturning; 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.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; /** * 统一日志处理切面 * Created by macro on 2018/4/26. */ @Aspect @Component @Order(1) public class WebLogAspect { private static final Logger logger = LoggerUtil.get(ELogger.API_REQUEST); private static final Logger sysLogger = LoggerUtil.get(ELogger.SYS_ERROR); /** * 100毫秒 */ private static final long MS_100 = 100; /** * 2秒 */ private static final long SEC_1 = 1000; /** * 2秒 */ private static final long SEC_2 = 2 * 1000; /** * 10秒 */ private static final long SEC_10 = 10 * 1000; /** * 1分钟 */ private static final long MINS_1 = 60 * 1000; /** * 5分钟 */ private static final long MINS_5 = 5 * 60 * 1000; @Pointcut( "execution(public * com.lunhan.*.host.controller.*.*(..))" + "||execution(public * com.lunhan.*.host.admin.*.*(..))" + "||execution(public * com.lunhan.*.host.customer.*.*(..))" ) public void webLog() { } @Before("webLog()") public void doBefore(JoinPoint joinPoint) { } @AfterReturning(value = "webLog()", returning = "ret") public void doAfterReturning(Object ret) { } @Around("webLog()") public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable { long startTime = System.currentTimeMillis(); //获取当前请求对象 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); //记录请求信息(通过Logstash传入Elasticsearch) ApiRequestLogDTO webLog = HttpRequestLogPool.getRequestInfo(); Object result = joinPoint.proceed(); Signature signature = joinPoint.getSignature(); MethodSignature methodSignature = (MethodSignature) signature; Method method = methodSignature.getMethod(); // if (method.isAnnotationPresent(ApiOperation.class)) { // ApiOperation log = method.getAnnotation(ApiOperation.class); // webLog.setDescription(log.value()); // } String desc; switch (webLog.getMethod()) { case "POST": desc = method.getAnnotation(PostMapping.class).name(); break; case "GET": desc = method.getAnnotation(GetMapping.class).name(); break; case "PUT": desc = method.getAnnotation(PutMapping.class).name(); break; case "Delete": desc = method.getAnnotation(DeleteMapping.class).name(); break; default: desc = ""; break; } webLog.setDesc(desc); Long endTime = LocalDateTimeUtil.nowTimeStamp(); webLog.setResponseTime(endTime); webLog.setRequestData(SerializeUtil.toJson(getParameter(method, joinPoint.getArgs()))); webLog.setResponseData(SerializeUtil.toJson(result)); webLog.setSpendTime((endTime - startTime)); String usedTimesLevel; if (webLog.getSpendTime() > MINS_5) {//大于5分钟 usedTimesLevel = "F"; } else if (webLog.getSpendTime() > MINS_1) {//1 - 5分钟 usedTimesLevel = "E"; } else if (webLog.getSpendTime() > SEC_10) {//10秒 - 1分钟 usedTimesLevel = "D"; } else if (webLog.getSpendTime() > SEC_2) {//2秒 - 10秒 usedTimesLevel = "C"; } else if (webLog.getSpendTime() > SEC_1) {//1秒 - 2秒 usedTimesLevel = "B"; } else if (webLog.getSpendTime() > MS_100) {//100毫秒 - 1秒 usedTimesLevel = "A"; } else {//100毫秒以内 usedTimesLevel = "SSS"; } List listTag = new ArrayList<>(); listTag.add("url=" + webLog.getPath()); listTag.add("method=" + webLog.getMethod()); listTag.add("spendTime=" + webLog.getSpendTime()); listTag.add("description=" + webLog.getDesc()); listTag.add("tokenCode=" + webLog.getRequestToken()); listTag.add("usedTimesLevel=" + usedTimesLevel); String log = String.format("[%s]" + "%nrequestPath: %s[%s]" + "%nreponseData: %s" + "%nrequestTime: %s" + "%nresponseTime: %s" + "%nspendTime: %s" + "%nmethod: %s" + "%nrequestIp: %s" + "%ntokenCode: %s" + "%nrequestData: %s", StringUtil.join(listTag, "],["), webLog.getPath(), webLog.getDesc(), webLog.getResponseData(), LocalDateTimeUtil.toFormatFullString(webLog.getRequestTime()), LocalDateTimeUtil.toFormatFullString(webLog.getResponseTime()), webLog.getSpendTime(), webLog.getMethod(), webLog.getRequestIP(), webLog.getRequestToken(), webLog.getRequestData() ); logger.info(log); return result; } /** * 根据方法和传入的参数获取请求参数 */ private Object getParameter(Method method, Object[] args) { List argList = new ArrayList<>(); Parameter[] parameters = method.getParameters(); for (int i = 0; i < parameters.length; i++) { //将RequestBody注解修饰的参数作为请求参数 RequestBody requestBody = parameters[i].getAnnotation(RequestBody.class); if (requestBody != null) { argList.add(args[i]); } //将RequestParam注解修饰的参数作为请求参数 RequestParam requestParam = parameters[i].getAnnotation(RequestParam.class); if (requestParam != null) { Map map = new HashMap<>(); String key = parameters[i].getName(); if (!StringUtils.isEmpty(requestParam.value())) { key = requestParam.value(); } map.put(key, args[i]); argList.add(map); } } if (argList.size() == 0) { return null; } else if (argList.size() == 1) { return argList.get(0); } else { return argList; } } }