reactor-logback的AsyncAppender执行流程源码解读

 更新时间:2023年12月18日 09:54:52   作者:codecraft  
这篇文章主要为大家介绍了reactor-logback的AsyncAppender执行流程源码解读,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

本文主要研究一下reactor-logback的AsyncAppender

AsyncAppender

reactor-logback/src/main/java/reactor/logback/AsyncAppender.java

public class AsyncAppender extends ContextAwareBase
        implements Appender<ILoggingEvent>, AppenderAttachable<ILoggingEvent>,
                   CoreSubscriber<ILoggingEvent> {
    private final AppenderAttachableImpl<ILoggingEvent>    aai      =
            new AppenderAttachableImpl<ILoggingEvent>();
    private final FilterAttachableImpl<ILoggingEvent>      fai      =
            new FilterAttachableImpl<ILoggingEvent>();
    private final AtomicReference<Appender<ILoggingEvent>> delegate =
            new AtomicReference<Appender<ILoggingEvent>>();
    private String                            name;
    private WorkQueueProcessor<ILoggingEvent> processor;
    private int     backlog           = 1024 * 1024;
    private boolean includeCallerData = false;
    private boolean started           = false;
    //......
}
AsyncAppender继承了ContextAwareBase,同时实现了Appender、AppenderAttachable、CoreSubscriber接口

CoreSubscriber

reactor/core/CoreSubscriber.java

public interface CoreSubscriber<T> extends Subscriber<T> {
    /**
     * Request a {@link Context} from dependent components which can include downstream
     * operators during subscribing or a terminal {@link org.reactivestreams.Subscriber}.
     *
     * @return a resolved context or {@link Context#empty()}
     */
    default Context currentContext(){
        return Context.empty();
    }
    /**
     * Implementors should initialize any state used by {@link #onNext(Object)} before
     * calling {@link Subscription#request(long)}. Should further {@code onNext} related
     * state modification occur, thread-safety will be required.
     * <p>
     *    Note that an invalid request {@code <= 0} will not produce an onError and
     *    will simply be ignored or reported through a debug-enabled
     *    {@link reactor.util.Logger}.
     *
     * {@inheritDoc}
     */
    @Override
    void onSubscribe(Subscription s);
}
CoreSubscriber继承了Subscriber接口,Subscriber接口定义了onSubscribe(Subscription s)、onNext、onError、onComplete方法

onSubscribe

public void onSubscribe(Subscription s) {
        try {
            doStart();
        }
        catch (Throwable t) {
            addError(t.getMessage(), t);
        }
        finally {
            started = true;
            s.request(Long.MAX_VALUE);
        }
    }
    protected void doStart() {
    }
onSubscribe方法执行doStart,标记started为true,同时触发s.request(Long.MAX_VALUE)

onNext

public void onNext(ILoggingEvent iLoggingEvent) {
        aai.appendLoopOnAppenders(iLoggingEvent);
    }
onNext调用AppenderAttachableImpl的appendLoopOnAppenders方法

onError

public void onError(Throwable t) {
        addError(t.getMessage(), t);
    }
onError主要是添加错误信息到logback的status

onComplete

public void onComplete() {
        try {
            Appender<ILoggingEvent> appender = delegate.getAndSet(null);
            if (appender != null){
                doStop();
                appender.stop();
                aai.detachAndStopAllAppenders();
            }
        }
        catch (Throwable t) {
            addError(t.getMessage(), t);
        }
        finally {
            started = false;
        }
    }
    protected void doStop() {
    }
onComplete则执行doStop、appender.stop()、aai.detachAndStopAllAppenders(),最后标记started为false

Appender.doAppend

public void doAppend(ILoggingEvent evt) throws LogbackException {
        if (getFilterChainDecision(evt) == FilterReply.DENY) {
            return;
        }
        evt.prepareForDeferredProcessing();
        if (includeCallerData) {
            evt.getCallerData();
        }
        try {
            queueLoggingEvent(evt);
        }
        catch (Throwable t) {
            addError(t.getMessage(), t);
        }
    }

    protected void queueLoggingEvent(ILoggingEvent evt) {
        if (null != delegate.get()) {
            processor.onNext(evt);
        }
    }
doAppend方法先判断是否需要DENY,是则直接返回,之后主要执行queueLoggingEvent,它在delegate不为null时执行processor.onNext(evt)

LifeCycle.start

