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.Collections;
22  import java.util.Iterator;
23  import java.util.List;
24  
25  import org.apache.logging.log4j.Level;
26  import org.apache.logging.log4j.Marker;
27  import org.apache.logging.log4j.core.AbstractLifeCycle;
28  import org.apache.logging.log4j.core.Filter;
29  import org.apache.logging.log4j.core.LogEvent;
30  import org.apache.logging.log4j.core.Logger;
31  import org.apache.logging.log4j.core.config.Node;
32  import org.apache.logging.log4j.core.config.plugins.Plugin;
33  import org.apache.logging.log4j.core.config.plugins.PluginElement;
34  import org.apache.logging.log4j.core.config.plugins.PluginFactory;
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 long serialVersionUID = 1L;
44  
45      private final List<Filter> filters;
46  
47      private CompositeFilter() {
48          this.filters = new ArrayList<>();
49      }
50  
51      private CompositeFilter(final List<Filter> filters) {
52          if (filters == null) {
53              this.filters = Collections.unmodifiableList(new ArrayList<Filter>());
54              return;
55          }
56          this.filters = Collections.unmodifiableList(filters);
57      }
58  
59      public CompositeFilter addFilter(final Filter filter) {
60          if (filter == null) {
61              // null does nothing
62              return this;
63          }
64          final List<Filter> filterList = new ArrayList<>(this.filters);
65          filterList.add(filter);
66          return new CompositeFilter(Collections.unmodifiableList(filterList));
67      }
68  
69      public CompositeFilter removeFilter(final Filter filter) {
70          if (filter == null) {
71              // null does nothing
72              return this;
73          }
74          final List<Filter> filterList = new ArrayList<>(this.filters);
75          filterList.remove(filter);
76          return new CompositeFilter(Collections.unmodifiableList(filterList));
77      }
78  
79      @Override
80      public Iterator<Filter> iterator() {
81          return filters.iterator();
82      }
83  
84      public List<Filter> getFilters() {
85          return filters;
86      }
87  
88      /**
89       * Returns whether this composite contains any filters.
90       *
91       * @return whether this composite contains any filters.
92       */
93      public boolean isEmpty() {
94          return this.filters.isEmpty();
95      }
96  
97      public int size() {
98          return filters.size();
99      }
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 }