package dmg.util.logback; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.LoggerContext; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.classic.turbo.TurboFilter; import ch.qos.logback.core.Appender; import ch.qos.logback.core.spi.FilterReply; import com.google.common.collect.Iterators; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import org.slf4j.MDC; import org.slf4j.Marker; import java.util.List; import java.util.Set; import dmg.cells.nucleus.CDC; import dmg.cells.nucleus.CellNucleus; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; public class CellThresholdFilter extends TurboFilter { private FilterReply _onHigherOrEqual = FilterReply.NEUTRAL; private FilterReply _onLower = FilterReply.DENY; private final List<Threshold> _thresholds = Lists.newArrayList(); /** * Adds a default threshold that will be used by all filters * unless overridden. */ public void addThreshold(Threshold threshold) { checkState(!isStarted(), "Cannot add threshold after start"); _thresholds.add(threshold); } /** * Get the FilterReply when the level of the logging request is * higher or equal to the effective threshold. * * @return FilterReply */ public FilterReply getOnHigherOrEqual() { return _onHigherOrEqual; } public void setOnHigherOrEqual(FilterReply onHigherOrEqual) { checkNotNull(onHigherOrEqual); _onHigherOrEqual = onHigherOrEqual; } /** * Get the FilterReply when the level of the logging request is * lower than the effective threshold. * * @return FilterReply */ public FilterReply getOnLower() { return _onLower; } public void setOnLower(FilterReply onLower) { checkNotNull(onLower); _onLower = onLower; } private Set<Appender<ILoggingEvent>> getAppenders(LoggerContext context) { Set<Appender<ILoggingEvent>> appenders = Sets.newHashSet(); for (Logger logger: context.getLoggerList()) { Iterators.addAll(appenders, logger.iteratorForAppenders()); } return appenders; } @Override public void start() { LoggerContext context = (LoggerContext) getContext(); for (Logger logger: context.getLoggerList()) { RootFilterThresholds.setRoot(LoggerName.getInstance(logger.getName()), !logger.isAdditive()); } for (Appender<ILoggingEvent> appender: getAppenders(context)) { String appenderName = appender.getName(); RootFilterThresholds.addAppender(appenderName); for (Threshold threshold: _thresholds) { if (threshold.isApplicableToAppender(appender)) { RootFilterThresholds.setThreshold( threshold.getLogger(), appenderName, threshold.getLevel()); } } CellThresholdFilterCompanion filter = new CellThresholdFilterCompanion(appenderName); filter.start(); appender.addFilter(filter); } super.start(); } @Override public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t) { if (!isStarted()) { return FilterReply.NEUTRAL; } String cell = MDC.get(CDC.MDC_CELL); CellNucleus nucleus = CellNucleus.getLogTargetForCell(cell); if (nucleus == null) { return FilterReply.NEUTRAL; } FilterThresholdSet thresholds = nucleus.getLoggingThresholds(); if (thresholds == null) { return FilterReply.NEUTRAL; } Level threshold = thresholds.getThreshold(logger); if (threshold == null) { return FilterReply.NEUTRAL; } if (level.isGreaterOrEqual(threshold)) { return _onHigherOrEqual; } else { return _onLower; } } }