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();
}

相关推荐

  1. Controller 自动化日志输出

    2024-06-14 09:56:04       33 阅读
  2. Android 日志实时输出

    2024-06-14 09:56:04       33 阅读
  3. SpringBoot默认日志输出格式

    2024-06-14 09:56:04       56 阅读
  4. c++学习:iostream输入输出+错误流+标准日志

    2024-06-14 09:56:04       55 阅读
  5. [Electron] 将应用日志文件输出

    2024-06-14 09:56:04       58 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-14 09:56:04       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-14 09:56:04       106 阅读
  3. 在Django里面运行非项目文件

    2024-06-14 09:56:04       87 阅读
  4. Python语言-面向对象

    2024-06-14 09:56:04       96 阅读

热门阅读

  1. 物联网复习

    2024-06-14 09:56:04       22 阅读
  2. 【VUE】VUE安装包,怎么检查全部依赖包版本?

    2024-06-14 09:56:04       38 阅读
  3. redis 一主两从三哨兵

    2024-06-14 09:56:04       31 阅读
  4. UltraISO 未找到虚拟光驱

    2024-06-14 09:56:04       31 阅读
  5. 代码随想录第三十七天打卡

    2024-06-14 09:56:04       31 阅读
  6. 数据库什么情况使用索引(附MYSQL示例)

    2024-06-14 09:56:04       37 阅读
  7. 速盾的防护功能是如何实现的?

    2024-06-14 09:56:04       32 阅读
  8. 判断IP地址是否与CIDR表示的96.32/12匹配

    2024-06-14 09:56:04       34 阅读
  9. QT——事件

    2024-06-14 09:56:04       35 阅读
  10. SqlSugar无实体CURD应用-C#

    2024-06-14 09:56:04       31 阅读
  11. uni-app canvas创建画布

    2024-06-14 09:56:04       31 阅读