一拜秧、MDC概念
slf4j除了trace痹屹、debug、info枉氮、warn志衍、error這幾個日志接口外,還可以配合MDC將數據寫入日志聊替。換句話說MDC也是用來記錄日志的楼肪,但它的使用方式與使用日志接口不同。
在使用日志接口時我們一般這么做
Logger LOG = LoggerFactory.getLogger("LOGNAME_OR_CLASS");
if(LOG.isDebugEnabled()) {
LOG.debug("log debug");
}
MDC從使用方式上有些不同,我對它的理解是MDC可以將一個處理線程中你想體現(xiàn)在日志文件中的數據統(tǒng)一管理起來惹悄,根據你的日志文件配置決定是否輸出春叫。
比如以下但不限于以下場景可以考慮使用MDC來達到目的
在日志中體現(xiàn)請求用戶IP地址
用戶使用http客戶端的user-agent
記錄一次處理線程的日志跟蹤編號(這個編號目的是為了查詢日志方便,結合grep命令能根據跟蹤編號將本次的處理日志全部輸出)
二、MDC的使用
org.slf4j.MDC我個人會用AOP或Filter或Interceptor這類工具配合使用暂殖,獲得你希望輸出到日志的變量并調用MDC.put(String key, String val)价匠,比如下面代碼片段第5行:
public static void initUUID(String uuid) {
if(!StringUtils.isBlank(getUUID())) {
LOGGER.debug("初始化uuid是發(fā)現(xiàn)uuid:{} 已存在,已重置", getUUID());
}
MDC.put("mdc_trace_id", StringUtils.isBlank(uuid)?createUUID():uuid);
}
代碼通過AOP記錄了每次請求的traceId并使用變量"mdc_trace_id"記錄呛每,在日志配置文件里需要設置變量才能將"mdc_trace_id"輸出到日志文件中踩窖。我以logback配置文件為例,看日志第6行%X{mdc_trace_id}:
<appender name="activexAppender" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="/opt/web/commerce/wf/logs/commerce.log" />
<param name="DatePattern" value="'.'yyyy-MM-dd-HH'.log'" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="[%d{MM-dd HH:mm:ss SSS\} %-5p] [%X{mdc_trace_id}] [%t] %c{3\} - %m%n" />
</layout>
</appender>
三、MDC帶來的好處
如果你的系統(tǒng)除了bug,老大讓你查某一用戶數據到日志里分析一下晨横。如果沒有MDC我猜此時此刻你應該處于雪崩狀態(tài)毙石。MDC恰到好處的讓你能夠實現(xiàn)快速定位線上問題與某一用戶的操作行為。
如果你是個代碼潔癖颓遏,封裝了公司LOG的操作徐矩,并且將處理線程跟蹤日志號也封裝了進去,但只有使用了你封裝日志工具的部分才能打印跟蹤日志號叁幢,其他部分(比如hibernate滤灯、mybatis、httpclient等等)日志都不會體現(xiàn)跟蹤號曼玩。當然我們可以通過linux命令來繞過這些困擾鳞骤。
使代碼簡潔、日志風格統(tǒng)一