zoukankan      html  css  js  c++  java
  • Logback中%X的使用

    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.
    
  • 相关阅读:
    unicode utf-8 ascll
    解压赋值。django导读,http协议,
    手撸orm
    优酷oneday 元类单例 多路复用
    前后台交互, 按钮, 输入栏,列表,选项 ,dom
    jq 事件;jq选择器,与js转化,jq操作文档,属性,类名,全局变量;获取盒子信息
    事件补充;对象操作;字符串类型操作;数组操作;数字类型操作
    if结构 ,循环结构,数据类型转换,逻辑运算符;三个弹出窗口;计算后样式获取,修改;函数
    js 引入与选择器;对文档修改;数据类型基础语法;计算后样式
    伪类边框,字体图标,显隐,overflow,阴影,二维变形
  • 原文地址:https://www.cnblogs.com/hiver/p/9887116.html
Copyright © 2011-2022 走看看