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