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