java-中記錄用戶操作日志(方法入參&&結果出參)本地打印方便服務器中查看日志


package com.property.framework.aspectj;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.property.common.utils.ServletUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.StringJoiner;

/**
 * @className: OperLogAspect
 * @program: property-new-admin
 * @description:
 * @author: wangliangzhi
 * @create: 2022-02-17 17:17
 */
@Aspect
@Slf4j
@Component
public class OperLogAspect {
    /**
     * 開始時間
     */
    private ThreadLocal<Long> startTime = new ThreadLocal<>();
    /**
     * 日志記錄
     */
    private ThreadLocal<String> logApi = new ThreadLocal<>();


	// "execution(public * com.property.*.controller.*..*.*(..))" 這里換成你的接口地址
	// 也就是隨便找一個 controller 復制他的地址就可以了
    @Pointcut("execution(public * com.property.*.controller.*..*.*(..))")
    private void pointcut() {

    }

    @Before("pointcut()")
    private void beforeExeApi(JoinPoint joinPoint) {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (servletRequestAttributes != null) {
            HttpServletRequest request = servletRequestAttributes.getRequest();
            startTime.set(System.currentTimeMillis());
            // ip
            String ip = getRemoteHost(request);
            // 請求方式
            String httpMethod = request.getMethod();
            // url附帶的參數
            String urlParam = getUrlParam(request);
            // body 參數
            String bodyParam = "";
            if ("POST".equals(httpMethod)) {
                bodyParam = JSON.toJSONString(joinPoint.getArgs());
            }
            Signature signature = joinPoint.getSignature();
            // 方法名
            String methodName = signature.getName();
            // 目標類
            String targetClass = joinPoint.getTarget().getClass().getName();
            log.info("統一日志記錄: 操作IP:[{}], 請求方式:[{}], 接口地址:[{}], 請求地址:[{}], get請求參數:[{}], post請求參數:[{}]",
                    ip, httpMethod, targetClass, ServletUtils.getRequest().getRequestURI(), urlParam, bodyParam);
        }
    }

    /**
     * @Description 切入點方法執行之后執行,@AfterReturning是在一個Join Point(連接點)正常返回后執行的Advice(增強)
     * @Version 1.0
     */
    @AfterReturning(value = "pointcut()", returning = "returnValue")
    public void afterReturning(JoinPoint joinPoint, Object returnValue) {
        // ip
        String ip = getRemoteHost(ServletUtils.getRequest());
        // 方法名
        String methodName = ServletUtils.getRequest().getRequestURI();
        // 目標類
        String targetClass = joinPoint.getTarget().getClass().getName();
        try {
            String asString;
            long total = System.currentTimeMillis() - startTime.get();
            String logv = logApi.get();
            logv = StringUtils.join(logv, "統一日志記錄:操作IP:[" + ip + "], 接口地址:[" + targetClass + "], 請求地址:[" + methodName + "],總耗時:" + total + "ms", "\n");
            if (total < 5000L) {
                // 超過5秒 數據量大沒必要記錄日志
                ObjectMapper objectMapper = new ObjectMapper();
                if (null == returnValue) {
                    logv = StringUtils.join(logv, "返回結果:", "\n");
                } else if (returnValue instanceof ResponseEntity) {
                    asString = objectMapper.writeValueAsString(((ResponseEntity) returnValue).getBody());

                    logv = StringUtils.join(logv, "返回結果:" + (asString.length() > 5000 ? "數據量過大不打印結果" : asString), "\n");
                } else {
                    asString = objectMapper.writeValueAsString(returnValue);
                    logv = StringUtils.join(logv, "返回結果:" + (asString.length() > 5000 ? "數據量過大不打印結果" : asString), "\n");
                }
            } else {
                logv = StringUtils.join(logv, "耗時過長不打印結果");
            }
            logApi.set(logv);
            log.info(logApi.get());
        } catch (Exception e) {
            log.error(e.toString());
        } finally {
            // 釋放資源
            logApi.remove();
            startTime.remove();
        }
    }


    private String getUrlParam(HttpServletRequest request) {
        Map<String, String[]> parameterMap = request.getParameterMap();
        StringBuilder paramKv = new StringBuilder();
        StringJoiner urlParam = new StringJoiner(", ");
        for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
            for (String s : entry.getValue()) {
                paramKv.append(entry.getKey()).append("=").append(s);
            }
            urlParam.add(paramKv.toString());
            paramKv = new StringBuilder();
        }
        return urlParam.toString();
    }

    /**
     * 獲取目標主機的ip
     *
     * @param request
     * @return
     */
    private String getRemoteHost(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
    }

}

文中用到的 ServletUtils

package com.property.common.utils;

import com.property.common.constant.FileConstants;
import com.property.common.core.text.Convert;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * 客戶端工具類
 *
 * @author wangliangzhi
 */
public class ServletUtils {
    /**
     * 獲取String參數
     */
    public static String getParameter(String name) {
        return getRequest().getParameter(name);
    }

    /**
     * 獲取String參數
     */
    public static String getParameter(String name, String defaultValue) {
        return Convert.toStr(getRequest().getParameter(name), defaultValue);
    }

    /**
     * 獲取Integer參數
     */
    public static Integer getParameterToInt(String name) {
        return Convert.toInt(getRequest().getParameter(name));
    }

    /**
     * 獲取Integer參數
     */
    public static Integer getParameterToInt(String name, Integer defaultValue) {
        return Convert.toInt(getRequest().getParameter(name), defaultValue);
    }

    /**
     * 獲取request
     *
     * @return
     */
    public static HttpServletRequest getRequest() {
        return getRequestAttributes().getRequest();
    }

    /**
     * 獲取response
     */
    public static HttpServletResponse getResponse() {
        return getRequestAttributes().getResponse();
    }

    /**
     * 獲取session
     */
    public static HttpSession getSession() {
        return getRequest().getSession();
    }

    public static ServletRequestAttributes getRequestAttributes() {
        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
        return (ServletRequestAttributes) attributes;
    }

    /**
     * 將字符串渲染到客戶端
     *
     * @param response 渲染對象
     * @param string   待渲染的字符串
     * @return null
     */
    public static String renderString(HttpServletResponse response, String string) {
        try {
            response.setStatus(200);
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            response.getWriter().print(string);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 是否是Ajax異步請求
     *
     * @param request
     */
    public static boolean isAjaxRequest(HttpServletRequest request) {
        String accept = request.getHeader("accept");
        if (accept != null && accept.indexOf("application/json") != -1) {
            return true;
        }

        String xRequestedWith = request.getHeader("X-Requested-With");
        if (xRequestedWith != null && xRequestedWith.indexOf("XMLHttpRequest") != -1) {
            return true;
        }

        String uri = request.getRequestURI();
        if (StringUtils.inStringIgnoreCase(uri, FileConstants.JSON_SUFFIX, FileConstants.XML_SUFFIX)) {
            return true;
        }

        String ajax = request.getParameter("__ajax");
        if (StringUtils.inStringIgnoreCase(ajax, FileConstants.FILE_TYPE_JSON, FileConstants.FILE_TYPE_XML)) {
            return true;
        }
        return false;
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM