1. 参考资料

2. 环境

Java: jdk1.8.0_144

Logback: 1.0.13

3. %X 的使用方法

%X用于输出和当前线程相关联的NDC(嵌套诊断环境),在代码中给org.slf4j.MDC添加key/value即可增加新值

示例 说明
%X 输出所有值
%X{testKey} 输出testKey所对应的value,且无默认值
%X{testKey:-} 输出testKey所对应的value,默认为空
%X{testKey:-aaa} 输出testKey所对应的value,默认为aaa

测试代码

public class AbstractLogWrapper<T> {
private final T job;
private final Map<?, ?> context; public AbstractLogWrapper(T t) {
this.job = t;
this.context = MDC.getCopyOfContextMap();
} public void setLogContext() {
if (this.context != null) {
MDC.setContextMap(this.context);
}
} public void clearLogContext() {
MDC.clear();
} public T getJob() {
return this.job;
}
} public class LogSupplier<T> extends AbstractLogWrapper<Supplier<T>> implements Supplier<T> {
public LogSupplier(Supplier<T> supplier) {
super(supplier);
} @Override
public T get() {
this.setLogContext();
try {
return getJob().get();
} finally {
this.clearLogContext();
}
}
} @RunWith(MockitoJUnitRunner.class)
public class LogSupplierTest {
private static final Logger LOGGER = LoggerFactory.getLogger(LogSupplierTest.class);
private ExecutorService executorService; @Before
public void setUp() {
executorService = Executors.newFixedThreadPool(2);
} @Test
public void testGet() {
AtomicInteger counter = new AtomicInteger(0);
Supplier<String> supplier = () -> {
String rtn = String.valueOf(counter.incrementAndGet());
// 往MDC中添加内容
MDC.put(RunnabeTestHelper.RUNNABLE, rtn);
LOGGER.info("This is {} supplier.", rtn);
return rtn;
}; LogSupplier<String> logSupplier = Mockito.spy(new LogSupplier<>(supplier));
Set<String> set = new HashSet<>();
Mockito.doAnswer(invocation -> set.add(invocation.getMethod().getName())).when(logSupplier).setLogContext();
Mockito.doAnswer(invocation -> set.add(invocation.getMethod().getName())).when(logSupplier).clearLogContext(); List<CompletableFuture<String>> futures = IntStream.rangeClosed(0, 4).mapToObj(index -> CompletableFuture.supplyAsync(logSupplier, executorService)).collect(Collectors.toList());
futures.forEach(CompletableFuture::join);
Assert.assertEquals("[setLogContext, clearLogContext]", set.toString());
} } class RunnabeTestHelper {
static final String RUNNABLE = "runn_able";
}
  • 输出所有
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="stdot" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%X %m%n</pattern>
</layout>
</appender>
<root level="debug">
<appender-ref ref="stdot"/>
</root>
</configuration>

结果

runn_able=1 This is 1 supplier.
runn_able=3 This is 3 supplier.
runn_able=2 This is 2 supplier.
runn_able=4 This is 4 supplier.
runn_able=5 This is 5 supplier.
  • 输出特定值(不指定默认值/默认空/默认非空)
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="stdot" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%X{runn_able} %X{runn_able:-} %X{runnable:-aaa} %m%n</pattern>
</layout>
</appender>
<root level="debug">
<appender-ref ref="stdot"/>
</root>
</configuration>

结果

1 1 aaa This is 1 supplier.
2 2 aaa This is 2 supplier.
3 3 aaa This is 3 supplier.
5 5 aaa This is 5 supplier.
4 4 aaa This is 4 supplier.

4. 与%replace的配合使用

示例 说明
%replace(p ){r, t} p 为日志内容,r 是正则表达式,将p 中符合r 的内容替换为t
  • 把只有key没有value内容从日志中替换掉
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="stdot" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%replace(Test_Method=%X{method} runn-able=%X{runn_able}){'\S+=( |$)', ''} -> %m%n</pattern>
</layout>
</appender>
<root level="debug">
<appender-ref ref="stdot"/>
</root>
</configuration>

结果

runn-able=2 -> This is 2 supplier.
runn-able=3 -> This is 3 supplier.
runn-able=4 -> This is 4 supplier.
runn-able=5 -> This is 5 supplier.
runn-able=1 -> This is 1 supplier.

