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();
}
相关推荐
高山上有一只小老虎5 分钟前
java 正则表达式大全
java·正则表达式
躲猫猫的喵喵13 分钟前
Ubuntu2204降内核版本
linux·运维·服务器·ubuntu
_院长大人_41 分钟前
设计模式-工厂模式
java·开发语言·设计模式
zdslovezy43 分钟前
CentOS 系统升级 OpenSSH 和 OpenSSL 的完整方案
linux·运维·centos
凌波粒1 小时前
MyBatis完整教程IDEA版(2)--ResultMap/注解/一对多/多对一/lombok/log4j
java·intellij-idea·mybatis
蓝-萧1 小时前
【玩转全栈】----Django基本配置和介绍
java·后端
priority_key1 小时前
排序算法:堆排序、快速排序、归并排序
java·后端·算法·排序算法·归并排序·堆排序·快速排序
cccccc语言我来了1 小时前
(Linux (6):从包管理到工具探索,构建系统操作基础认知)
linux·运维·服务器
8K超高清2 小时前
高校巡展:中国传媒大学+河北传媒学院
大数据·运维·网络·人工智能·传媒
wuk9982 小时前
CentOS7环境搭建L2TP服务器
运维·服务器