public void start() {
        startDelegateAppender();
        processor = WorkQueueProcessor.<ILoggingEvent>builder().name("logger")
                                                               .bufferSize(backlog)
                                                               .autoCancel(false)
                                                               .build();
        processor.subscribe(this);
    }
    private void startDelegateAppender() {
        Appender<ILoggingEvent> delegateAppender = delegate.get();
        if (null != delegateAppender && !delegateAppender.isStarted()) {
            delegateAppender.start();
        }
    }
    public void addAppender(Appender<ILoggingEvent> newAppender) {
        if (delegate.compareAndSet(null, newAppender)) {
            aai.addAppender(newAppender);
        }
        else {
            throw new IllegalArgumentException(delegate.get() + " already attached.");
        }
    }
start方法执行startDelegateAppender,然后创建WorkQueueProcessor(默认bufferSize为1024 * 1024),并subscribe当前实例;addAppender方法会设置delegate,并往AppenderAttachableImpl添加appender

stop

public void stop() {
        processor.onComplete();
    }
stop方法执行processor.onComplete()

小结

reactor-logback基于WorkQueueProcessor提供了另外一种AsyncAppender,它不是基于BlockingQueue而是基于RingBuffer来实现的。其onSubscribe方法执行doStart,标记started为true,同时触发s.request(Long.MAX_VALUE);onNext调用AppenderAttachableImpl的appendLoopOnAppenders方法;onComplete则执行doStop、appender.stop()、aai.detachAndStopAllAppenders(),最后标记started为false;doAppend方法先判断是否需要DENY,是则直接返回,之后主要执行queueLoggingEvent,它在delegate不为null时执行processor.onNext(evt)。

以上就是reactor-logback的AsyncAppender执行流程源码解读的详细内容,更多关于reactor-logback AsyncAppender的资料请关注脚本之家其它相关文章!

相关文章

  • 基于java涉及父子类的异常详解

    基于java涉及父子类的异常详解

    下面小编就为大家带来一篇基于java涉及父子类的异常详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09
  • Java实现在PPT中创建SmartArt图形的示例代码

    Java实现在PPT中创建SmartArt图形的示例代码

    SmartArt其实就是一个文字的可视化工具,用户可在PowerPoint,Word,Excel中使用该特性创建各种图形图表。本文就将为您介绍如何通过Java应用程序在PPT中创建SmartArt图形,需要的可以参考一下
    2023-04-04
  • Java利用redis zset实现延时任务详解

    Java利用redis zset实现延时任务详解

    zset作为redis的有序集合数据结构存在,排序的依据就是score。本文就将利用zset score这个排序的这个特性,来实现延时任务,感兴趣的可以了解一下
    2022-08-08
  • spring aop实现接口超时处理组件的代码详解

    spring aop实现接口超时处理组件的代码详解

    这篇文章给大家介绍了spring aop实现接口超时处理组件,文中有详细的实现思路,并通过代码示例给大家介绍的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-02-02
  • SpringBoot实现缓存预热的几种常用方案

    SpringBoot实现缓存预热的几种常用方案

    缓存预热是指在 Spring Boot 项目启动时,预先将数据加载到缓存系统(如 Redis)中的一种机制,本文给大家介绍了SpringBoot实现缓存预热的几种常用方案,并通过代码示例讲解的非常详细,需要的朋友可以参考下
    2024-02-02
  • mybatis拦截器与分页插件实例教程

    mybatis拦截器与分页插件实例教程

    Mybatis拦截器常常会被用来进行分页处理。所以下面这篇文章主要给大家介绍了关于mybatis拦截器与分页插件的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用mybatis具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-04-04
  • Java try catch finally异常处理组合详解

    Java try catch finally异常处理组合详解

    这篇文章主要介绍了Java try catch finally异常处理组合详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05
  • 详解Spring MVC的异步模式(高性能的关键)

    详解Spring MVC的异步模式(高性能的关键)

    本篇文章主要介绍了详解Spring MVC的异步模式(高性能的关键),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02
  • SpringBoot+微信小程序实现文件上传与下载功能详解

    SpringBoot+微信小程序实现文件上传与下载功能详解

    这篇文章主要为大家介绍了SpringBoot整合微信小程序实现文件上传与下载功能,文中的实现步骤讲解详细,快跟随小编一起学习一下吧
    2022-03-03
  • Java中Properties的使用详解

    Java中Properties的使用详解

    这篇文章主要介绍了Java中Properties的使用详解的相关资料,需要的朋友可以参考下
    2016-05-05

最新评论