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 */ 017package org.apache.logging.log4j.core.filter; 018 019import java.util.ArrayList; 020import java.util.Arrays; 021import java.util.Iterator; 022import java.util.List; 023 024import org.apache.logging.log4j.Level; 025import org.apache.logging.log4j.Marker; 026import org.apache.logging.log4j.core.AbstractLifeCycle; 027import org.apache.logging.log4j.core.Filter; 028import org.apache.logging.log4j.core.LogEvent; 029import org.apache.logging.log4j.core.Logger; 030import org.apache.logging.log4j.core.config.Node; 031import org.apache.logging.log4j.core.config.plugins.Plugin; 032import org.apache.logging.log4j.core.config.plugins.PluginElement; 033import org.apache.logging.log4j.core.config.plugins.PluginFactory; 034import org.apache.logging.log4j.core.util.ObjectArrayIterator; 035import org.apache.logging.log4j.message.Message; 036 037/** 038 * Composes and invokes one or more filters. 039 */ 040@Plugin(name = "filters", category = Node.CATEGORY, printObject = true) 041public final class CompositeFilter extends AbstractLifeCycle implements Iterable<Filter>, Filter { 042 043 private static final Filter[] EMPTY_FILTERS = new Filter[0]; 044 private final Filter[] filters; 045 046 private CompositeFilter() { 047 this.filters = EMPTY_FILTERS; 048 } 049 050 private CompositeFilter(final Filter[] filters) { 051 this.filters = filters == null ? EMPTY_FILTERS : filters; 052 } 053 054 public CompositeFilter addFilter(final Filter filter) { 055 if (filter == null) { 056 // null does nothing 057 return this; 058 } 059 if (filter instanceof CompositeFilter) { 060 final int size = this.filters.length + ((CompositeFilter) filter).size(); 061 final Filter[] copy = Arrays.copyOf(this.filters, size); 062 final int index = this.filters.length; 063 for (final Filter currentFilter : ((CompositeFilter) filter).filters) { 064 copy[index] = currentFilter; 065 } 066 return new CompositeFilter(copy); 067 } else { 068 final Filter[] copy = Arrays.copyOf(this.filters, this.filters.length + 1); 069 copy[this.filters.length] = filter; 070 return new CompositeFilter(copy); 071 } 072 } 073 074 public CompositeFilter removeFilter(final Filter filter) { 075 if (filter == null) { 076 // null does nothing 077 return this; 078 } 079 // This is not a great implementation but simpler than copying Apache Commons 080 // Lang ArrayUtils.removeElement() and associated bits (MutableInt), 081 // which is OK since removing a filter should not be on the critical path. 082 final List<Filter> filterList = new ArrayList<>(Arrays.asList(this.filters)); 083 if (filter instanceof CompositeFilter) { 084 for (final Filter currentFilter : ((CompositeFilter) filter).filters) { 085 filterList.remove(currentFilter); 086 } 087 } else { 088 filterList.remove(filter); 089 } 090 return new CompositeFilter(filterList.toArray(new Filter[this.filters.length - 1])); 091 } 092 093 @Override 094 public Iterator<Filter> iterator() { 095 return new ObjectArrayIterator<>(filters); 096 } 097 098 /** 099 * Gets a new list over the internal filter array. 100 * 101 * @return a new list over the internal filter array 102 * @deprecated Use {@link #getFiltersArray()} 103 */ 104 @Deprecated 105 public List<Filter> getFilters() { 106 return Arrays.asList(filters); 107 } 108 109 public Filter[] getFiltersArray() { 110 return filters; 111 } 112 113 /** 114 * Returns whether this composite contains any filters. 115 * 116 * @return whether this composite contains any filters. 117 */ 118 public boolean isEmpty() { 119 return this.filters.length == 0; 120 } 121 122 public int size() { 123 return filters.length; 124 } 125 126 @Override 127 public void start() { 128 this.setStarting(); 129 for (final Filter filter : filters) { 130 filter.start(); 131 } 132 this.setStarted(); 133 } 134 135 @Override 136 public void stop() { 137 this.setStopping(); 138 for (final Filter filter : filters) { 139 filter.stop(); 140 } 141 this.setStopped(); 142 } 143 144 /** 145 * Returns the result that should be returned when the filter does not match the event. 146 * 147 * @return the Result that should be returned when the filter does not match the event. 148 */ 149 @Override 150 public Result getOnMismatch() { 151 return Result.NEUTRAL; 152 } 153 154 /** 155 * Returns the result that should be returned when the filter matches the event. 156 * 157 * @return the Result that should be returned when the filter matches the event. 158 */ 159 @Override 160 public Result getOnMatch() { 161 return Result.NEUTRAL; 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 * String text to filter on. 175 * @param params 176 * An array of parameters or null. 177 * @return the Result. 178 */ 179 @Override 180 public Result filter(final Logger logger, final Level level, final Marker marker, final String msg, 181 final Object... params) { 182 Result result = Result.NEUTRAL; 183 for (int i = 0; i < filters.length; i++) { 184 result = filters[i].filter(logger, level, marker, msg, params); 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 * String text to filter on. 203 * @param p0 the message parameters 204 * @return the Result. 205 */ 206 @Override 207 public Result filter(final Logger logger, final Level level, final Marker marker, final String msg, 208 final Object p0) { 209 Result result = Result.NEUTRAL; 210 for (int i = 0; i < filters.length; i++) { 211 result = filters[i].filter(logger, level, marker, msg, p0); 212 if (result == Result.ACCEPT || result == Result.DENY) { 213 return result; 214 } 215 } 216 return result; 217 } 218 219 /** 220 * Filter an event. 221 * 222 * @param logger 223 * The Logger. 224 * @param level 225 * The event logging Level. 226 * @param marker 227 * The Marker for the event or null. 228 * @param msg 229 * String text to filter on. 230 * @param p0 the message parameters 231 * @param p1 the message parameters 232 * @return the Result. 233 */ 234 @Override 235 public Result filter(final Logger logger, final Level level, final Marker marker, final String msg, 236 final Object p0, final Object p1) { 237 Result result = Result.NEUTRAL; 238 for (int i = 0; i < filters.length; i++) { 239 result = filters[i].filter(logger, level, marker, msg, p0, p1); 240 if (result == Result.ACCEPT || result == Result.DENY) { 241 return result; 242 } 243 } 244 return result; 245 } 246 247 /** 248 * Filter an event. 249 * 250 * @param logger 251 * The Logger. 252 * @param level 253 * The event logging Level. 254 * @param marker 255 * The Marker for the event or null. 256 * @param msg 257 * String text to filter on. 258 * @param p0 the message parameters 259 * @param p1 the message parameters 260 * @param p2 the message parameters 261 * @return the Result. 262 */ 263 @Override 264 public Result filter(final Logger logger, final Level level, final Marker marker, final String msg, 265 final Object p0, final Object p1, final Object p2) { 266 Result result = Result.NEUTRAL; 267 for (int i = 0; i < filters.length; i++) { 268 result = filters[i].filter(logger, level, marker, msg, p0, p1, p2); 269 if (result == Result.ACCEPT || result == Result.DENY) { 270 return result; 271 } 272 } 273 return result; 274 } 275 276 /** 277 * Filter an event. 278 * 279 * @param logger 280 * The Logger. 281 * @param level 282 * The event logging Level. 283 * @param marker 284 * The Marker for the event or null. 285 * @param msg 286 * String text to filter on. 287 * @param p0 the message parameters 288 * @param p1 the message parameters 289 * @param p2 the message parameters 290 * @param p3 the message parameters 291 * @return the Result. 292 */ 293 @Override 294 public Result filter(final Logger logger, final Level level, final Marker marker, final String msg, 295 final Object p0, final Object p1, final Object p2, final Object p3) { 296 Result result = Result.NEUTRAL; 297 for (int i = 0; i < filters.length; i++) { 298 result = filters[i].filter(logger, level, marker, msg, p0, p1, p2, p3); 299 if (result == Result.ACCEPT || result == Result.DENY) { 300 return result; 301 } 302 } 303 return result; 304 } 305 306 /** 307 * Filter an event. 308 * 309 * @param logger 310 * The Logger. 311 * @param level 312 * The event logging Level. 313 * @param marker 314 * The Marker for the event or null. 315 * @param msg 316 * String text to filter on. 317 * @param p0 the message parameters 318 * @param p1 the message parameters 319 * @param p2 the message parameters 320 * @param p3 the message parameters 321 * @param p4 the message parameters 322 * @return the Result. 323 */ 324 @Override 325 public Result filter(final Logger logger, final Level level, final Marker marker, final String msg, 326 final Object p0, final Object p1, final Object p2, final Object p3, 327 final Object p4) { 328 Result result = Result.NEUTRAL; 329 for (int i = 0; i < filters.length; i++) { 330 result = filters[i].filter(logger, level, marker, msg, p0, p1, p2, p3, p4); 331 if (result == Result.ACCEPT || result == Result.DENY) { 332 return result; 333 } 334 } 335 return result; 336 } 337 338 /** 339 * Filter an event. 340 * 341 * @param logger 342 * The Logger. 343 * @param level 344 * The event logging Level. 345 * @param marker 346 * The Marker for the event or null. 347 * @param msg 348 * String text to filter on. 349 * @param p0 the message parameters 350 * @param p1 the message parameters 351 * @param p2 the message parameters 352 * @param p3 the message parameters 353 * @param p4 the message parameters 354 * @param p5 the message parameters 355 * @return the Result. 356 */ 357 @Override 358 public Result filter(final Logger logger, final Level level, final Marker marker, final String msg, 359 final Object p0, final Object p1, final Object p2, final Object p3, 360 final Object p4, final Object p5) { 361 Result result = Result.NEUTRAL; 362 for (int i = 0; i < filters.length; i++) { 363 result = filters[i].filter(logger, level, marker, msg, p0, p1, p2, p3, p4, p5); 364 if (result == Result.ACCEPT || result == Result.DENY) { 365 return result; 366 } 367 } 368 return result; 369 } 370 371 /** 372 * Filter an event. 373 * 374 * @param logger 375 * The Logger. 376 * @param level 377 * The event logging Level. 378 * @param marker 379 * The Marker for the event or null. 380 * @param msg 381 * String text to filter on. 382 * @param p0 the message parameters 383 * @param p1 the message parameters 384 * @param p2 the message parameters 385 * @param p3 the message parameters 386 * @param p4 the message parameters 387 * @param p5 the message parameters 388 * @param p6 the message parameters 389 * @return the Result. 390 */ 391 @Override 392 public Result filter(final Logger logger, final Level level, final Marker marker, final String msg, 393 final Object p0, final Object p1, final Object p2, final Object p3, 394 final Object p4, final Object p5, final Object p6) { 395 Result result = Result.NEUTRAL; 396 for (int i = 0; i < filters.length; i++) { 397 result = filters[i].filter(logger, level, marker, msg, p0, p1, p2, p3, p4, p5, p6); 398 if (result == Result.ACCEPT || result == Result.DENY) { 399 return result; 400 } 401 } 402 return result; 403 } 404 405 /** 406 * Filter an event. 407 * 408 * @param logger 409 * The Logger. 410 * @param level 411 * The event logging Level. 412 * @param marker 413 * The Marker for the event or null. 414 * @param msg 415 * String text to filter on. 416 * @param p0 the message parameters 417 * @param p1 the message parameters 418 * @param p2 the message parameters 419 * @param p3 the message parameters 420 * @param p4 the message parameters 421 * @param p5 the message parameters 422 * @param p6 the message parameters 423 * @param p7 the message parameters 424 * @return the Result. 425 */ 426 @Override 427 public Result filter(final Logger logger, final Level level, final Marker marker, final String msg, 428 final Object p0, final Object p1, final Object p2, final Object p3, 429 final Object p4, final Object p5, final Object p6, 430 final Object p7) { 431 Result result = Result.NEUTRAL; 432 for (int i = 0; i < filters.length; i++) { 433 result = filters[i].filter(logger, level, marker, msg, p0, p1, p2, p3, p4, p5, p6, p7); 434 if (result == Result.ACCEPT || result == Result.DENY) { 435 return result; 436 } 437 } 438 return result; 439 } 440 441 /** 442 * Filter an event. 443 * 444 * @param logger 445 * The Logger. 446 * @param level 447 * The event logging Level. 448 * @param marker 449 * The Marker for the event or null. 450 * @param msg 451 * String text to filter on. 452 * @param p0 the message parameters 453 * @param p1 the message parameters 454 * @param p2 the message parameters 455 * @param p3 the message parameters 456 * @param p4 the message parameters 457 * @param p5 the message parameters 458 * @param p6 the message parameters 459 * @param p7 the message parameters 460 * @param p8 the message parameters 461 * @return the Result. 462 */ 463 @Override 464 public Result filter(final Logger logger, final Level level, final Marker marker, final String msg, 465 final Object p0, final Object p1, final Object p2, final Object p3, 466 final Object p4, final Object p5, final Object p6, 467 final Object p7, final Object p8) { 468 Result result = Result.NEUTRAL; 469 for (int i = 0; i < filters.length; i++) { 470 result = filters[i].filter(logger, level, marker, msg, p0, p1, p2, p3, p4, p5, p6, p7, p8); 471 if (result == Result.ACCEPT || result == Result.DENY) { 472 return result; 473 } 474 } 475 return result; 476 } 477 478 /** 479 * Filter an event. 480 * 481 * @param logger 482 * The Logger. 483 * @param level 484 * The event logging Level. 485 * @param marker 486 * The Marker for the event or null. 487 * @param msg 488 * String text to filter on. 489 * @param p0 the message parameters 490 * @param p1 the message parameters 491 * @param p2 the message parameters 492 * @param p3 the message parameters 493 * @param p4 the message parameters 494 * @param p5 the message parameters 495 * @param p6 the message parameters 496 * @param p7 the message parameters 497 * @param p8 the message parameters 498 * @param p9 the message parameters 499 * @return the Result. 500 */ 501 @Override 502 public Result filter(final Logger logger, final Level level, final Marker marker, final String msg, 503 final Object p0, final Object p1, final Object p2, final Object p3, 504 final Object p4, final Object p5, final Object p6, 505 final Object p7, final Object p8, final Object p9) { 506 Result result = Result.NEUTRAL; 507 for (int i = 0; i < filters.length; i++) { 508 result = filters[i].filter(logger, level, marker, msg, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); 509 if (result == Result.ACCEPT || result == Result.DENY) { 510 return result; 511 } 512 } 513 return result; 514 } 515 516 /** 517 * Filter an event. 518 * 519 * @param logger 520 * The Logger. 521 * @param level 522 * The event logging Level. 523 * @param marker 524 * The Marker for the event or null. 525 * @param msg 526 * Any Object. 527 * @param t 528 * A Throwable or null. 529 * @return the Result. 530 */ 531 @Override 532 public Result filter(final Logger logger, final Level level, final Marker marker, final Object msg, 533 final Throwable t) { 534 Result result = Result.NEUTRAL; 535 for (int i = 0; i < filters.length; i++) { 536 result = filters[i].filter(logger, level, marker, msg, t); 537 if (result == Result.ACCEPT || result == Result.DENY) { 538 return result; 539 } 540 } 541 return result; 542 } 543 544 /** 545 * Filter an event. 546 * 547 * @param logger 548 * The Logger. 549 * @param level 550 * The event logging Level. 551 * @param marker 552 * The Marker for the event or null. 553 * @param msg 554 * The Message 555 * @param t 556 * A Throwable or null. 557 * @return the Result. 558 */ 559 @Override 560 public Result filter(final Logger logger, final Level level, final Marker marker, final Message msg, 561 final Throwable t) { 562 Result result = Result.NEUTRAL; 563 for (int i = 0; i < filters.length; i++) { 564 result = filters[i].filter(logger, level, marker, msg, t); 565 if (result == Result.ACCEPT || result == Result.DENY) { 566 return result; 567 } 568 } 569 return result; 570 } 571 572 /** 573 * Filter an event. 574 * 575 * @param event 576 * The Event to filter on. 577 * @return the Result. 578 */ 579 @Override 580 public Result filter(final LogEvent event) { 581 Result result = Result.NEUTRAL; 582 for (int i = 0; i < filters.length; i++) { 583 result = filters[i].filter(event); 584 if (result == Result.ACCEPT || result == Result.DENY) { 585 return result; 586 } 587 } 588 return result; 589 } 590 591 @Override 592 public String toString() { 593 final StringBuilder sb = new StringBuilder(); 594 for (int i = 0; i < filters.length; i++) { 595 if (sb.length() == 0) { 596 sb.append('{'); 597 } else { 598 sb.append(", "); 599 } 600 sb.append(filters[i].toString()); 601 } 602 if (sb.length() > 0) { 603 sb.append('}'); 604 } 605 return sb.toString(); 606 } 607 608 /** 609 * Create a CompositeFilter. 610 * 611 * @param filters 612 * An array of Filters to call. 613 * @return The CompositeFilter. 614 */ 615 @PluginFactory 616 public static CompositeFilter createFilters(@PluginElement("Filters") final Filter[] filters) { 617 return new CompositeFilter(filters); 618 } 619 620}