在日常的生產(chǎn)中,尤其是在微服務(wù)盛行的今天,我們的服務(wù)很可能是作為分布式應(yīng)用上的一個(gè)點(diǎn)筐赔,會(huì)接受來(lái)自不同客戶端的請(qǐng)求,那么在服務(wù)的為每行日志標(biāo)記出來(lái)自的客戶端呢渔欢?本篇我們通過(guò)介紹Logback的高級(jí)用法盗忱,來(lái)為大家實(shí)現(xiàn)索昂。
- 擴(kuò)展知識(shí)
在分布式應(yīng)用的今天怔毛,如何通過(guò)日志把客戶端請(qǐng)求的不同應(yīng)用的日志串起來(lái)左痢,展示呢
首先分析原理
其實(shí)很簡(jiǎn)單契耿,就是為每個(gè)線程保存點(diǎn)私有變量瞒大,這個(gè)私有變量的值,由我們自定義宵喂,用于區(qū)分不同的應(yīng)用糠赦。
說(shuō)到線程的私有變量,可能老程序猿,就想到這個(gè)類及 ThreadLocal
,關(guān)于個(gè)類的源碼分析拙泽,小編已經(jīng)寫過(guò)了淌山,這里就不解釋了,繼續(xù)... ,我們今天用到的這個(gè) MDC
就是為每個(gè)線程請(qǐng)求保存私有變量顾瞻,然后在輸出日志的時(shí)候打印出來(lái)泼疑,這樣就能標(biāo)識(shí)出,每一行日志的來(lái)源荷荤。
代碼實(shí)現(xiàn)
Logback
框架已經(jīng)為我們實(shí)現(xiàn)了一套常用的請(qǐng)求退渗,今天我們就用,這個(gè)來(lái)演示蕴纳。
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
為每個(gè)處理請(qǐng)求的線程添加上私有變量会油。就是如此,
不過(guò)我們要注意的是為了讓MDC中的信息在任何時(shí)候都是正確有效的古毛,我們需要在request被處理之前翻翩,就講相關(guān)信息放入mdc,再在處理完后稻薇,clear掉嫂冻。
大家看到其實(shí)這個(gè)類是繼承了 Filter
就是一個(gè)過(guò)濾器,在這里小編用的是 SpringBoot實(shí)現(xiàn)的
那么如何使用呢塞椎?
/**
* @Package: firebird.logger.config.filter
* @Description: 應(yīng)用配置
* @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<String> urlPatterns = new ArrayList<>();
urlPatterns.add("/*");
registrationBean.setUrlPatterns(urlPatterns);
return registrationBean;
}
}
Loback打印日志
該教程還是參考了我之前寫的日志錯(cuò)誤提醒框架桨仿,所以注釋部分包括了使用 Sentry
的部分代碼,如果對(duì)錯(cuò)誤收集框架感興趣的同學(xué)案狠,可以看我的另一篇博客
SpringBoot整合Sentry
<configuration>
<!-- 彩色日志 -->
<!-- 彩色日志依賴的渲染類 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
<conversionRule conversionWord="wex"
converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
<conversionRule conversionWord="wEx"
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(--){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>/>
<property name="MDC_LOG_PATTERN" value="IP:%X{req.remoteHost} -url:%X{req.requestURI} -Method:%X{req.method} - QueryString:%X{req.queryString} - device:%X{req.userAgent} -ips:%X{req.xForwardedFor} - %m%n "></property>
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
<layout>
<pattern>${MDC_LOG_PATTERN}</pattern>
</layout>
</appender>
<!--<appender name="Sentry" class="com.getsentry.raven.logback.SentryAppender">-->
<!--<!–每個(gè)項(xiàng)目生成不通的key–>-->
<!--<dsn>http://d73b23c481654b9ca0e4e8a9db310169:daaf5dc2edef462690791ef324316738@sentry.boluome.com/7</dsn>-->
<!--<!– 設(shè)置攔截的最低級(jí)別為warn 警告–>-->
<!--<filter class="ch.qos.logback.classic.filter.ThresholdFilter">-->
<!--<level>WARN</level>-->
<!--</filter>-->
<!--</appender>-->
<!--<logger name="logback.SentryAppenderIT" level="INFO">-->
<!--<appender-ref ref="Sentry"/>-->
<!--</logger>-->
<root level="INFO">
<appender-ref ref="Console"/>
<!--<appender-ref ref="Sentry"/>-->
</root>
</configuration>
可以看到 MDC_LOG_PATTERN 中獲取了從MDC過(guò)濾器中的參數(shù)服傍,這樣我們就能打印出來(lái)了
代碼測(cè)試
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: - 請(qǐng)求類型 : 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: - 請(qǐng)求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: - 參數(shù)列表 : []
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: - 返回參數(shù) : 請(qǐng)查看日志
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: - -----------------方法執(zhí)行完畢,耗時(shí):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方法開始執(zhí)行----------------------------
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: - 請(qǐng)求類型 : 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: - 請(qǐng)求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: - 參數(shù)列表 : []
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: - 返回參數(shù) : 請(qǐng)查看日志
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: - -----------------方法執(zhí)行完畢,耗時(shí):0ms-------------------
擴(kuò)展方法如何實(shí)現(xiàn)呢? 不積跬步無(wú)以至千里,接下來(lái)還有要學(xué)習(xí)如何使用
Logstash
kibana
elasticsearch