001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache license, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the license for the specific language governing permissions and 015 * limitations under the license. 016 */ 017package org.apache.logging.log4j.core.filter; 018 019import java.util.ArrayList; 020import java.util.Arrays; 021import java.util.Collections; 022import java.util.Iterator; 023import java.util.List; 024 025import org.apache.logging.log4j.Level; 026import org.apache.logging.log4j.Marker; 027import org.apache.logging.log4j.core.AbstractLifeCycle; 028import org.apache.logging.log4j.core.Filter; 029import org.apache.logging.log4j.core.LogEvent; 030import org.apache.logging.log4j.core.Logger; 031import org.apache.logging.log4j.core.config.Node; 032import org.apache.logging.log4j.core.config.plugins.Plugin; 033import org.apache.logging.log4j.core.config.plugins.PluginElement; 034import org.apache.logging.log4j.core.config.plugins.PluginFactory; 035import org.apache.logging.log4j.message.Message; 036 037/** 038 * Composes and invokes one or more filters. 039 */ 040@Plugin(name = "filters", category = Node.CATEGORY, printObject = true) 041public final class CompositeFilter extends AbstractLifeCycle implements Iterable<Filter>, Filter { 042 043 private static final long serialVersionUID = 1L; 044 045 private final List<Filter> filters; 046 047 private CompositeFilter() { 048 this.filters = new ArrayList<Filter>(); 049 } 050 051 private CompositeFilter(final List<Filter> filters) { 052 if (filters == null) { 053 this.filters = Collections.unmodifiableList(new ArrayList<Filter>()); 054 return; 055 } 056 this.filters = Collections.unmodifiableList(filters); 057 } 058 059 public CompositeFilter addFilter(final Filter filter) { 060 if (filter == null) { 061 // null does nothing 062 return this; 063 } 064 final List<Filter> filterList = new ArrayList<Filter>(this.filters); 065 filterList.add(filter); 066 return new CompositeFilter(Collections.unmodifiableList(filterList)); 067 } 068 069 public CompositeFilter removeFilter(final Filter filter) { 070 if (filter == null) { 071 // null does nothing 072 return this; 073 } 074 final List<Filter> filterList = new ArrayList<Filter>(this.filters); 075 filterList.remove(filter); 076 return new CompositeFilter(Collections.unmodifiableList(filterList)); 077 } 078 079 @Override 080 public Iterator<Filter> iterator() { 081 return filters.iterator(); 082 } 083 084 public List<Filter> getFilters() { 085 return filters; 086 } 087 088 /** 089 * Returns whether this composite contains any filters. 090 * 091 * @return whether this composite contains any filters. 092 */ 093 public boolean isEmpty() { 094 return this.filters.isEmpty(); 095 } 096 097 public int size() { 098 return filters.size(); 099 } 100 101 @Override 102 public void start() { 103 this.setStarting(); 104 for (final Filter filter : filters) { 105 filter.start(); 106 } 107 this.setStarted(); 108 } 109 110 @Override 111 public void stop() { 112 this.setStopping(); 113 for (final Filter filter : filters) { 114 filter.stop(); 115 } 116 this.setStopped(); 117 } 118 119 /** 120 * Returns the result that should be returned when the filter does not match the event. 121 * 122 * @return the Result that should be returned when the filter does not match the event. 123 */ 124 @Override 125 public Result getOnMismatch() { 126 return Result.NEUTRAL; 127 } 128 129 /** 130 * Returns the result that should be returned when the filter matches the event. 131 * 132 * @return the Result that should be returned when the filter matches the event. 133 */ 134 @Override 135 public Result getOnMatch() { 136 return Result.NEUTRAL; 137 } 138 139 /** 140 * Filter an event. 141 * 142 * @param logger 143 * The Logger. 144 * @param level 145 * The event logging Level. 146 * @param marker 147 * The Marker for the event or null. 148 * @param msg 149 * String text to filter on. 150 * @param params 151 * An array of parameters or null. 152 * @return the Result. 153 */ 154 @Override 155 public Result filter(final Logger logger, final Level level, final Marker marker, final String msg, 156 final Object... params) { 157 Result result = Result.NEUTRAL; 158 for (final Filter filter : filters) { 159 result = filter.filter(logger, level, marker, msg, params); 160 if (result == Result.ACCEPT || result == Result.DENY) { 161 return result; 162 } 163 } 164 return result; 165 } 166 167 /** 168 * Filter an event. 169 * 170 * @param logger 171 * The Logger. 172 * @param level 173 * The event logging Level. 174 * @param marker 175 * The Marker for the event or null. 176 * @param msg 177 * Any Object. 178 * @param t 179 * A Throwable or null. 180 * @return the Result. 181 */ 182 @Override 183 public Result filter(final Logger logger, final Level level, final Marker marker, final Object msg, 184 final Throwable t) { 185 Result result = Result.NEUTRAL; 186 for (final Filter filter : filters) { 187 result = filter.filter(logger, level, marker, msg, t); 188 if (result == Result.ACCEPT || result == Result.DENY) { 189 return result; 190 } 191 } 192 return result; 193 } 194 195 /** 196 * Filter an event. 197 * 198 * @param logger 199 * The Logger. 200 * @param level 201 * The event logging Level. 202 * @param marker 203 * The Marker for the event or null. 204 * @param msg 205 * The Message 206 * @param t 207 * A Throwable or null. 208 * @return the Result. 209 */ 210 @Override 211 public Result filter(final Logger logger, final Level level, final Marker marker, final Message msg, 212 final Throwable t) { 213 Result result = Result.NEUTRAL; 214 for (final Filter filter : filters) { 215 result = filter.filter(logger, level, marker, msg, t); 216 if (result == Result.ACCEPT || result == Result.DENY) { 217 return result; 218 } 219 } 220 return result; 221 } 222 223 /** 224 * Filter an event. 225 * 226 * @param event 227 * The Event to filter on. 228 * @return the Result. 229 */ 230 @Override 231 public Result filter(final LogEvent event) { 232 Result result = Result.NEUTRAL; 233 for (final Filter filter : filters) { 234 result = filter.filter(event); 235 if (result == Result.ACCEPT || result == Result.DENY) { 236 return result; 237 } 238 } 239 return result; 240 } 241 242 @Override 243 public String toString() { 244 final StringBuilder sb = new StringBuilder(); 245 for (final Filter filter : filters) { 246 if (sb.length() == 0) { 247 sb.append('{'); 248 } else { 249 sb.append(", "); 250 } 251 sb.append(filter.toString()); 252 } 253 if (sb.length() > 0) { 254 sb.append('}'); 255 } 256 return sb.toString(); 257 } 258 259 /** 260 * Create a CompositeFilter. 261 * 262 * @param filters 263 * An array of Filters to call. 264 * @return The CompositeFilter. 265 */ 266 @PluginFactory 267 public static CompositeFilter createFilters(@PluginElement("Filters") final Filter[] filters) { 268 final List<Filter> filterList = filters == null || filters.length == 0 ? 269 new ArrayList<Filter>() : Arrays.asList(filters); 270 return new CompositeFilter(filterList); 271 } 272 273}