//Dstl (c) Crown Copyright 2017 package uk.gov.dstl.baleen.core.logging; import java.util.List; import com.google.common.base.Strings; import com.google.common.collect.Lists; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.filter.Filter; import ch.qos.logback.core.spi.FilterReply; /** * Filter that can be used to filter based on the logger name (usually the class name). * * Does the comparison using a startsWith() test, so that the filter can be used to filter by package as well. * To perform an exact match, then provide a NULL terminated string (e.g. \0) * * */ public class LoggerFilter extends Filter<ILoggingEvent> { private final List<String> loggerName; private final Boolean exclude; /** * Contruct new LoggerFilter * * @param loggerName The name of the logger to match against * @param exclude Should matched loggers be included (false) or excluded (true) */ public LoggerFilter(String loggerName, Boolean exclude){ this.loggerName = Lists.newArrayList(loggerName); this.exclude = exclude; } /** * Construct new LoggerFilter * * @param loggerName A list of loggers to match against * @param exclude Should matched loggers be included (false) or excluded (true) */ public LoggerFilter(List<String> loggerName, Boolean exclude){ this.loggerName = loggerName; this.exclude = exclude; } /** * Decide whether or not to deny the event based on the settings of this filter * * @param event The logging event to test */ @Override public FilterReply decide(ILoggingEvent event) { if(Strings.isNullOrEmpty(event.getLoggerName())){ return FilterReply.DENY; } for(String name : loggerName){ FilterReply ret; if(name.endsWith("/0")){ String nullTerminatedLN = event.getLoggerName()+"/0"; ret = nameMatches(nullTerminatedLN.equals(name)); }else{ ret = nameMatches(event.getLoggerName().startsWith(name)); } ret = shouldReturn(ret); if(ret != null){ return ret; } } if(exclude){ return FilterReply.NEUTRAL; }else{ return FilterReply.DENY; } } private FilterReply shouldReturn(FilterReply ret){ if(exclude && ret == FilterReply.DENY){ return FilterReply.DENY; }else if (!exclude && ret == FilterReply.NEUTRAL){ return FilterReply.NEUTRAL; }else{ return null; } } /** * Determine whether, on matching the logger name, we should reply DENY or NEUTRAL based on the current settings * * @param matches Does it match or not * @return FilterReply.DENY or FilterReply.NEUTRAL */ private FilterReply nameMatches(boolean matches){ if(matches){ return exclude ? FilterReply.DENY : FilterReply.NEUTRAL; }else{ return !exclude ? FilterReply.DENY : FilterReply.NEUTRAL; } } /** * @return the loggerName */ public List<String> getLoggerName() { return loggerName; } /** * @return the exclude */ public Boolean getExclude() { return exclude; } }