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 java.util.ArrayList; 020 import java.util.Arrays; 021 import java.util.Collections; 022 import java.util.Iterator; 023 import java.util.List; 024 025 import org.apache.logging.log4j.Level; 026 import org.apache.logging.log4j.Marker; 027 import org.apache.logging.log4j.core.AbstractLifeCycle; 028 import org.apache.logging.log4j.core.Filter; 029 import org.apache.logging.log4j.core.LogEvent; 030 import org.apache.logging.log4j.core.Logger; 031 import org.apache.logging.log4j.core.config.plugins.Plugin; 032 import org.apache.logging.log4j.core.config.plugins.PluginElement; 033 import org.apache.logging.log4j.core.config.plugins.PluginFactory; 034 import org.apache.logging.log4j.message.Message; 035 036 /** 037 * Composes and invokes one or more filters. 038 */ 039 @Plugin(name = "filters", category = "Core", printObject = true) 040 public final class CompositeFilter extends AbstractLifeCycle implements Iterable<Filter>, Filter { 041 042 private final List<Filter> filters; 043 044 private CompositeFilter() { 045 this.filters = new ArrayList<Filter>(); 046 } 047 048 private CompositeFilter(final List<Filter> filters) { 049 if (filters == null) { 050 this.filters = Collections.unmodifiableList(new ArrayList<Filter>()); 051 return; 052 } 053 this.filters = Collections.unmodifiableList(filters); 054 } 055 056 public CompositeFilter addFilter(final Filter filter) { 057 if (filter == null) { 058 // null does nothing 059 return this; 060 } 061 final List<Filter> filterList = new ArrayList<Filter>(this.filters); 062 filterList.add(filter); 063 return new CompositeFilter(Collections.unmodifiableList(filterList)); 064 } 065 066 public CompositeFilter removeFilter(final Filter filter) { 067 if (filter == null) { 068 // null does nothing 069 return this; 070 } 071 final List<Filter> filterList = new ArrayList<Filter>(this.filters); 072 filterList.remove(filter); 073 return new CompositeFilter(Collections.unmodifiableList(filterList)); 074 } 075 076 @Override 077 public Iterator<Filter> iterator() { 078 return filters.iterator(); 079 } 080 081 public List<Filter> getFilters() { 082 return filters; 083 } 084 085 /** 086 * Returns whether this composite contains any filters. 087 * 088 * @return whether this composite contains any filters. 089 */ 090 public boolean isEmpty() { 091 return this.filters.isEmpty(); 092 } 093 094 public int size() { 095 return filters.size(); 096 } 097 098 @Override 099 public void start() { 100 this.setStarting(); 101 for (final Filter filter : filters) { 102 filter.start(); 103 } 104 this.setStarted(); 105 } 106 107 @Override 108 public void stop() { 109 this.setStopping(); 110 for (final Filter filter : filters) { 111 filter.stop(); 112 } 113 this.setStopped(); 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> filterList = filters == null || filters.length == 0 ? 266 new ArrayList<Filter>() : Arrays.asList(filters); 267 return new CompositeFilter(filterList); 268 } 269 270 }