Logback中%X的使用的更多相关文章

  1. Logback中使用TurboFilter实现日志级别等内容的动态修改

    可能看到这个标题,读者会问:要修改日志的级别,不是直接修改log.xxx就好了吗?为何要搞那么复杂呢?所以,先说一下场景,为什么要通过TurboFilter去动态的修改日志级别.我们在使用Java开发 ...

  2. Logback中如何自定义灵活的日志过滤规则

    当我们需要对日志的打印要做一些范围的控制的时候,通常都是通过为各个Appender设置不同的Filter配置来实现.在Logback中自带了两个过滤器实现:ch.qos.logback.classic ...

  3. Logback中文文档(二):体系结构

    logback Logback 的基本结构充分通用,可应用于各种不同环境.目前,logback 分为三个模块:Core.Classic 和 Access. Core模块是其他两个模块的基础.Class ...

  4. 守护线程在logback中的使用 - 论基础知识的重要性

    守护线程在logback中的使用 先说问题,在java应用中,logback的异步Appender是怎么在主线程结束后,停下来的? 复盘 我在一个logback的测试用例中,写了这样的代码和logba ...

  5. logback中appender继承

    实例: <?xml version="1.0" encoding="UTF-8"?> <configuration debug="t ...

  6. logback中配置的日志文件的生成地址

    配置文件如下 <?xml version="1.0" encoding="UTF-8"?> <configuration debug=&quo ...

  7. logback中logger详解

    前言 logback实践笔记 ​ 上一篇主要对root进行了实践总结,现在基于上一篇中的springboot代码环境对logback.xml中的logger来进行实践和自己遇到的坑. logger简介 ...

  8. Logback中文文档(四):Appender

    什么是 Appender Appender是负责写记录事件的组件.Appender 必须实现接口"ch.qos.logback.core.Appender".该接口的重要方法总结如 ...

  9. Logback中文文档(三):配置

    在第一部分,我们将介绍配置 logback 的各种方法,给出了很多配置脚本例子.在第二部分,我们将介绍 Joran,它是一个通用配置框架,你可以在自己的项目里使用 Joran. Logback里的配置 ...

  10. logback中MDC使用

    今天在项目发现别人写了很多MDC.put("taskid", "testThread/heart/main_heart");或者MDC.put("ta ...

随机推荐

  1. 【paddle学习】图像分类

    https://zhuanlan.zhihu.com/p/28871960 深度学习模型中的卷积神经网络(Convolution Neural Network, CNN)近年来在图像领域取得了惊人的成 ...

  2. NPOI操作Excel 005:写入空Excel(Winform版)

    前文写了一个BS版本号的导出Excel的样例(http://blog.csdn.net/yysyangyangyangshan/article/details/47904119).对于CS版在保存的地 ...

  3. C#中Queue&lt;T&gt;类的使用以及部分方法的源代码分析

    Queue<T>类 表示对象的先进先出集合. 队列在按接收顺序存储消息方面很实用,以便于进行顺序处理. 存储在 Queue,<T> 中的对象在一端插入,从还有一端移除. Que ...

  4. 一览新的 Android Gradle 构建工具:新的 DSL 结构 和 Gradle 2.5

    译者地址:[翻]一览新的 Android Gradle 构建工具:新的 DSL 结构 和 Gradle 2.5 原文:First Look at New Android Gradle Build To ...

  5. java设计模式----真实世界的模式

    设计模式的定义: 模式是在某情境下,针对某问题的某种解决方案 反模式: 告诉你如何采用一个不好的解决方案解决一个问题 要点: 1.让设计模式自然而然地出现在你的设计中,而不是为了使用而使用 2.设计模 ...

  6. 写码时应该缩进使用 tab 还是空格?

    对于程序员来说,其实Tab和空格远远不只是“立场”问题那么简单. 在不同的编辑器里tab的长度可能不一致,所以在一个编辑器里用tab设置缩进后,在其它编辑器里看可能缩进就乱了.空格不会出现这个问题,因 ...

  7. ArrayList遍历的4种方法

    public class ArrayListDemo { public static void main(String args[]){ List<String> list = new A ...

  8. SQL常见问题及解决备忘

    1.mysql中:you cant't specify tartget table for update in from clause 错误 含义:在同一语句中update或delete某张表的时候, ...

  9. hadoop shuffle

    1 hadoop shuffle的地位 hadoop  shuffle是map reduce算法的核心,是它连接了多个map和多个reduce,它将map的输出交给reduce作为输入. 2 hado ...

  10. 使用双引擎,让kbmmw 的客户端访问更方便(既给浏览器做服务,也给桌面程序做服务)

    前面我们一直都讲了如何使用kbmmw smarthttpservice 给客户端提供REST  服务.主要都是返回给 浏览器访问的,如果我们使用delphi 开发桌面应用,如何使用这些服务呢?其实一切 ...