package org.eluder.logback.ext.lmax.appender; import ch.qos.logback.core.Appender; import ch.qos.logback.core.Context; import ch.qos.logback.core.spi.AppenderAttachable; import ch.qos.logback.core.spi.AppenderAttachableImpl; import ch.qos.logback.core.spi.DeferredProcessingAware; import com.lmax.disruptor.WorkHandler; import java.util.Iterator; public class DelegatingDisruptorAppender<E extends DeferredProcessingAware> extends DisruptorAppender<E> implements AppenderAttachable<E> { private final AppenderAttachableImpl<E> appenders = new AppenderAttachableImpl<>(); public DelegatingDisruptorAppender() { setWorkHandler(new AppendersWorkHandler()); } @Override public void start() { lock.lock(); try { if (isStarted()) { return; } startDelegateAppenders(); super.start(); } finally { lock.unlock(); } } @Override public void stop() { lock.lock(); try { if (!isStarted()) { return; } super.stop(); stopDelegateAppenders(); } finally { lock.unlock(); } } protected void startDelegateAppenders() { Iterator<Appender<E>> iter = appenders.iteratorForAppenders(); while (iter.hasNext()) { Appender<E> appender = iter.next(); if (!appender.isStarted()) { appender.start(); } } } protected void stopDelegateAppenders() { Iterator<Appender<E>> iter = appenders.iteratorForAppenders(); while (iter.hasNext()) { Appender<E> appender = iter.next(); if (appender.isStarted()) { appender.stop(); } } } @Override public void addAppender(Appender<E> newAppender) { if (getContext() != null && newAppender.getContext() == null) { newAppender.setContext(getContext()); } appenders.addAppender(newAppender); } @Override public Iterator<Appender<E>> iteratorForAppenders() { return appenders.iteratorForAppenders(); } @Override public Appender<E> getAppender(String name) { return appenders.getAppender(name); } @Override public boolean isAttached(Appender<E> appender) { return appenders.isAttached(appender); } @Override public void detachAndStopAllAppenders() { appenders.detachAndStopAllAppenders(); } @Override public boolean detachAppender(Appender<E> appender) { return appenders.detachAppender(appender); } @Override public boolean detachAppender(String name) { return appenders.detachAppender(name); } @Override public void setContext(Context context) { Iterator<Appender<E>> iter = appenders.iteratorForAppenders(); while (iter.hasNext()) { Appender<E> appender = iter.next(); if (appender.getContext() == null) { appender.setContext(context); } } super.setContext(context); } private class AppendersWorkHandler implements WorkHandler<LogEvent<E>> { @Override public void onEvent(LogEvent<E> event) throws Exception { appenders.appendLoopOnAppenders(event.event); } } }