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. Filter和Interceptor的终归作用还是从入口修改或验证请求进来的数据

    Filter是Java EE标准.Inteceptor是Spring 标准. Filter在servlet前面,Interveptor在servlet之后 Filter和Inteceptor都可以改变 ...

  2. nginx匹配规则

    rewrite ^/(.*)$ /index.php/$1 last; 这句话的意思,是把slash(/)之后的所有内容在前面加上一个/index.php,这里的$1指代前面括号的正则表达式(.*)所 ...

  3. UP Board USB无线网卡选购指南

    前言 原创文章,转载引用务必注明链接,水平有限,欢迎指正. 本文环境:ubilinux 3.0 kernel 4.4.0 本文使用Markdown写成,为获得更好的阅读体验和正常的图片.链接,请访问我 ...

  4. Java并发编程(三)volatile域

    相关文章 Java并发编程(一)线程定义.状态和属性 Java并发编程(二)同步 Android多线程(一)线程池 Android多线程(二)AsyncTask源代码分析 前言 有时仅仅为了读写一个或 ...

  5. GridView的经常使用属性

    1.android:numColumns="auto_fit"   //GridView的列数设置为自己主动 2.android:columnWidth="90dp &q ...

  6. 安卓自带下拉刷新SwipeRefreshLayout加入上拉刷新功能

    在项目里面要用到刷新库.曾经都是使用第三方的.只是看到官方出了  SwipeRefreshLayout之后就用SwipeRefreshLayout.可是不知道什么原因官方SwipeRefreshL ...

  7. C指针——C语言手记

    近期敲代码的时候.发现自己非常多东西都開始忘了. 今天最终有机会好好总结一下指针.当做个笔记同一时候也希望对大家实用.假设有不对的地方.希望大家能帮我指正一下.然后我的实验环境是32位RHEL+ecl ...

  8. iOS 把数据库文件打包到mainbundle中,查找不到路径的解决的方法;以及在删除bundle中文件的可行性

    在开发中有时我们须要把数据库文件打包到我们的项目中.一般我们都是在外部用工具生成数据库文件,然后拉入项目中.可是我们在程序中查找改文件时.返回的路径总是nil 解决的方法: 原因我们拉入其它资源文件( ...

  9. 在线API

    JExcelApi http://jexcelapi.sourceforge.net/resources/javadocs/index.html Poi http://poi.apache.org/a ...

  10. php新版本号废弃 preg_replace /e 修饰符

    近期serverphp版本号升级到了 5.6  发现出了非常多警告 preg_replace(): The /e modifier is deprecated, use preg_replace_ca ...