追踪日志
通过什么方式,可以在logger的输出结果上自动附加一个标识?
日常开发中,为了能够快速定位问题,通常需要在日志中记录请求url,请求方法,用户ID,请求ID等等等等。硬编码的形式log.info("requestUrl:{}, userId: {}......", requestUrl, userId)
;显然是无法满足要求的,这样实现工作量大,易出错,改动也极其不便。
解决方案
使用MDC只需要几行代码就能轻松应对上述需求。实现一个Filter
,使用MDC.put(key, val)
写入需要打印的参数。
import org.slf4j.MDC; public class MDCFilter extends OncePerRequestFilter implements Filter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException { try { MDC.put("requestMethod", request.getMethod().toUpperCase()); MDC.put("requestUri", request.getRequestURI()); MDC.put("uuid", UUID.randomUUID().toString().replace("-", "")); MDC.put("ip", request.getRemoteAddr()); User requestUser = (User) request.getAttribute(Constants.REQUEST_USER); if (requestUser != null) { MDC.put("uid", String.valueOf(requestUser.getId())); } } catch (Exception e) { logger.error("init MDC error.", e); } try { filterChain.doFilter(request, response); } finally { MDC.clear(); } } }
注册Filter
@Bean public FilterRegistrationBean<MDCFilter> mdcFilter() { FilterRegistrationBean<MDCFilter> registrationBean = new FilterRegistrationBean<>(); registrationBean.setName("mdcFilter"); MDCFilter mdcFilter = new MDCFilter(); registrationBean.setFilter(mdcFilter); registrationBean.addUrlPatterns("/*"); registrationBean.setOrder(100); return registrationBean; }
日志pattern
配置,使用%X{}
取值。%X{requestMethod} %X{requestUri} %X{uuid} %X{uid}
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${log.path}/log.log</file> <encoder> <pattern> %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %X{requestMethod} %X{requestUri} %X{uuid} %X{uid} %logger{50} - %msg%n </pattern> <charset>UTF-8</charset> </encoder> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>10MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <maxHistory>15</maxHistory> </rollingPolicy> </appender>
打印效果
2020-05-23 01:59:27.028 INFO POST /api/login 5a7fa16b42e44f1395678f77fbbcad92 17552
实现应该还是threadloacl