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<Boolean> test() {
    return Result.success();
}
相关推荐
2202_754421545 分钟前
生成MPSOC以及ZYNQ的启动文件BOOT.BIN的小软件
java·linux·开发语言
蓝染-惣右介8 分钟前
【MyBatisPlus·最新教程】包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段
java·数据库·tomcat·mybatis
小林想被监督学习8 分钟前
idea怎么打开两个窗口,运行两个项目
java·ide·intellij-idea
HoneyMoose10 分钟前
IDEA 2024.3 版本更新主要功能介绍
java·ide·intellij-idea
我只会发热12 分钟前
Java SE 与 Java EE:基础与进阶的探索之旅
java·开发语言·java-ee
是老余13 分钟前
本地可运行,jar包运行错误【解决实例】:通过IDEA的maven package打包多模块项目
java·maven·intellij-idea·jar
crazy_wsp14 分钟前
IDEA怎么定位java类所用maven依赖版本及引用位置
java·maven·intellij-idea
.Ayang16 分钟前
tomcat 后台部署 war 包 getshell
java·计算机网络·安全·web安全·网络安全·tomcat·网络攻击模型
一直学习永不止步21 分钟前
LeetCode题练习与总结:最长回文串--409
java·数据结构·算法·leetcode·字符串·贪心·哈希表
努力的悟空32 分钟前
国土变更调查拓扑错误自动化修复工具的研究
运维·自动化