在日常的生产中,尤其是在微服务盛行的今天,我们的服务很可能是作为分布式应用上的一个点,会接受来自不同客户端的请求,那么在服务的为每行日志标记出来自的客户端呢?本篇我们通过介绍Logback的高级用法,来为大家实现。
- 扩展知识
在分布式应用的今天,如何通过日志把客户端请求的不同应用的日志串起来,展示呢
首先分析原理
其实很简单,就是为每个线程保存点私有变量,这个私有变量的值,由我们自定义,用于区分不同的应用。
说到线程的私有变量,可能老程序猿,就想到这个类及 ThreadLocal
,关于个类的源码分析,小编已经写过了,这里就不解释了,继续... ,我们今天用到的这个 MDC
就是为每个线程请求保存私有变量,然后在输出日志的时候打印出来,这样就能标识出,每一行日志的来源。
代码实现
Logback
框架已经为我们实现了一套常用的请求,今天我们就用,这个来演示。
MDCInsertingServletFilter
我们看一下该类的源码分析一下:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
this.insertIntoMDC(request);
try {
chain.doFilter(request, response);
} finally {
this.clearMDC();
}
}
void insertIntoMDC(ServletRequest request) {
MDC.put("req.remoteHost", request.getRemoteHost());
if(request instanceof HttpServletRequest) {
HttpServletRequest httpServletRequest = (HttpServletRequest)request;
MDC.put("req.requestURI", httpServletRequest.getRequestURI());
StringBuffer requestURL = httpServletRequest.getRequestURL();
if(requestURL != null) {
MDC.put("req.requestURL", requestURL.toString());
}
MDC.put("req.method", httpServletRequest.getMethod());
MDC.put("req.queryString", httpServletRequest.getQueryString());
MDC.put("req.userAgent", httpServletRequest.getHeader("User-Agent"));
MDC.put("req.xForwardedFor", httpServletRequest.getHeader("X-Forwarded-For"));
}
}
就是利用 MDC
为每个处理请求的线程添加上私有变量。就是如此,
不过我们要注意的是为了让MDC中的信息在任何时候都是正确有效的,我们需要在request被处理之前,就讲相关信息放入mdc,再在处理完后,clear掉。
大家看到其实这个类是继承了 Filter
就是一个过滤器,在这里小编用的是 SpringBoot实现的
那么如何使用呢?
/**
* @Package: firebird.logger.config.filter
* @Description: 应用配置
* @author: liuxin
* @date: 2017/8/29 下午5:32
*/
@Component
public class ApplicationConfig {
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
Filter actionFilter = new MDCInsertingServletFilter();
registrationBean.setFilter(actionFilter);
List urlPatterns = new ArrayList<>();
urlPatterns.add("/*");
registrationBean.setUrlPatterns(urlPatterns);
return registrationBean;
}
}
Loback打印日志
该教程还是参考了我之前写的日志错误提醒框架,所以注释部分包括了使用 Sentry
的部分代码,如果对错误收集框架感兴趣的同学,可以看我的另一篇博客
SpringBoot整合Sentry
/>
${MDC_LOG_PATTERN}
可以看到 MDC_LOG_PATTERN 中获取了从MDC过滤器中的参数,这样我们就能打印出来了
代码测试
IP:0:0:0:0:0:0:0:1 -url:/logger -Method:GET - QueryString: - device:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8 -ips: - URL : http://localhost:10111/logger
IP:0:0:0:0:0:0:0:1 -url:/logger -Method:GET - QueryString: - device:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8 -ips: - 请求类型 : GET
IP:0:0:0:0:0:0:0:1 -url:/logger -Method:GET - QueryString: - device:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8 -ips: - 请求IP : 0:0:0:0:0:0:0:1
IP:0:0:0:0:0:0:0:1 -url:/logger -Method:GET - QueryString: - device:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8 -ips: - 方法 : firebird.logger.rest.OtoRestController.testLogger
IP:0:0:0:0:0:0:0:1 -url:/logger -Method:GET - QueryString: - device:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8 -ips: - 参数列表 : []
IP:0:0:0:0:0:0:0:1 -url:/logger -Method:GET - QueryString: - device:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8 -ips: - hello world !!!
IP:0:0:0:0:0:0:0:1 -url:/logger -Method:GET - QueryString: - device:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8 -ips: - hello world !!!
IP:0:0:0:0:0:0:0:1 -url:/logger -Method:GET - QueryString: - device:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8 -ips: - 返回参数 : 请查看日志
IP:0:0:0:0:0:0:0:1 -url:/logger -Method:GET - QueryString: - device:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8 -ips: - -----------------方法执行完毕,耗时:1ms-------------------
IP:192.168.199.191 -url:/logger -Method:GET - QueryString: - device:Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.0 Mobile/14G60 Safari/602.1 -ips: - ----------testLogger方法开始执行----------------------------
IP:192.168.199.191 -url:/logger -Method:GET - QueryString: - device:Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.0 Mobile/14G60 Safari/602.1 -ips: - URL : http://192.168.199.235:10111/logger
IP:192.168.199.191 -url:/logger -Method:GET - QueryString: - device:Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.0 Mobile/14G60 Safari/602.1 -ips: - 请求类型 : GET
IP:192.168.199.191 -url:/logger -Method:GET - QueryString: - device:Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.0 Mobile/14G60 Safari/602.1 -ips: - 请求IP : 192.168.199.191
IP:192.168.199.191 -url:/logger -Method:GET - QueryString: - device:Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.0 Mobile/14G60 Safari/602.1 -ips: - 方法 : firebird.logger.rest.OtoRestController.testLogger
IP:192.168.199.191 -url:/logger -Method:GET - QueryString: - device:Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.0 Mobile/14G60 Safari/602.1 -ips: - 参数列表 : []
IP:192.168.199.191 -url:/logger -Method:GET - QueryString: - device:Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.0 Mobile/14G60 Safari/602.1 -ips: - hello world !!!
IP:192.168.199.191 -url:/logger -Method:GET - QueryString: - device:Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.0 Mobile/14G60 Safari/602.1 -ips: - hello world !!!
IP:192.168.199.191 -url:/logger -Method:GET - QueryString: - device:Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.0 Mobile/14G60 Safari/602.1 -ips: - 返回参数 : 请查看日志
IP:192.168.199.191 -url:/logger -Method:GET - QueryString: - device:Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.0 Mobile/14G60 Safari/602.1 -ips: - -----------------方法执行完毕,耗时:0ms-------------------
扩展方法如何实现呢? 不积跬步无以至千里,接下来还有要学习如何使用
Logstash
kibana
elasticsearch