论坛首页新手上路 签到
查看: 5053|回复: 0

[知识分享] 利用logId,跟踪请求路线

[复制链接]
金智-周雷

该用户从未签到

11

主题

11

帖子

33

积分

初来乍到

凡人

Rank: 1

积分
33
发表于 2017-9-2 13:02:48 | 显示全部楼层 |阅读模式
利用logId,跟踪请求路线

------------------------------------------
目的:
      通常不允许直接将异常堆栈信息,显示在前端。而经过转义的异常描述,又无法表达详细异常信息,且往往只是通用性描述,不具有唯一性。
      在繁忙的业务系统中,日志文件往往非常庞大,通过前端异常描述,定位问题非常困难。
      此时,就需要一个唯一性的异常标识,既可以显示在前端,也打印在异常日志中,从而将通用性异常描述和异常堆栈信息关联起来。该异常标识,可以选择UUID,或加上时间前缀。



------------------------------------------
异常标识logId

  1.     public static String getId() {
  2.         return UUID.randomUUID().toString().replace("-", "");
  3.     }
复制代码




------------------------------------------
使用过滤器Filter,注入logId至slf4j的MDC中

注:允许logId由请求参数中传入(如nginx中设置logId),从而将跨系统请求串联起来。

  1. public class MyFilter implements Filter {
  2.     private LoggerDecorate logger = LoggerDecorateFactory.getLogger(this.getClass());
  3.    
  4.     @Override
  5.     public void destroy() {
  6.         logger.debug("MyFilter过滤器销毁");
  7.     }

  8.     @Override
  9.     public void doFilter(ServletRequest request, ServletResponse response,
  10.             FilterChain chain) throws IOException, ServletException {
  11.         logger.debug("MyFilter执行过滤操作");
  12.         initReqLog(request);
  13.         chain.doFilter(request, response);
  14.     }

  15.     @Override
  16.     public void init(FilterConfig config) throws ServletException {
  17.         logger.debug("MyFilter过滤器初始化");
  18.     }
  19.    
  20.    
  21.     /**
  22.      * 日志输出uuid
  23.      * @param httpRequest
  24.      */
  25.     private void initReqLog(ServletRequest request) {
  26.         String logId = request.getParameter("logId");
  27.         if(StringUtils.isEmpty(logId)){
  28.             logId = "MF"+CommonUtil.getId();
  29.         }
  30.         logger.debug("上一个请求处理线程的MDC遗留logId={}", MDC.get("logId"));
  31.         MDC.clear();
  32.         MDC.put("logId", logId);
  33.     }
  34.    
  35. }
复制代码




------------------------------------------
响应基类
注:将logId作为响应参数返回,进而前端显示

  1. public class BaseResult implements IBaseRsp, Serializable {
  2.         private static final long serialVersionUID = 1L;

  3.         /**
  4.          * 接口返回码
  5.          */
  6.         private int code = ResultCode.OK;

  7.         /**
  8.          * 描述
  9.          */
  10.         private String msg;

  11.         /**
  12.          * 日志ID
  13.          */
  14.         private String logId;
  15.        
  16.         public BaseResult() {
  17.                 code = ResultCode.OK;
  18.                 logId = MDC.get("logId");
  19.                 if(StringUtils.isBlank(logId)){
  20.                     logId = "BR"+CommonUtil.getId();
  21.                 }
  22.                
  23.         }
  24.     public BaseResult(int code) {
  25.         this.code = code;
  26.         logId = MDC.get("logId");
  27.         if(StringUtils.isBlank(logId)){
  28.             logId = "BR"+CommonUtil.getId();
  29.         }
  30.     }

  31.     public BaseResult(int code, String msg) {
  32.         this.code = code;
  33.         this.msg = msg;
  34.         logId = MDC.get("logId");
  35.         if(StringUtils.isBlank(logId)){
  36.             logId = "BR"+CommonUtil.getId();
  37.         }
  38.     }
  39.    
  40.         public int getCode() {
  41.                 return code;
  42.         }

  43.         public void setCode(int code) {
  44.                 this.code = code;
  45.         }

  46.         public String getMsg() {
  47.                 return msg;
  48.         }

  49.         public void setMsg(String msg) {
  50.                 this.msg = msg;
  51.         }

  52.         public String getLogId() {
  53.                 return logId;
  54.         }

  55.         public void setLogId(String logId) {
  56.                 this.logId = logId;
  57.         }

  58. }
复制代码



------------------------------------------
打印日志

logback.xml
  1.     <property name="outPattern" value="^A[%date{yyyy-MM-dd HH:mm:ss.SSS}] [%level] [api] [%t] [%c] [%X{logId}] %msg %n"/>
  2.    
  3.         <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
  4.           <encoder>
  5.             <Pattern>${outPattern}</Pattern>
  6.           </encoder>
  7.           <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
  8.             <level>TRACE</level>
  9.           </filter>
  10.         </appender>
复制代码









像猪一样乐观,像鱼一样自由
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

Archiver|手机版|小黑屋|江苏金智教育信息股份有限公司 ( 系统管理员:binmeng@wisedu.com  

GMT+8, 2021-4-23 07:37

Powered by Discuz! X3.2

© 2015 Design: www.wisedu.com

快速回复 返回顶部 返回列表