Logback中的MDC
来源:互联网 发布:淘宝代写作业 编辑:程序博客网 时间:2024/06/06 02:32
Logback学习交流群:603634815。
Logback是一个日志框架。
其中有一项功能很好使-MDC,映射诊断环境(Mapped Diagnostic Context)。
MDC本质上是使用的ThreadLocal。系统调用链可能很长,为了方便日志跟踪,统一打印标识。
以下是一个官方入门例子:
/** * Logback: the reliable, generic, fast and flexible logging framework. * Copyright (C) 1999-2015, QOS.ch. All rights reserved. * * This program and the accompanying materials are dual-licensed under * either the terms of the Eclipse Public License v1.0 as published by * the Eclipse Foundation * * or (per the licensee's choosing) * * under the terms of the GNU Lesser General Public License version 2.1 * as published by the Free Software Foundation. */package chapters.mdc;import java.io.File;import java.net.MalformedURLException;import java.net.URL;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.slf4j.MDC;import ch.qos.logback.classic.LoggerContext;import ch.qos.logback.classic.encoder.PatternLayoutEncoder;import ch.qos.logback.classic.joran.JoranConfigurator;import ch.qos.logback.classic.spi.ILoggingEvent;import ch.qos.logback.core.ConsoleAppender;import ch.qos.logback.core.joran.spi.JoranException;import ch.qos.logback.core.util.Loader;import ch.qos.logback.core.util.StatusPrinter;public class SimpleMDC { static public void main(String[] args) throws Exception { // You can put values in the MDC at any time. Before anything else // we put the first name MDC.put("first", "Dorothy"); // configure via the configuration file "chapters/mdc/simpleMDC.xml" // which ships with the examples //configureViaXML_File(); // For educational purposes, the same configuration can // be accomplished programmatically. // programmaticConfiguration(); Logger logger = LoggerFactory.getLogger(SimpleMDC.class); // We now put the last name MDC.put("last", "Parker"); // The most beautiful two words in the English language according // to Dorothy Parker: logger.info("Check enclosed."); logger.debug("The most beautiful two words in English."); MDC.put("first", "Richard"); MDC.put("last", "Nixon"); logger.info("I am not a crook."); logger.info("Attributed to the former US president. 17 Nov 1973."); } static void programmaticConfiguration() { // Configure logback LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); loggerContext.reset(); PatternLayoutEncoder layout = new PatternLayoutEncoder(); layout.setContext(loggerContext); layout.setPattern("%X{first} %X{last} - %m%n"); layout.start(); ConsoleAppender<ILoggingEvent> appender = new ConsoleAppender<ILoggingEvent>(); appender.setContext(loggerContext); appender.setEncoder(layout); appender.start(); // cast root logger to c.q.logback.classic.Logger so that we can attach // an appender to it ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger("root"); root.addAppender(appender); } static void configureViaXML_File() { LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); try { JoranConfigurator configurator = new JoranConfigurator(); configurator.setContext(lc); lc.reset(); URL url = Loader.getResourceBySelfClassLoader("chapters/mdc/simpleMDC.xml"); try { url = url==null?new File("src/main/java/chapters/mdc/simpleMDC.xml").toURI().toURL():url; } catch (MalformedURLException e) { e.printStackTrace(); } configurator.doConfigure(url); } catch (JoranException je) { StatusPrinter.print(lc); } }}MDC.put(String, String); 是将变量内容存到线程内部。看他的内部实现
public static void put(String key, String val) throws IllegalArgumentException { if (key == null) { throw new IllegalArgumentException("key parameter cannot be null"); } if (mdcAdapter == null) { throw new IllegalStateException("MDCAdapter cannot be null. See also " + NULL_MDCA_URL); } mdcAdapter.put(key, val); }是通过mdcAdapter存放的,类型org.slf4j.spi.MDCAdapter,是slf4j提供的一个统一接口。
它是通过一个静态块进行初始化的:
private static MDCAdapter bwCompatibleGetMDCAdapterFromBinder() throws NoClassDefFoundError { try { return StaticMDCBinder.getSingleton().getMDCA(); } catch (NoSuchMethodError nsme) { // binding is probably a version of SLF4J older than 1.7.14 return StaticMDCBinder.SINGLETON.getMDCA(); } } static { try { mdcAdapter = bwCompatibleGetMDCAdapterFromBinder(); } catch (NoClassDefFoundError ncde) { mdcAdapter = new NOPMDCAdapter(); String msg = ncde.getMessage(); if (msg != null && msg.contains("StaticMDCBinder")) { Util.report("Failed to load class \"org.slf4j.impl.StaticMDCBinder\"."); Util.report("Defaulting to no-operation MDCAdapter implementation."); Util.report("See " + NO_STATIC_MDC_BINDER_URL + " for further details."); } else { throw ncde; } } catch (Exception e) { // we should never get here Util.report("MDC binding unsuccessful.", e); } }StaticMDCBinder是org.slf4j.impl.StaticMDCBinder,在logback-classic包里面。但是这段代码是在slf4j-api中的,所以,只要使用slf4j作为统一日志门面的日志框架在使用MDC功能时一定要在自己的jar包里面创建org.slf4j.impl.StaticMDCBinder,包名、类名不能错。
org.slf4j.impl.StaticMDCBinder里面 getMDCA()方法,直接返回的是new LogbackMDCAdapter();
ch.qos.logback.classic.util.LogbackMDCAdapter实现org.slf4j.spi.MDCAdapter,声明ThreadLocal:
final ThreadLocal<Map<String, String>> copyOnThreadLocal = new ThreadLocal<Map<String, String>>();
进行get、set方法。
因为程序里面配置了pattern属性
layout.setPattern("%X{first} %X{last} - %m%n");所以在日志打印的时候会从MDC中取出first和last进行打印。
如果是以下配置文件,也能起到同样作用:
<?xml version="1.0" encoding="UTF-8" ?><configuration><appender name="CONSOLE"class="ch.qos.logback.core.ConsoleAppender"><layout class="ch.qos.logback.classic.PatternLayout"><Pattern>%X{first} %X{last} - %m%n</Pattern></layout></appender><root level="debug"><appender-ref ref="CONSOLE" /></root></configuration>
未完待续:MDC取值过程。
阅读全文
0 0
- Logback中的MDC
- logback mdc
- logback的MDC简单实用
- slf4j中的MDC
- log4j中的MDC和NDC
- MDC
- Slf4j MDC 使用和 基于 Logback 的实现分析
- 在SpringBoot项目中添加logback的MDC
- 日志线程与MDC中的Akka源
- LogBack sl4j 通过MDC实现日志记录区分用户Session[以Spring mvc为例] - 独木桥
- logback MDC(Mapped Diagnostic Context)与分布式系统的跟踪系统
- 使用MDC为Logback slf4 日志记录线程ID,区分每次执行的会话日志
- 使用MDC为Logback slf4 日志记录线程ID,区分每次执行的会话日志
- LogBack在项目中的应用
- 日志mdc
- 使用Spring MVC中的Interceptor和slf4j中的MDC实现日志归类标记
- logback
- LOGBACK
- sicily1000. 输入输出LL(1)语法分析程序
- 一个页面中如果存在多个ajax访问后台,此刻后台是单线程的吗?还是多线程
- java.lang.RuntimeException: Parcel: unable to marshal value
- Spring MVC配置CORS
- RabbitMQ消息队列的小伙伴: ProtoBuf(Google Protocol Buffer)
- Logback中的MDC
- 文本情感分类(四)
- Mac 安装 XGBoost Python库
- RabbitMQ消息队列(九):Publisher的消息确认机制
- ThinkPHP5.0中Request请求对象的使用和常用的操作
- Spring Boot入门篇
- JZOJ 1637. 【ZJOI2009】狼和羊的故事
- 三角函数各角度的值,角度用π的形式表示
- MC9S08DZ60移植ucos小记