日志链路追踪

本文介绍了在分布式环境中如何实现日志链路追踪,包括通过servlet拦截器生成全局TraceId,使用自定义注解和Aspect记录日志,结合dubbo拦截器跨服务传递traceId和用户信息,以及利用Mysql拦截器记录SQL日志,从而实现完整的调用链路追踪。
摘要由CSDN通过智能技术生成

摘要

在我们的系统中需要记录日志,包括接口、方法的调用用户信息、用时、参数等。分布式环境中通过dubbo调用rpc服务,需要提供全局traceId追踪完整调用链路。


解决方案

  • 日志中心独立部署,提供rpc服务,日志统一记录统一管理,可以记录到数据库或者log文件中
  • request入口添加拦截器,采用slf4j提供的MDC记录用户信息
  • 自定义注解和aspect,添加环绕切面,调用日志中心的rpc服务记录日志
  • 添加dubbo拦截器,使用户信息,全局traceId可以跨服务传输
  • mysql数据库添加Interceptors,将mysql日志记录到ThreadLocal中
  • log-chain-spring-boot-starter

实现

  1. 代码结构调用链架构图

  2. 日志中心
    提供RPC服务记录日志,demo中采用的dubbo服务,日志记录到数据库中

    @Component
    @Service(interfaceClass = LogApi.class, timeout = 10000)
    public class LogApiImpl implements LogApi{
         
        @Autowired
        private LogServiceImpl logService;
        public void save(LogDTO dto){
         
            LogEntity entity=new LogEntity();
            BeanUtils.copyProperties(dto,entity);
            logService.save(entity);
        }
    }
    

    日志内容

    @Data
    public class LogDTO implements Serializable{
         
        private static final long serialVersionUID = 4069882290787051188L;
        private Integer id;
        private String traceId;
        private String appName;
        private String userId;
        private String userName;
        private String methodName;
        private String type;
        private String param;
        private String result;
        private String description;
        private Long spendTime;
        private Date optTime;
    }
    
  3. log-chain-spring-boot-start

    类名 作用
    LogChainConfiguration starter配置类
    LogChainProperties 配置文件类,配置appName
    LogRecord 注解,配置日志描述以及方法是否记录Mysql日志
    LogRecordAspect 从MDC和ThreadLocal中读取信息并记录日志
    LogRecordManager ThreadLocal记录日志链
    MysqlLogManager ThreadLocal记录Mysql日志信息
    TraceFilter dubbo过滤器
    MySQLStatementInterceptor mysql拦截器
    LogRecordVO 日志VO,记录方法唯一标识以及是否记录mysql
    MysqlLogVO Mysql日志信息

    在这里插入图片描述

  4. servlet拦截器
    拦截请求,生成全局TraceId、记录用户信息至MDC中
    由于各个应用获取用户信息方式不一样,所以拦截器由各个项目实现

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
         
            String userId= SysUtil.getCurUserId((HttpServletRequest)request);
            if(!StringUtils.isEmpty(userId)){
         
                UserDTO user= userService.getUserById(userId);
                if(user!=null){
         
                    MDCUtil.setUserName(user.getUserName());
                }
            }
            MDCUtil.setUserId(userId);
            MDCUtil.setTraceId();
            chain.doFilter(request, response);
        }
    
  5. 自定义注解添加日志描述

    @Documented
    @Target({
         ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface LogRecord {
         
        String description() default "" ;
        Boolean recordMysql() default true;
    }
    

    需要记录日志的方法添加注解

    @LogRecord(description = "根据用户id查询用户角色列表")
    public List<RoleDTO> listUserRole(String userId){
         
        UserDTO user=getUserById(userId);
        if(user==null){
         
            return new ArrayList<>();
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值