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 org.apache.logging.log4j.Level;
020 import org.apache.logging.log4j.Marker;
021 import org.apache.logging.log4j.core.Filter;
022 import org.apache.logging.log4j.core.LifeCycle;
023 import org.apache.logging.log4j.core.LogEvent;
024 import org.apache.logging.log4j.core.Logger;
025 import org.apache.logging.log4j.core.config.plugins.Plugin;
026 import org.apache.logging.log4j.core.config.plugins.PluginElement;
027 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
028 import org.apache.logging.log4j.message.Message;
029
030 import java.util.ArrayList;
031 import java.util.Arrays;
032 import java.util.Collections;
033 import java.util.Iterator;
034 import java.util.List;
035
036 /**
037 * Composes and invokes one or more filters.
038 */
039 @Plugin(name = "filters", category = "Core", printObject = true)
040 public final class CompositeFilter implements Iterable<Filter>, Filter, LifeCycle {
041
042 private final List<Filter> filters;
043 private final boolean hasFilters;
044
045 private boolean isStarted;
046
047 private CompositeFilter() {
048 this.filters = new ArrayList<Filter>();
049 this.hasFilters = false;
050 }
051
052 private CompositeFilter(final List<Filter> filters) {
053 if (filters == null) {
054 this.filters = Collections.unmodifiableList(new ArrayList<Filter>());
055 this.hasFilters = false;
056 return;
057 }
058 this.filters = Collections.unmodifiableList(filters);
059 this.hasFilters = this.filters.size() > 0;
060 }
061
062 public CompositeFilter addFilter(final Filter filter) {
063 final List<Filter> filters = new ArrayList<Filter>(this.filters);
064 filters.add(filter);
065 return new CompositeFilter(Collections.unmodifiableList(filters));
066 }
067
068 public CompositeFilter removeFilter(final Filter filter) {
069 final List<Filter> filters = new ArrayList<Filter>(this.filters);
070 filters.remove(filter);
071 return new CompositeFilter(Collections.unmodifiableList(filters));
072 }
073
074 @Override
075 public Iterator<Filter> iterator() {
076 return filters.iterator();
077 }
078
079 public List<Filter> getFilters() {
080 return filters;
081 }
082
083 public boolean hasFilters() {
084 return hasFilters;
085 }
086
087 public int size() {
088 return filters.size();
089 }
090
091 @Override
092 public void start() {
093 for (final Filter filter : filters) {
094 if (filter instanceof LifeCycle) {
095 ((LifeCycle) filter).start();
096 }
097 }
098 isStarted = true;
099 }
100
101 @Override
102 public void stop() {
103 for (final Filter filter : filters) {
104 if (filter instanceof LifeCycle) {
105 ((LifeCycle) filter).stop();
106 }
107 }
108 isStarted = false;
109 }
110
111 @Override
112 public boolean isStarted() {
113 return isStarted;
114 }
115
116 /**
117 * Returns the result that should be returned when the filter does not match the event.
118 *
119 * @return the Result that should be returned when the filter does not match the event.
120 */
121 @Override
122 public Result getOnMismatch() {
123 return Result.NEUTRAL;
124 }
125
126 /**
127 * Returns the result that should be returned when the filter matches the event.
128 *
129 * @return the Result that should be returned when the filter matches the event.
130 */
131 @Override
132 public Result getOnMatch() {
133 return Result.NEUTRAL;
134 }
135
136 /**
137 * Filter an event.
138 *
139 * @param logger
140 * The Logger.
141 * @param level
142 * The event logging Level.
143 * @param marker
144 * The Marker for the event or null.
145 * @param msg
146 * String text to filter on.
147 * @param params
148 * An array of parameters or null.
149 * @return the Result.
150 */
151 @Override
152 public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
153 final Object... params) {
154 Result result = Result.NEUTRAL;
155 for (final Filter filter : filters) {
156 result = filter.filter(logger, level, marker, msg, params);
157 if (result == Result.ACCEPT || result == Result.DENY) {
158 return result;
159 }
160 }
161 return result;
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 * Any Object.
175 * @param t
176 * A Throwable or null.
177 * @return the Result.
178 */
179 @Override
180 public Result filter(final Logger logger, final Level level, final Marker marker, final Object msg,
181 final Throwable t) {
182 Result result = Result.NEUTRAL;
183 for (final Filter filter : filters) {
184 result = filter.filter(logger, level, marker, msg, t);
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 * The Message
203 * @param t
204 * A Throwable or null.
205 * @return the Result.
206 */
207 @Override
208 public Result filter(final Logger logger, final Level level, final Marker marker, final Message msg,
209 final Throwable t) {
210 Result result = Result.NEUTRAL;
211 for (final Filter filter : filters) {
212 result = filter.filter(logger, level, marker, msg, t);
213 if (result == Result.ACCEPT || result == Result.DENY) {
214 return result;
215 }
216 }
217 return result;
218 }
219
220 /**
221 * Filter an event.
222 *
223 * @param event
224 * The Event to filter on.
225 * @return the Result.
226 */
227 @Override
228 public Result filter(final LogEvent event) {
229 Result result = Result.NEUTRAL;
230 for (final Filter filter : filters) {
231 result = filter.filter(event);
232 if (result == Result.ACCEPT || result == Result.DENY) {
233 return result;
234 }
235 }
236 return result;
237 }
238
239 @Override
240 public String toString() {
241 final StringBuilder sb = new StringBuilder();
242 for (final Filter filter : filters) {
243 if (sb.length() == 0) {
244 sb.append("{");
245 } else {
246 sb.append(", ");
247 }
248 sb.append(filter.toString());
249 }
250 if (sb.length() > 0) {
251 sb.append("}");
252 }
253 return sb.toString();
254 }
255
256 /**
257 * Create a CompositeFilter.
258 *
259 * @param filters
260 * An array of Filters to call.
261 * @return The CompositeFilter.
262 */
263 @PluginFactory
264 public static CompositeFilter createFilters(@PluginElement("filters") final Filter[] filters) {
265 final List<Filter> f = filters == null || filters.length == 0 ?
266 new ArrayList<Filter>() : Arrays.asList(filters);
267 return new CompositeFilter(f);
268 }
269
270 }