Logback中%X的使用
1. 参考资料
- https://gist.github.com/logogin/ff44c254f655340b653c
- http://www.cnblogs.com/zhudongchang/p/6861375.html
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的使用的更多相关文章
- Logback中使用TurboFilter实现日志级别等内容的动态修改
可能看到这个标题,读者会问:要修改日志的级别,不是直接修改log.xxx就好了吗?为何要搞那么复杂呢?所以,先说一下场景,为什么要通过TurboFilter去动态的修改日志级别.我们在使用Java开发 ...
- Logback中如何自定义灵活的日志过滤规则
当我们需要对日志的打印要做一些范围的控制的时候,通常都是通过为各个Appender设置不同的Filter配置来实现.在Logback中自带了两个过滤器实现:ch.qos.logback.classic ...
- Logback中文文档(二):体系结构
logback Logback 的基本结构充分通用,可应用于各种不同环境.目前,logback 分为三个模块:Core.Classic 和 Access. Core模块是其他两个模块的基础.Class ...
- 守护线程在logback中的使用 - 论基础知识的重要性
守护线程在logback中的使用 先说问题,在java应用中,logback的异步Appender是怎么在主线程结束后,停下来的? 复盘 我在一个logback的测试用例中,写了这样的代码和logba ...
- logback中appender继承
实例: <?xml version="1.0" encoding="UTF-8"?> <configuration debug="t ...
- logback中配置的日志文件的生成地址
配置文件如下 <?xml version="1.0" encoding="UTF-8"?> <configuration debug=&quo ...
- logback中logger详解
前言 logback实践笔记 上一篇主要对root进行了实践总结,现在基于上一篇中的springboot代码环境对logback.xml中的logger来进行实践和自己遇到的坑. logger简介 ...
- Logback中文文档(四):Appender
什么是 Appender Appender是负责写记录事件的组件.Appender 必须实现接口"ch.qos.logback.core.Appender".该接口的重要方法总结如 ...
- Logback中文文档(三):配置
在第一部分,我们将介绍配置 logback 的各种方法,给出了很多配置脚本例子.在第二部分,我们将介绍 Joran,它是一个通用配置框架,你可以在自己的项目里使用 Joran. Logback里的配置 ...
- logback中MDC使用
今天在项目发现别人写了很多MDC.put("taskid", "testThread/heart/main_heart");或者MDC.put("ta ...
随机推荐
- ASP.NET Core默认注入方式下如何注入多个实现(多种方式) - sky 胡萝卜星星 - CSDN博客
原文:ASP.NET Core默认注入方式下如何注入多个实现(多种方式) - sky 胡萝卜星星 - CSDN博客 版权声明:本文为starfd原创文章,转载请标明出处. https://blog.c ...
- Python爬虫之简单的图片获取
简单的静态网页的图片获取: import urllib import re import os url = 'http://www.toutiao.com/a6467889113046450702/' ...
- POJ 1260 Pearls (动规)
Pearls Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 7210 Accepted: 3543 Description In ...
- 静态NAT、动态NAT、PAT(端口多路复用)的配置
静态NAT.动态NAT.PAT(端口多路复用)的配置 NAT的实现方式有三种,即静态转换Static Nat.动态转换Dynamic Nat 和 端口多路复用OverLoad. 静态转换 ( ...
- 30 分钟编写一个 Flask 应用
Flask 是一种很赞的Python web框架.它极小,简单,最棒的是它很容易学. 今天我来带你搭建你的第一个Flask web应用!和官方教程 一样,你将搭建你自己的微博客系统:Flaskr.和官 ...
- insertion-sort-list——链表、插入排序、链表插入
Sort a linked list using insertion sort. PS:需要考虑left为head且只有一个数时,此时left->==NULL,若right<left则应更 ...
- 【转载】图说OOP基础(一)
本文用图形化的形式描述OOP的相关知识.对OOP进行系统化的梳理,以便掌握. 涉及知识点: OOP的相关知识 OOP知识[Object-Orientation Programming 面向对象编程]总 ...
- MeiTuanLocateCity
https://github.com/eltld/MeiTuanLocateCity
- 图像处理之图像格式变换和色彩增强---rgb2hsi2hsv 色彩增强
从昨天折腾到今天.再折腾下去我都要上主楼了 大致和灰度图均衡是一样的,主要是不能像平滑什么的直接对R,G,B三个分量进行.这样出来的图像时没法看的.因此我们要对亮度进行均衡.而HSI彩色空间中的分量 ...
- 小心APP应用让你成为“透明人”
随着智能手机和平板电脑的迅猛发展,各式各样的APP在涌入这些移动终端的同一时候.吸费.窃取隐私等恶意程序也随之盛行. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5u ...