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  package org.apache.log4j.rewrite;
18  
19  import org.apache.log4j.Appender;
20  import org.apache.log4j.AppenderSkeleton;
21  import org.apache.log4j.helpers.AppenderAttachableImpl;
22  import org.apache.log4j.spi.AppenderAttachable;
23  import org.apache.log4j.spi.LoggingEvent;
24  import org.apache.log4j.spi.OptionHandler;
25  import org.apache.log4j.xml.UnrecognizedElementHandler;
26  import org.w3c.dom.Element;
27  
28  import java.util.Enumeration;
29  import java.util.Properties;
30  
31  /**
32   * This appender forwards a logging request to another
33   * appender after possibly rewriting the logging event.
34   * <p>
35   * This appender (with the appropriate policy)
36   * replaces the MapFilter, PropertyFilter and ReflectionFilter
37   * from log4j 1.3.
38   */
39  public class RewriteAppender extends AppenderSkeleton
40      implements AppenderAttachable, UnrecognizedElementHandler {
41      /**
42       * Rewrite policy.
43       */
44      private RewritePolicy policy;
45      /**
46       * Nested appenders.
47       */
48      private final AppenderAttachableImpl appenders;
49  
50      public RewriteAppender() {
51          appenders = new AppenderAttachableImpl();
52      }
53  
54      /**
55       * {@inheritDoc}
56       */
57      protected void append(final LoggingEvent event) {
58          LoggingEvent rewritten = event;
59          if (policy != null) {
60              rewritten = policy.rewrite(event);
61          }
62          if (rewritten != null) {
63              synchronized (appenders) {
64                  appenders.appendLoopOnAppenders(rewritten);
65              }
66          }
67      }
68  
69      /**
70       * Add appender.
71       *
72       * @param newAppender appender to add, may not be null.
73       */
74      public void addAppender(final Appender newAppender) {
75          synchronized (appenders) {
76              appenders.addAppender(newAppender);
77          }
78      }
79  
80      /**
81       * Get iterator over attached appenders.
82       *
83       * @return iterator or null if no attached appenders.
84       */
85      public Enumeration getAllAppenders() {
86          synchronized (appenders) {
87              return appenders.getAllAppenders();
88          }
89      }
90  
91      /**
92       * Get appender by name.
93       *
94       * @param name name, may not be null.
95       * @return matching appender or null.
96       */
97      public Appender getAppender(final String name) {
98          synchronized (appenders) {
99              return appenders.getAppender(name);
100         }
101     }
102 
103 
104     /**
105      * Close this <code>AsyncAppender</code> by interrupting the dispatcher
106      * thread which will process all pending events before exiting.
107      */
108     public void close() {
109         closed = true;
110         //
111         //    close all attached appenders.
112         //
113         synchronized (appenders) {
114             Enumeration iter = appenders.getAllAppenders();
115 
116             if (iter != null) {
117                 while (iter.hasMoreElements()) {
118                     Object next = iter.nextElement();
119 
120                     if (next instanceof Appender) {
121                         ((Appender) next).close();
122                     }
123                 }
124             }
125         }
126     }
127 
128     /**
129      * Determines if specified appender is attached.
130      *
131      * @param appender appender.
132      * @return true if attached.
133      */
134     public boolean isAttached(final Appender appender) {
135         synchronized (appenders) {
136             return appenders.isAttached(appender);
137         }
138     }
139 
140     /**
141      * {@inheritDoc}
142      */
143     public boolean requiresLayout() {
144         return false;
145     }
146 
147     /**
148      * Removes and closes all attached appenders.
149      */
150     public void removeAllAppenders() {
151         synchronized (appenders) {
152             appenders.removeAllAppenders();
153         }
154     }
155 
156     /**
157      * Removes an appender.
158      *
159      * @param appender appender to remove.
160      */
161     public void removeAppender(final Appender appender) {
162         synchronized (appenders) {
163             appenders.removeAppender(appender);
164         }
165     }
166 
167     /**
168      * Remove appender by name.
169      *
170      * @param name name.
171      */
172     public void removeAppender(final String name) {
173         synchronized (appenders) {
174             appenders.removeAppender(name);
175         }
176     }
177 
178 
179     public void setRewritePolicy(final RewritePolicy rewritePolicy) {
180         policy = rewritePolicy;
181     }
182 
183     /**
184      * {@inheritDoc}
185      */
186     public boolean parseUnrecognizedElement(final Element element,
187                                             final Properties props) throws Exception {
188         final String nodeName = element.getNodeName();
189         if ("rewritePolicy".equals(nodeName)) {
190             Object rewritePolicy =
191                 org.apache.log4j.xml.DOMConfigurator.parseElement(
192                     element, props, RewritePolicy.class);
193             if (rewritePolicy != null) {
194                 if (rewritePolicy instanceof OptionHandler) {
195                     ((OptionHandler) rewritePolicy).activateOptions();
196                 }
197                 this.setRewritePolicy((RewritePolicy) rewritePolicy);
198             }
199             return true;
200         }
201         return false;
202     }
203 
204 }