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