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  
18  package org.apache.log4j.filter;
19  
20  import org.apache.log4j.spi.Filter;
21  import org.apache.log4j.spi.LoggingEvent;
22  import org.apache.log4j.spi.OptionHandler;
23  import org.apache.log4j.xml.UnrecognizedElementHandler;
24  import org.w3c.dom.Element;
25  
26  import java.util.Properties;
27  
28  
29  /***
30   * A filter that 'and's the results of any number of contained filters together.
31   * 
32   * For the filter to process events, all contained filters must return Filter.ACCEPT.
33   * 
34   * If the contained filters do not return Filter.ACCEPT, Filter.NEUTRAL is returned.
35   * 
36   * If acceptOnMatch is set to true, Filter.ACCEPT is returned.
37   * If acceptOnMatch is set to false, Filter.DENY is returned.
38   * 
39   * Here is an example config that will accept only events that contain BOTH
40   * a DEBUG level AND 'test' in the message:
41   * 
42   *<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
43   * <filter class="org.apache.log4j.filter.AndFilter">
44   *  <filter class="org.apache.log4j.filter.LevelMatchFilter">
45   *        <param name="levelToMatch" value="DEBUG" />
46   *        <param name="acceptOnMatch" value="true" />
47   *  </filter>
48   *  <filter class="org.apache.log4j.filter.StringMatchFilter">
49   *        <param name="stringToMatch" value="test" />
50   *        <param name="acceptOnMatch" value="true" />
51   *  </filter>
52   *  <param name="acceptOnMatch" value="false"/>
53   * </filter>
54   * <filter class="org.apache.log4j.filter.DenyAllFilter"/>
55   *<layout class="org.apache.log4j.SimpleLayout"/>
56   *</appender>
57   * 
58   * To accept all events EXCEPT those events that contain a 
59   * DEBUG level and 'test' in the message: 
60   * change the AndFilter's acceptOnMatch param to false and remove the DenyAllFilter
61   * 
62   * NOTE: If you are defining a filter that is only relying on logging event content 
63   * (no external or filter-managed state), you could opt instead
64   * to use an ExpressionFilter with one of the following expressions:
65   * 
66   * LEVEL == DEBUG && MSG ~= 'test'
67   * or
68   * ! ( LEVEL == DEBUG && MSG ~= 'test' )
69   *
70   * XML configuration of this filter requires use of either log4j 1.2.15 or later or
71   * org.apache.log4j.rolling.DOMConfigurator.
72   *
73   * @author Scott Deboy sdeboy@apache.org
74   */
75  public class AndFilter extends Filter implements UnrecognizedElementHandler {
76    Filter headFilter = null;
77    Filter tailFilter = null;
78    boolean acceptOnMatch = true;
79    
80    public void activateOptions() {
81    }
82  
83    public void addFilter(final Filter filter) {
84      if (headFilter == null) {
85        headFilter = filter;
86        tailFilter = filter;
87      } else {
88        tailFilter.next = filter;
89      }
90    }
91    
92    public void setAcceptOnMatch(final boolean acceptOnMatch) {
93      this.acceptOnMatch = acceptOnMatch;
94    }
95    /***
96     * If this event does not already contain location information, 
97     * evaluate the event against the expression.
98     * 
99     * If the expression evaluates to true, generate a LocationInfo instance 
100    * by creating an exception and set this LocationInfo on the event.
101    * 
102    * Returns {@link Filter#NEUTRAL}
103    */
104   public int decide(final LoggingEvent event) {
105     boolean accepted = true;
106     Filter f = headFilter;
107     while (f != null) {
108       accepted = accepted && (Filter.ACCEPT == f.decide(event));
109       f = f.next;
110     }
111     if (accepted) {
112       if(acceptOnMatch) {
113         return Filter.ACCEPT;
114       }
115        return Filter.DENY;
116     }
117     return Filter.NEUTRAL;
118   }
119 
120     /***
121      * {@inheritDoc}
122      */
123   public boolean parseUnrecognizedElement(final Element element,
124                                           final Properties props) throws Exception {
125       final String nodeName = element.getNodeName();
126       if ("filter".equals(nodeName)) {
127           OptionHandler filter =
128                   org.apache.log4j.extras.DOMConfigurator.parseElement(
129                           element, props, Filter.class);
130           if (filter instanceof Filter) {
131               filter.activateOptions();
132               this.addFilter((Filter) filter);
133           }
134           return true;
135       }
136       return false;
137   }
138 
139 }