aspect记录access_detail日志

 

通过切面方式记录请求的req和res日志:

 

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>




package
com.autonavi.aos.share.aspect; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.autonavi.aos.share.common.util.Constants; import org.apache.commons.lang3.StringUtils; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import com.autonavi.aos.share.common.log.AccessDetailLog; import javax.servlet.http.HttpServletRequest; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; /** * 记录请求日志 * * @author zhangbaoshan * @date 19/12/30 */ @Aspect @Order(1) @Component public class AccessLogAspect extends AbstractPointcutDefinitions { private static final Logger LOGGER = LoggerFactory.getLogger(AccessLogAspect.class); /** * access_detail日志 */ private static final Logger ACCESS_DETAIL_LOGGER = LoggerFactory.getLogger("ACCESS_DETAIL_LOGGER"); private static final String PROCESS_START_TS_KEY = "_PROCESS_START_TS_KEY"; @Value("${client.ip.proxy.header}") private String ipProxyHeader; @Around("controller()") public Object aroundMethodInvoke(ProceedingJoinPoint pjp) throws Throwable { Object[] args = pjp.getArgs(); Map<String, Object> inAspectArgs = new HashMap<>(); this.beforeMethodInvoke(args, inAspectArgs); Object retVal = null; try { retVal = pjp.proceed(); } catch (Throwable t) { throw t; } return this.afterMethodInvoke(args, inAspectArgs, retVal); } protected void beforeMethodInvoke(Object[] args, Map<String, Object> inAspectArgs) { Long ts = System.currentTimeMillis(); inAspectArgs.put(PROCESS_START_TS_KEY, ts); } protected Object afterMethodInvoke(Object[] args, Map<String, Object> inAspectArgs, Object retVal) { HttpServletRequest request = getRequest(args); Long startTs = (Long) inAspectArgs.get(PROCESS_START_TS_KEY); if (request != null && startTs != null) { try { this.outputDetailLog(request, retVal, startTs); } catch (Exception e) { LOGGER.error("AccessLogAspect.afterMethodInvoke error", e); } } return retVal; } private void outputDetailLog(HttpServletRequest request, Object res, long startTs) { AccessDetailLog log = new AccessDetailLog(); log.setLocalName(Constants.HOSTNAME); log.setClientIP(getClientIP(request, ipProxyHeader)); log.setServerIP(Constants.LOCAL_IP); log.setUid(request.getParameter("uid")); log.setDiu(request.getParameter("diu")); log.setTid(request.getParameter("tid")); // 记录请求进入的时间 log.setTs(startTs); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); log.setTsf(sf.format(new Date(startTs))); long endTs = System.currentTimeMillis(); int resMillis = (int) (endTs - startTs); log.setResMillis(resMillis); //请求参数 JSONObject reqObj = new JSONObject(); reqObj.put("method", request.getMethod()); reqObj.put("protocol", request.getProtocol()); reqObj.put("path", request.getServletPath() + request.getPathInfo()); reqObj.put("header", parseRequestHeaders(request)); reqObj.put("params", getParamMap(request)); log.setReq(reqObj); //设置返回结果 log.setRes(res); ACCESS_DETAIL_LOGGER.info(JSON.toJSONString(log)); } protected HttpServletRequest getRequest(Object[] args) { HttpServletRequest request = null; if (args != null) { for (Object arg : args) { if (arg instanceof HttpServletRequest) { request = (HttpServletRequest) arg; break; } } } return request; } private static Map<String, String> getParamMap(HttpServletRequest request) { Map<String, String> paramMap = new HashMap<>(16); Enumeration em = request.getParameterNames(); while (em.hasMoreElements()) { String name = (String) em.nextElement(); String value = request.getParameter(name); paramMap.put(name, value); } return paramMap; } public static String getClientIP(HttpServletRequest request, String ipProxyHeader) { String forwardInfo = request.getHeader(ipProxyHeader); if (forwardInfo == null) { return request.getRemoteAddr(); } String[] proxys = forwardInfo.split("\\,"); // 经过多次代理,则取第一个IP为原始IP String ip = proxys[0]; return ip == null ? request.getRemoteAddr() : ip.trim(); } private Map<String, String> parseRequestHeaders(HttpServletRequest request) { Map<String, String> reqHeaders = new HashMap<>(); Enumeration<String> headerNames = request.getHeaderNames(); if (headerNames != null) { while (headerNames.hasMoreElements()) { String headerName = headerNames.nextElement(); StringBuilder sb = new StringBuilder(); String currentValue = reqHeaders.get(headerName); if (StringUtils.isNotBlank(currentValue)) { sb.append(currentValue); } Enumeration<String> headerValues = request.getHeaders(headerName); if (headerValues != null) { while (headerValues.hasMoreElements()) { String headerValue = headerValues.nextElement(); if (sb.length() == 0) { sb.append(headerValue); } else { sb.append(", " + headerValue); } } } reqHeaders.put(headerName, sb.toString()); } } return reqHeaders; } }
AbstractPointcutDefinitions:
package com.autonavi.aos.share.aspect;

import org.aspectj.lang.annotation.Pointcut;

/**
 * 定义切面
 *
 * @author zhangbaoshan
 * @date 19/12/30
 */
public abstract class AbstractPointcutDefinitions {

    /**
     * controller入口Pointcut
     */
    @Pointcut("execution(public * com.autonavi.aos.share.controller.*.*(..))")
    protected void controller() {
    }

}
AccessDetailLog:
package com.autonavi.aos.share.common.log;

import lombok.Getter;
import lombok.Setter;

import java.util.Map;

/**
 * access日志
 *
 * @author zhangbaoshan
 * @date 19/12/28
 */
@Setter
@Getter
public class AccessDetailLog {

    private String localName;

    private String clientIP;

    private String serverIP;

    private int resMillis;

    private String uid;

    private String diu;

    private String tid;

    private long ts;

    private String tsf;

    private Object req;

    private Object res;

    private Map<String, Object> ext;

}
posted @ 2020-01-08 18:33  大米粒汪汪叫  阅读(258)  评论(0编辑  收藏  举报