View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache license, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the license for the specific language governing permissions and
15   * limitations under the license.
16   */
17  package org.apache.logging.log4j.core.filter;
18  
19  import java.util.ArrayList;
20  import java.util.Arrays;
21  import java.util.Iterator;
22  import java.util.List;
23  
24  import org.apache.logging.log4j.Level;
25  import org.apache.logging.log4j.Marker;
26  import org.apache.logging.log4j.core.AbstractLifeCycle;
27  import org.apache.logging.log4j.core.Filter;
28  import org.apache.logging.log4j.core.LogEvent;
29  import org.apache.logging.log4j.core.Logger;
30  import org.apache.logging.log4j.core.config.Node;
31  import org.apache.logging.log4j.core.config.plugins.Plugin;
32  import org.apache.logging.log4j.core.config.plugins.PluginElement;
33  import org.apache.logging.log4j.core.config.plugins.PluginFactory;
34  import org.apache.logging.log4j.core.util.ObjectArrayIterator;
35  import org.apache.logging.log4j.message.Message;
36  
37  /**
38   * Composes and invokes one or more filters.
39   */
40  @Plugin(name = "filters", category = Node.CATEGORY, printObject = true)
41  public final class CompositeFilter extends AbstractLifeCycle implements Iterable<Filter>, Filter {
42  
43      private static final Filter[] EMPTY_FILTERS = new Filter[0];
44      private final Filter[] filters;
45  
46      private CompositeFilter() {
47          this.filters = EMPTY_FILTERS;
48      }
49  
50      private CompositeFilter(final Filter[] filters) {
51          this.filters = filters == null ? EMPTY_FILTERS : filters;
52      }
53  
54      public CompositeFilter addFilter(final Filter filter) {
55          if (filter == null) {
56              // null does nothing
57              return this;
58          }
59          if (filter instanceof CompositeFilter) {
60              final int size = this.filters.length + ((CompositeFilter) filter).size();
61              final Filter[] copy = Arrays.copyOf(this.filters, size);
62              final int index = this.filters.length;
63              for (final Filter currentFilter : ((CompositeFilter) filter).filters) {
64                  copy[index] = currentFilter;
65              }
66              return new CompositeFilter(copy);
67          } else {
68              final Filter[] copy = Arrays.copyOf(this.filters, this.filters.length + 1);
69              copy[this.filters.length] = filter;
70              return new CompositeFilter(copy);
71          }
72      }
73  
74      public CompositeFilter removeFilter(final Filter filter) {
75          if (filter == null) {
76              // null does nothing
77              return this;
78          }
79          // This is not a great implementation but simpler than copying Apache Commons
80          // Lang ArrayUtils.removeElement() and associated bits (MutableInt),
81          // which is OK since removing a filter should not be on the critical path.
82          final List<Filter> filterList = new ArrayList<>(Arrays.asList(this.filters));
83          if (filter instanceof CompositeFilter) {
84              for (final Filter currentFilter : ((CompositeFilter) filter).filters) {
85                  filterList.remove(currentFilter);
86              }
87          } else {
88              filterList.remove(filter);
89          }
90          return new CompositeFilter(filterList.toArray(new Filter[this.filters.length - 1]));
91      }
92  
93      @Override
94      public Iterator<Filter> iterator() {
95          return new ObjectArrayIterator<>(filters);
96      }
97  
98      /**
99       * Gets a new list over the internal filter array.
100      *
101      * @return a new list over the internal filter array
102      * @deprecated Use {@link #getFiltersArray()}
103      */
104     @Deprecated
105     public List<Filter> getFilters() {
106         return Arrays.asList(filters);
107     }
108 
109     public Filter[] getFiltersArray() {
110         return filters;
111     }
112 
113     /**
114      * Returns whether this composite contains any filters.
115      *
116      * @return whether this composite contains any filters.
117      */
118     public boolean isEmpty() {
119         return this.filters.length == 0;
120     }
121 
122     public int size() {
123         return filters.length;
124     }
125 
126     @Override
127     public void start() {
128         this.setStarting();
129         for (final Filter filter : filters) {
130             filter.start();
131         }
132         this.setStarted();
133     }
134 
135     @Override
136     public void stop() {
137         this.setStopping();
138         for (final Filter filter : filters) {
139             filter.stop();
140         }
141         this.setStopped();
142     }
143 
144     /**
145      * Returns the result that should be returned when the filter does not match the event.
146      *
147      * @return the Result that should be returned when the filter does not match the event.
148      */
149     @Override
150     public Result getOnMismatch() {
151         return Result.NEUTRAL;
152     }
153 
154     /**
155      * Returns the result that should be returned when the filter matches the event.
156      *
157      * @return the Result that should be returned when the filter matches the event.
158      */
159     @Override
160     public Result getOnMatch() {
161         return Result.NEUTRAL;
162     }
163 
164     /**
165      * Filter an event.
166      *
167      * @param logger
168      *            The Logger.
169      * @param level
170      *            The event logging Level.
171      * @param marker
172      *            The Marker for the event or null.
173      * @param msg
174      *            String text to filter on.
175      * @param params
176      *            An array of parameters or null.
177      * @return the Result.
178      */
179     @Override
180     public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
181             final Object... params) {
182         Result result = Result.NEUTRAL;
183         for (int i = 0; i < filters.length; i++) {
184             result = filters[i].filter(logger, level, marker, msg, params);
185             if (result == Result.ACCEPT || result == Result.DENY) {
186                 return result;
187             }
188         }
189         return result;
190     }
191 
192     /**
193      * Filter an event.
194      *
195      * @param logger
196      *            The Logger.
197      * @param level
198      *            The event logging Level.
199      * @param marker
200      *            The Marker for the event or null.
201      * @param msg
202      *            String text to filter on.
203      * @param p0 the message parameters
204      * @return the Result.
205      */
206     @Override
207     public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
208             final Object p0) {
209         Result result = Result.NEUTRAL;
210         for (int i = 0; i < filters.length; i++) {
211             result = filters[i].filter(logger, level, marker, msg, p0);
212             if (result == Result.ACCEPT || result == Result.DENY) {
213                 return result;
214             }
215         }
216         return result;
217     }
218 
219     /**
220      * Filter an event.
221      *
222      * @param logger
223      *            The Logger.
224      * @param level
225      *            The event logging Level.
226      * @param marker
227      *            The Marker for the event or null.
228      * @param msg
229      *            String text to filter on.
230      * @param p0 the message parameters
231      * @param p1 the message parameters
232      * @return the Result.
233      */
234     @Override
235     public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
236             final Object p0, final Object p1) {
237         Result result = Result.NEUTRAL;
238         for (int i = 0; i < filters.length; i++) {
239             result = filters[i].filter(logger, level, marker, msg, p0, p1);
240             if (result == Result.ACCEPT || result == Result.DENY) {
241                 return result;
242             }
243         }
244         return result;
245     }
246 
247     /**
248      * Filter an event.
249      *
250      * @param logger
251      *            The Logger.
252      * @param level
253      *            The event logging Level.
254      * @param marker
255      *            The Marker for the event or null.
256      * @param msg
257      *            String text to filter on.
258      * @param p0 the message parameters
259      * @param p1 the message parameters
260      * @param p2 the message parameters
261      * @return the Result.
262      */
263     @Override
264     public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
265             final Object p0, final Object p1, final Object p2) {
266         Result result = Result.NEUTRAL;
267         for (int i = 0; i < filters.length; i++) {
268             result = filters[i].filter(logger, level, marker, msg, p0, p1, p2);
269             if (result == Result.ACCEPT || result == Result.DENY) {
270                 return result;
271             }
272         }
273         return result;
274     }
275 
276     /**
277      * Filter an event.
278      *
279      * @param logger
280      *            The Logger.
281      * @param level
282      *            The event logging Level.
283      * @param marker
284      *            The Marker for the event or null.
285      * @param msg
286      *            String text to filter on.
287      * @param p0 the message parameters
288      * @param p1 the message parameters
289      * @param p2 the message parameters
290      * @param p3 the message parameters
291      * @return the Result.
292      */
293     @Override
294     public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
295             final Object p0, final Object p1, final Object p2, final Object p3) {
296         Result result = Result.NEUTRAL;
297         for (int i = 0; i < filters.length; i++) {
298             result = filters[i].filter(logger, level, marker, msg, p0, p1, p2, p3);
299             if (result == Result.ACCEPT || result == Result.DENY) {
300                 return result;
301             }
302         }
303         return result;
304     }
305 
306     /**
307      * Filter an event.
308      *
309      * @param logger
310      *            The Logger.
311      * @param level
312      *            The event logging Level.
313      * @param marker
314      *            The Marker for the event or null.
315      * @param msg
316      *            String text to filter on.
317      * @param p0 the message parameters
318      * @param p1 the message parameters
319      * @param p2 the message parameters
320      * @param p3 the message parameters
321      * @param p4 the message parameters
322      * @return the Result.
323      */
324     @Override
325     public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
326             final Object p0, final Object p1, final Object p2, final Object p3,
327             final Object p4) {
328         Result result = Result.NEUTRAL;
329         for (int i = 0; i < filters.length; i++) {
330             result = filters[i].filter(logger, level, marker, msg, p0, p1, p2, p3, p4);
331             if (result == Result.ACCEPT || result == Result.DENY) {
332                 return result;
333             }
334         }
335         return result;
336     }
337 
338     /**
339      * Filter an event.
340      *
341      * @param logger
342      *            The Logger.
343      * @param level
344      *            The event logging Level.
345      * @param marker
346      *            The Marker for the event or null.
347      * @param msg
348      *            String text to filter on.
349      * @param p0 the message parameters
350      * @param p1 the message parameters
351      * @param p2 the message parameters
352      * @param p3 the message parameters
353      * @param p4 the message parameters
354      * @param p5 the message parameters
355      * @return the Result.
356      */
357     @Override
358     public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
359             final Object p0, final Object p1, final Object p2, final Object p3,
360             final Object p4, final Object p5) {
361         Result result = Result.NEUTRAL;
362         for (int i = 0; i < filters.length; i++) {
363             result = filters[i].filter(logger, level, marker, msg, p0, p1, p2, p3, p4, p5);
364             if (result == Result.ACCEPT || result == Result.DENY) {
365                 return result;
366             }
367         }
368         return result;
369     }
370 
371     /**
372      * Filter an event.
373      *
374      * @param logger
375      *            The Logger.
376      * @param level
377      *            The event logging Level.
378      * @param marker
379      *            The Marker for the event or null.
380      * @param msg
381      *            String text to filter on.
382      * @param p0 the message parameters
383      * @param p1 the message parameters
384      * @param p2 the message parameters
385      * @param p3 the message parameters
386      * @param p4 the message parameters
387      * @param p5 the message parameters
388      * @param p6 the message parameters
389      * @return the Result.
390      */
391     @Override
392     public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
393             final Object p0, final Object p1, final Object p2, final Object p3,
394             final Object p4, final Object p5, final Object p6) {
395         Result result = Result.NEUTRAL;
396         for (int i = 0; i < filters.length; i++) {
397             result = filters[i].filter(logger, level, marker, msg, p0, p1, p2, p3, p4, p5, p6);
398             if (result == Result.ACCEPT || result == Result.DENY) {
399                 return result;
400             }
401         }
402         return result;
403     }
404 
405     /**
406      * Filter an event.
407      *
408      * @param logger
409      *            The Logger.
410      * @param level
411      *            The event logging Level.
412      * @param marker
413      *            The Marker for the event or null.
414      * @param msg
415      *            String text to filter on.
416      * @param p0 the message parameters
417      * @param p1 the message parameters
418      * @param p2 the message parameters
419      * @param p3 the message parameters
420      * @param p4 the message parameters
421      * @param p5 the message parameters
422      * @param p6 the message parameters
423      * @param p7 the message parameters
424      * @return the Result.
425      */
426     @Override
427     public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
428             final Object p0, final Object p1, final Object p2, final Object p3,
429             final Object p4, final Object p5, final Object p6,
430             final Object p7) {
431         Result result = Result.NEUTRAL;
432         for (int i = 0; i < filters.length; i++) {
433             result = filters[i].filter(logger, level, marker, msg, p0, p1, p2, p3, p4, p5, p6, p7);
434             if (result == Result.ACCEPT || result == Result.DENY) {
435                 return result;
436             }
437         }
438         return result;
439     }
440 
441     /**
442      * Filter an event.
443      *
444      * @param logger
445      *            The Logger.
446      * @param level
447      *            The event logging Level.
448      * @param marker
449      *            The Marker for the event or null.
450      * @param msg
451      *            String text to filter on.
452      * @param p0 the message parameters
453      * @param p1 the message parameters
454      * @param p2 the message parameters
455      * @param p3 the message parameters
456      * @param p4 the message parameters
457      * @param p5 the message parameters
458      * @param p6 the message parameters
459      * @param p7 the message parameters
460      * @param p8 the message parameters
461      * @return the Result.
462      */
463     @Override
464     public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
465             final Object p0, final Object p1, final Object p2, final Object p3,
466             final Object p4, final Object p5, final Object p6,
467             final Object p7, final Object p8) {
468         Result result = Result.NEUTRAL;
469         for (int i = 0; i < filters.length; i++) {
470             result = filters[i].filter(logger, level, marker, msg, p0, p1, p2, p3, p4, p5, p6, p7, p8);
471             if (result == Result.ACCEPT || result == Result.DENY) {
472                 return result;
473             }
474         }
475         return result;
476     }
477 
478     /**
479      * Filter an event.
480      *
481      * @param logger
482      *            The Logger.
483      * @param level
484      *            The event logging Level.
485      * @param marker
486      *            The Marker for the event or null.
487      * @param msg
488      *            String text to filter on.
489      * @param p0 the message parameters
490      * @param p1 the message parameters
491      * @param p2 the message parameters
492      * @param p3 the message parameters
493      * @param p4 the message parameters
494      * @param p5 the message parameters
495      * @param p6 the message parameters
496      * @param p7 the message parameters
497      * @param p8 the message parameters
498      * @param p9 the message parameters
499      * @return the Result.
500      */
501     @Override
502     public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
503             final Object p0, final Object p1, final Object p2, final Object p3,
504             final Object p4, final Object p5, final Object p6,
505             final Object p7, final Object p8, final Object p9) {
506         Result result = Result.NEUTRAL;
507         for (int i = 0; i < filters.length; i++) {
508             result = filters[i].filter(logger, level, marker, msg, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
509             if (result == Result.ACCEPT || result == Result.DENY) {
510                 return result;
511             }
512         }
513         return result;
514     }
515 
516     /**
517      * Filter an event.
518      *
519      * @param logger
520      *            The Logger.
521      * @param level
522      *            The event logging Level.
523      * @param marker
524      *            The Marker for the event or null.
525      * @param msg
526      *            Any Object.
527      * @param t
528      *            A Throwable or null.
529      * @return the Result.
530      */
531     @Override
532     public Result filter(final Logger logger, final Level level, final Marker marker, final Object msg,
533             final Throwable t) {
534         Result result = Result.NEUTRAL;
535         for (int i = 0; i < filters.length; i++) {
536             result = filters[i].filter(logger, level, marker, msg, t);
537             if (result == Result.ACCEPT || result == Result.DENY) {
538                 return result;
539             }
540         }
541         return result;
542     }
543 
544     /**
545      * Filter an event.
546      *
547      * @param logger
548      *            The Logger.
549      * @param level
550      *            The event logging Level.
551      * @param marker
552      *            The Marker for the event or null.
553      * @param msg
554      *            The Message
555      * @param t
556      *            A Throwable or null.
557      * @return the Result.
558      */
559     @Override
560     public Result filter(final Logger logger, final Level level, final Marker marker, final Message msg,
561             final Throwable t) {
562         Result result = Result.NEUTRAL;
563         for (int i = 0; i < filters.length; i++) {
564             result = filters[i].filter(logger, level, marker, msg, t);
565             if (result == Result.ACCEPT || result == Result.DENY) {
566                 return result;
567             }
568         }
569         return result;
570     }
571 
572     /**
573      * Filter an event.
574      *
575      * @param event
576      *            The Event to filter on.
577      * @return the Result.
578      */
579     @Override
580     public Result filter(final LogEvent event) {
581         Result result = Result.NEUTRAL;
582         for (int i = 0; i < filters.length; i++) {
583             result = filters[i].filter(event);
584             if (result == Result.ACCEPT || result == Result.DENY) {
585                 return result;
586             }
587         }
588         return result;
589     }
590 
591     @Override
592     public String toString() {
593         final StringBuilder sb = new StringBuilder();
594         for (int i = 0; i < filters.length; i++) {
595             if (sb.length() == 0) {
596                 sb.append('{');
597             } else {
598                 sb.append(", ");
599             }
600             sb.append(filters[i].toString());
601         }
602         if (sb.length() > 0) {
603             sb.append('}');
604         }
605         return sb.toString();
606     }
607 
608     /**
609      * Create a CompositeFilter.
610      *
611      * @param filters
612      *            An array of Filters to call.
613      * @return The CompositeFilter.
614      */
615     @PluginFactory
616     public static CompositeFilter createFilters(@PluginElement("Filters") final Filter[] filters) {
617         return new CompositeFilter(filters);
618     }
619 
620 }