• Controller 自动化日志输出


    Starter库

    1.定义注解

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface TraceLog {
        /**
         * 日志类型
         *
         * @return
         */
        String type() default "";
    }
    

    2.定义捕获日志接口方法

    public interface ITraceLogProcess {
    
        void afterThrowing(JoinPoint pjp, Throwable ex, Long beforeTime);
    
        void afterReturning(JoinPoint pjp, Object result, Long beforeTime);
    
        void before(JoinPoint pjp);
    }
    

    3.定义捕获日志方法实现

    @Slf4j
    public class TraceLogProcess implements ITraceLogProcess {
        private static String UNKNOWN_IP = "unknown";
    
        private static String X_FORWARDED_FOR = "x-forwarded-for";
    
        @Override
        public void afterThrowing(JoinPoint pjp, Throwable ex, Long beforeTime) {
            MethodSignature signature = (MethodSignature) pjp.getSignature();
            Method method = signature.getMethod();
            TraceLog traceLog = method.getAnnotation(TraceLog.class);
            Integer errorCode = ResultCode.UNKNOWN_CODE.getCode();
            String errorMsg = ResultCode.UNKNOWN_CODE.getDesc();
            if (ex instanceof ApiException) {
                errorCode = ((ApiException) ex).getResultCode();
                errorMsg = ex.getMessage();
            }
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
            log.info("[Tracelog failed] Call interface[{}] from IP[{}] return error," +
                            "URL:[{}], method name:[{}]," +
                            "method type:[{}], expend time(ms):[{}]," +
                            "input parameter:[{}]," +
                            "error code:[{}], error message:[{}]",
                    traceLog != null ? traceLog.type() : "", getIpAddr(request),
                    request.getRequestURL().toString(), signature.getName(),
                    request.getMethod(), System.currentTimeMillis() - beforeTime,
                    pjp.getArgs(), errorCode, errorMsg);
        }
    
        @Override
        public void afterReturning(JoinPoint pjp, Object result, Long beforeTime) {
            MethodSignature signature = (MethodSignature) pjp.getSignature();
            Method method = signature.getMethod();
            TraceLog traceLog = method.getAnnotation(TraceLog.class);
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
            log.info("[Tracelog success]Call interface[{}] from IP[{}]," +
                            "URL:[{}], method name:[{}]," +
                            "method type:[{}], expend time(ms):[{}]," +
                            "input parameter:[{}]," +
                            "result:[{}]",
                    traceLog != null ? traceLog.type() : "", getIpAddr(request),
                    request.getRequestURL().toString(), signature.getName(),
                    request.getMethod(), System.currentTimeMillis() - beforeTime,
                    pjp.getArgs(), JSONObject.toJSONString(result));
        }
    
        @Override
        public void before(JoinPoint pjp) {
            MethodSignature signature = (MethodSignature) pjp.getSignature();
            Method method = signature.getMethod();
            TraceLog traceLog = method.getAnnotation(TraceLog.class);
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
            log.info("[Tracelog begin]Call interface[{}] from IP[{}]," +
                            "URL:[{}], method name:[{}]," +
                            "method type:[{}], input parameter:[{}]",
                    traceLog != null ? traceLog.type() : "", getIpAddr(request),
                    request.getRequestURL().toString(), signature.getName(),
                    request.getMethod(), pjp.getArgs());
        }
    
        private String getIpAddr(HttpServletRequest request) {
            //获取代理服务器IP地址
            String proxyIp = request.getHeader(X_FORWARDED_FOR);
            //如果存在代理服务器IP地址,则从中提取客户端真实IP地址
            if (proxyIp != null && proxyIp.length() != 0) {
                String[] ips = proxyIp.split(",");
                for (String ip : ips) {
                    if (!UNKNOWN_IP.equalsIgnoreCase(ip)) {
                        return ip.trim();
                    }
                }
            }
            //如果不存在代理服务器IP地址,则直接获取远程IP地址
            return request.getRemoteAddr();
        }
    }
    

    4.定义日志捕获切面

    @Slf4j
    @Aspect
    public class TraceLogAspect {
        @Resource(name = "traceLogProcess")
        ITraceLogProcess traceLogProcess;
    
        private Long beforeTime;
    
        @AfterThrowing(throwing = "ex", value = "@annotation(uih.st.core.traceLog.TraceLog)")
        public void afterThrowing(JoinPoint pjp, Throwable ex) {
            traceLogProcess.afterThrowing(pjp, ex, beforeTime);
        }
    
        @AfterReturning(returning = "result", value = "@annotation(uih.st.core.traceLog.TraceLog)")
        public void afterReturning(JoinPoint pjp, Object result) {
            traceLogProcess.afterReturning(pjp, result, beforeTime);
    
        }
    
        @Before(value = "@annotation(uih.st.core.traceLog.TraceLog)")
        public void before(JoinPoint pjp) {
            this.beforeTime = System.currentTimeMillis();
            traceLogProcess.before(pjp);
        }
    }
    

    5.通过AutoConfiguration实现注入

    @Configuration
    @ConditionalOnWebApplication
    public class TraceLogAutoConfiguration {
        @Bean(name = "traceLogProcess")
        @ConditionalOnMissingBean(name = "traceLogProcess")
        public ITraceLogProcess traceLogProcess() {
            return new TraceLogProcess();
        }
    
        @Bean
        public TraceLogAspect traceLogAspect() {
            return new TraceLogAspect();
        }
    }
    

    6.starter文件spring.factories新增类

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=core.TraceLogAutoConfiguration
    

    应用使用

    将上述实现的starter通过依赖引用后:

    @TraceLog(type = "aaaaaa")
    @PostMapping("/test")
    public Result test() {
        return Result.success();
    }
    
  • 相关阅读:
    promise中合并对象的实例方法
    web手势库Alloyfinger
    阿里云服务器地域和可用区查询表_地域可用区大全
    移动端测试
    Kafka 消费者解析
    学习入门 chatgpt原理 一
    开题:轴承的剩余寿命预测(为什么要长时间长序列预测,意义)
    [排序]leetcode1636:按照频率将数组升序排序(easy)
    【MM小贴士】SAP可配置物料的功能实现
    qt主窗体
  • 原文地址:https://blog.csdn.net/andybegin/article/details/139655730