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 */
017 package org.apache.logging.log4j.core.filter;
018
019 import java.util.ArrayList;
020 import java.util.Arrays;
021 import java.util.Collections;
022 import java.util.Iterator;
023 import java.util.List;
024
025 import org.apache.logging.log4j.Level;
026 import org.apache.logging.log4j.Marker;
027 import org.apache.logging.log4j.core.AbstractLifeCycle;
028 import org.apache.logging.log4j.core.Filter;
029 import org.apache.logging.log4j.core.LogEvent;
030 import org.apache.logging.log4j.core.Logger;
031 import org.apache.logging.log4j.core.config.Node;
032 import org.apache.logging.log4j.core.config.plugins.Plugin;
033 import org.apache.logging.log4j.core.config.plugins.PluginElement;
034 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
035 import 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)
041 public 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 }