package com.huaheng.framework.aspectj; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.huaheng.common.utils.ServletUtils; import com.huaheng.common.utils.StringUtils; import com.huaheng.framework.aspectj.lang.annotation.ApiLogger; import com.huaheng.framework.web.domain.AjaxResult; import com.huaheng.pc.config.address.domain.Address; import com.huaheng.pc.config.address.service.AddressService; import com.huaheng.pc.monitor.apilog.domain.ApiLog; import com.huaheng.pc.monitor.apilog.service.IApiLogService; import org.apache.commons.lang.exception.ExceptionUtils; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.net.HttpURLConnection; import java.net.URL; import java.util.*; /** * Api调用日志记录处理 * * @author huaheng */ @Aspect @Component //@EnableAsync public class ApiLogAspect { private static final Logger log = LoggerFactory.getLogger(ApiLogAspect.class); private static IApiLogService apiLogService; private static AddressService addressService; @Autowired public void setApiLogService(IApiLogService apiLogService){ ApiLogAspect.apiLogService = apiLogService; } @Autowired public void setAddressService(AddressService addressService){ ApiLogAspect.addressService = addressService; } // 配置织入点 @Pointcut("@annotation(com.huaheng.framework.aspectj.lang.annotation.ApiLogger)") public void logPointCut() { } @Around("logPointCut() && @annotation(apiLogger)") public Object around(ProceedingJoinPoint point, ApiLogger apiLogger) throws Throwable { if("WMS".equalsIgnoreCase(apiLogger.from())) //实际上静态方法上的Aop注解无法拦截到 return aroundWms2XXX(point, apiLogger); else return aroundXXX2Wms(point, apiLogger); } /**处理xxx调用wms接口的日志**/ private Object aroundXXX2Wms(ProceedingJoinPoint point, ApiLogger apiLogger){ Object ret = null; ApiLog log = initApiLog(apiLogger, point); try{ ret = point.proceed(); }catch (Exception e){ setApiLogException(log, e); throw e; }finally{ finishApiLog(log, ret); return ret; } } /**处理WMS调用xxx接口的日志**/ private Object aroundWms2XXX(ProceedingJoinPoint point, ApiLogger apiLogger){ Object ret = null; ApiLog log = new ApiLog(); HttpURLConnection connection = null; String body = null; try { connection = (HttpURLConnection) point.getArgs()[0]; body = (String) point.getArgs()[1]; initApiLog(connection, body); }catch (Exception e){ } try{ ret = point.proceed(); }catch (Exception e){ setApiLogException(log, e); throw e; }finally{ finishApiLog(log, connection, ret.toString()); return ret; } } /**记录WMS调用外接口的请求信息 * 在HttpUtils.bodypost方法中直接调用本类static方法**/ public static ApiLog initApiLog(HttpURLConnection connection, String body){ ApiLog log = new ApiLog(); try { log.setApiMethod(connection.getRequestMethod()); log.setUrl(connection.getURL().toString()); log.setRequestTime(new Date()); parseUrl(log, connection.getURL()); //请求头 Set<String> keySet = connection.getRequestProperties().keySet(); ArrayList<String> headerList = new ArrayList<>(); Iterator<String> it = keySet.iterator(); while (it.hasNext()) { String name = it.next(); String header = connection.getRequestProperty(name); headerList.add(name + ": " + header); } log.setRequestHeader(org.apache.commons.lang3.StringUtils.join(headerList, "\n")); log.setRequestBody(body); }catch (Exception e){ e.printStackTrace(); } return log; } /**根据url,从address表中判断调用的去向**/ public static void parseUrl(ApiLog log, URL url){ try { String[] spList = url.toString().split("/"); String apiName = spList[spList.length - 1]; int index = url.toString().lastIndexOf(apiName); String addUrl = url.toString().substring(0, index); Address address = addressService.getAddressByUrl(addUrl); log.setApiName(apiName); log.setRequestFrom("WMS"); log.setResponseBy(address.getParam().toUpperCase()); }catch (Exception e){ e.printStackTrace(); } } /**记录响应头信息**/ public static void finishApiLog(ApiLog log, HttpURLConnection connection, String body){ try { log.setResponseBody(body); log.setResponseTime(new Date()); Long duration = log.getResponseTime().getTime() - log.getRequestTime().getTime(); log.setDuration(duration.intValue()); log.setHttpCode(String.valueOf(connection.getResponseCode())); //响应头 Set<String> keyset = connection.getHeaderFields().keySet(); ArrayList<String> headerList = new ArrayList<>(); Iterator<String> it = keyset.iterator(); while(it.hasNext()){ String name = it.next(); String header = connection.getHeaderField(name); headerList.add(name + ": " + header); } log.setResponseHeader(org.apache.commons.lang3.StringUtils.join(headerList, "\n")); AjaxResult json = JSON.parseObject(body, AjaxResult.class); log.setHttpCode(String.valueOf(json.getCode())); }catch (Exception e){ e.printStackTrace(); }finally { saveApiLog(log); } } private ApiLog initApiLog(ApiLogger apiLogger, ProceedingJoinPoint point){ ApiLog log = new ApiLog(); try{ log.setRequestTime(new Date()); log.setRequestFrom(apiLogger.from()); log.setResponseBy(apiLogger.to()); log.setApiName(apiLogger.apiName()); HttpServletRequest request = ServletUtils.getRequest(); String qryStr = request.getQueryString(); String url = request.getRequestURL().toString(); if(StringUtils.isNotEmpty(qryStr)) url = url + "?" + qryStr; log.setUrl(url); log.setApiMethod(request.getMethod()); log.setIp(request.getRemoteAddr()); rebuildRequestHeader(log); rebuildRequestBody(log, request); //如果reqeust中取不到post参数,就从接口方法参数中取json对象 if(StringUtils.isEmpty(log.getRequestBody())) rebuildRequestBody(log, point); }catch (Exception e){ e.printStackTrace(); } return log; } private void finishApiLog(ApiLog log, Object ret){ try { rebuildResponseHeader(log); rebuildResponseBody(log, ret); log.setResponseTime(new Date()); Long duration = log.getResponseTime().getTime() - log.getRequestTime().getTime(); log.setDuration(duration.intValue()); HttpServletResponse resp = ServletUtils.getResponse(); log.setHttpCode(String.valueOf(resp.getStatus())); if (ret instanceof AjaxResult) { int retCode = ((AjaxResult) ret).getCode(); log.setRetCode(String.valueOf(retCode)); } }catch (Exception e){ e.printStackTrace(); }finally { saveApiLog(log); } } public static void setApiLogException(ApiLog log, Exception e){ try { String exception = ExceptionUtils.getFullStackTrace(e); String shortExpInfo = e.getMessage() + "\n" + org.apache.commons.lang3.StringUtils.left(exception, 1000); log.setException(shortExpInfo); }catch (Exception ex){ ex.printStackTrace(); } } private void rebuildRequestHeader(ApiLog log){ try { HttpServletRequest req = ServletUtils.getRequest(); Enumeration names = req.getHeaderNames(); ArrayList<String> headerList = new ArrayList<>(); while(names.hasMoreElements()){ String name = (String)names.nextElement(); String header = req.getHeader(name); headerList.add(name + ": " + header); } String headers = org.apache.commons.lang3.StringUtils.join(headerList, "\n"); log.setRequestHeader(headers); }catch (Exception e){ e.printStackTrace(); } } /**先从post参数中构造request body*/ private void rebuildRequestBody(ApiLog log, HttpServletRequest request){ try{ Set<String> keySet = request.getParameterMap().keySet(); Iterator<String> it = keySet.iterator(); StringBuffer sbf = new StringBuffer(); while(it.hasNext()){ String key = it.next(); String value = request.getParameter(key); sbf.append(key).append("=").append(value); if(it.hasNext()) sbf.append("&"); } log.setRequestBody(sbf.toString()); }catch (Exception e){ e.printStackTrace(); } } /** * 根据接口中的参数构造request body */ private void rebuildRequestBody(ApiLog log, ProceedingJoinPoint point) { try { if (point.getArgs().length == 1) { log.setRequestBody(JSONObject.toJSONString(point.getArgs()[0])); return; } MethodSignature m = (MethodSignature) point.getSignature(); HashMap<String, Object> map = new HashMap<>(); Object[] args = point.getArgs(); for (int i = 0; i < m.getParameterNames().length; i++) { String name = m.getParameterNames()[i]; // Class type = m.getParameterTypes()[i]; map.put(name, args[i]); } if(!map.isEmpty()) log.setRequestBody(JSONObject.toJSONString(map)); }catch (Exception e){ e.printStackTrace(); } } private void rebuildResponseHeader(ApiLog log){ try { HttpServletResponse resp = ServletUtils.getResponse(); Collection names = resp.getHeaderNames(); ArrayList<String> headerList = new ArrayList<>(); Iterator<String> it = names.iterator(); while(it.hasNext()){ String name = it.next(); String header = resp.getHeader(name); headerList.add(name + ": " + header); } String headers = org.apache.commons.lang3.StringUtils.join(headerList, "\n"); log.setResponseHeader(headers); }catch (Exception e){ e.printStackTrace(); } } private void rebuildResponseBody(ApiLog log, Object ret){ try { log.setResponseBody(JSONObject.toJSON(ret).toString()); }catch (Exception e){ e.printStackTrace(); } } public static void saveApiLog(ApiLog log){ try{ apiLogService.saveOrUpdate(log); }catch (Exception e){ e.printStackTrace(); } } }