1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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 }