logback源码阅读-根据源码学扩展点(七)

自定义appender

源码:点击跳转

1.xml定义

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--定义变量下面会使用到-->
    <property name="CHARSET" value="UTF-8"/>

<!--定义appender--> <appender name="dbAppender" class="cn.wine.ms.promotion.logTest.DBAppender"> <Encoder> <pattern>%p|%d{yyyy-MM-dd HH:mm:ss.SSS}|%t|%logger{10}:%line%n %m%n%n</pattern> <charset>${CHARSET}</charset> </Encoder> </appender> <!--与logger产生关联 详见源码<点击跳转>--> <root level="INFO"> <appender-ref ref="dbAppender" /> </root> </configuration>

2.实现类

注dbAppender其实logback有实现 这里只是举例具体类可见:ch.qos.logback.classic.db.DBAppender

@Slf4j
public class DBAppender extends OutputStreamAppender<ILoggingEvent> {
    /**
     * 可以做一些初始化操作
     */
    @Override
    public void start() {
//我们设置自定义outputStream 详见源码<5>
this.setOutputStream(new DBOutPutStream()); super.start(); } @Override protected void append(ILoggingEvent eventObject) { super.append(eventObject); } public static class DBOutPutStream extends OutputStream{ //不用实现 下面重写了父类的方法已经拦截 public void write(int b) throws IOException { } public void write(byte[] b) throws IOException { if(b==null){ return; } String message=new String(b); System.out.println(message); //插入db } } }

但是比如我们需要异步怎么办,logback提供了实现如只需要配置详见源码<点击跳转>- AsyncAppender 注意队列大小可配置 默认是256 源码处:点击跳转

自定义输出格式

<appender name="dbAppender" class="cn.wine.ms.promotion.logTest.DBAppender">
        <Encoder>
            <pattern>%p|%d{yyyy-MM-dd HH:mm:ss.SSS}|%t|%logger{10}:%line%n     %m%n%n</pattern>
            <charset>${CHARSET}</charset>
        </Encoder>
    </appender>

标红部分都是logback定义好的 可选的有 源码处:点击跳转

比如我们增加一个traceId用于链路追踪

1.定义convert实现类

@Slf4j
public class ThreadSharingIdGeneratorMessageConvert extends ClassicConverter {
    ThreadSharingIdGenerator threadSharingIdGenerator = new LogTraceIdGenerator();

    @Override
    public String convert(ILoggingEvent iLoggingEvent) {
        if (iLoggingEvent instanceof LoggingEvent) {
            LoggingEvent event = (LoggingEvent) iLoggingEvent;
            Map<String, String> stringStringMap = event.getLoggerContextVO().getPropertyMap();
            String traceId = stringStringMap.get("traceId");
            if (!StringUtil.isNullOrEmpty(traceId)) {
                return String.format("追溯码:%s",traceId);
            }
        }
        if(!StringUtil.isNullOrEmpty(ArmsUtils.getTraceId())) {
            //如果接入了arms的情况下使用Arms的 内部会判断有没有没有则使用线程共享
            return String.format("[追溯码:%s]", ArmsUtils.getTraceId());
        }
        return "";
    }
}

2.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--定义变量下面会使用到-->
    <property name="CHARSET" value="UTF-8"/>

<!--自定义格式--> <conversionRule conversionWord="tradeId" converterClass="cn.wine.ms.common.armslog.ThreadSharingIdGeneratorMessageConvert" /> <appender name="dbAppender" class="cn.wine.ms.promotion.logTest.DBAppender"> <Encoder> <pattern>%tradeId|%p|%d{yyyy-MM-dd HH:mm:ss.SSS}|%t|%logger{10}:%line%n %m%n%n</pattern> <charset>${CHARSET}</charset> </Encoder> </appender> <root level="INFO"> <appender-ref ref="dbAppender" /> </root> </configuration>

效果请见:点击跳转

原文地址:https://www.cnblogs.com/LQBlog/p/14103113.html