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.builders.appender;
18  
19  import static org.apache.log4j.builders.BuilderManager.CATEGORY;
20  import static org.apache.log4j.config.Log4j1Configuration.APPENDER_REF_TAG;
21  import static org.apache.log4j.config.Log4j1Configuration.THRESHOLD_PARAM;
22  import static org.apache.log4j.xml.XmlConfiguration.FILTER_TAG;
23  import static org.apache.log4j.xml.XmlConfiguration.NAME_ATTR;
24  import static org.apache.log4j.xml.XmlConfiguration.PARAM_TAG;
25  import static org.apache.log4j.xml.XmlConfiguration.VALUE_ATTR;
26  import static org.apache.log4j.xml.XmlConfiguration.forEachElement;
27  
28  import java.util.ArrayList;
29  import java.util.List;
30  import java.util.Properties;
31  import java.util.concurrent.atomic.AtomicReference;
32  
33  import org.apache.log4j.Appender;
34  import org.apache.log4j.bridge.AppenderWrapper;
35  import org.apache.log4j.bridge.RewritePolicyAdapter;
36  import org.apache.log4j.bridge.RewritePolicyWrapper;
37  import org.apache.log4j.builders.AbstractBuilder;
38  import org.apache.log4j.config.Log4j1Configuration;
39  import org.apache.log4j.config.PropertiesConfiguration;
40  import org.apache.log4j.helpers.OptionConverter;
41  import org.apache.log4j.rewrite.RewritePolicy;
42  import org.apache.log4j.spi.Filter;
43  import org.apache.log4j.xml.XmlConfiguration;
44  import org.apache.logging.log4j.Logger;
45  import org.apache.logging.log4j.core.appender.rewrite.RewriteAppender;
46  import org.apache.logging.log4j.core.config.AppenderRef;
47  import org.apache.logging.log4j.core.config.plugins.Plugin;
48  import org.apache.logging.log4j.status.StatusLogger;
49  import org.apache.logging.log4j.util.Strings;
50  import org.w3c.dom.Element;
51  
52  
53  /**
54   * Build an Asynch Appender
55   */
56  @Plugin(name = "org.apache.log4j.rewrite.RewriteAppender", category = CATEGORY)
57  public class RewriteAppenderBuilder extends AbstractBuilder implements AppenderBuilder {
58  
59      private static final Logger LOGGER = StatusLogger.getLogger();
60      private static final String REWRITE_POLICY_TAG = "rewritePolicy";
61  
62      public RewriteAppenderBuilder() {
63      }
64  
65      public RewriteAppenderBuilder(String prefix, Properties props) {
66          super(prefix, props);
67      }
68  
69      @Override
70      public Appender parseAppender(final Element appenderElement, final XmlConfiguration config) {
71          String name = appenderElement.getAttribute(NAME_ATTR);
72          AtomicReference<List<String>> appenderRefs = new AtomicReference<>(new ArrayList<>());
73          AtomicReference<RewritePolicy> rewritePolicyHolder = new AtomicReference<>();
74          AtomicReference<String> level = new AtomicReference<>();
75          AtomicReference<Filter> filter = new AtomicReference<>();
76          forEachElement(appenderElement.getChildNodes(), currentElement -> {
77              switch (currentElement.getTagName()) {
78                  case APPENDER_REF_TAG:
79                      Appender appender = config.findAppenderByReference(currentElement);
80                      if (appender != null) {
81                          appenderRefs.get().add(appender.getName());
82                      }
83                      break;
84                  case REWRITE_POLICY_TAG: {
85                      RewritePolicy policy = config.parseRewritePolicy(currentElement);
86                      if (policy != null) {
87                          rewritePolicyHolder.set(policy);
88                      }
89                      break;
90                  }
91                  case FILTER_TAG: {
92                      filter.set(config.parseFilters(currentElement));
93                      break;
94                  }
95                  case PARAM_TAG: {
96                      if (currentElement.getAttribute(NAME_ATTR).equalsIgnoreCase(THRESHOLD_PARAM)) {
97                          String value = currentElement.getAttribute(VALUE_ATTR);
98                          if (value == null) {
99                              LOGGER.warn("No value supplied for Threshold parameter, ignoring.");
100                         } else {
101                             level.set(value);
102                         }
103                     }
104                     break;
105                 }
106             }
107         });
108         return createAppender(name, level.get(), appenderRefs.get().toArray(Strings.EMPTY_ARRAY), rewritePolicyHolder.get(),
109                 filter.get(), config);
110     }
111 
112     @Override
113     public Appender parseAppender(final String name, final String appenderPrefix, final String layoutPrefix,
114             final String filterPrefix, final Properties props, final PropertiesConfiguration configuration) {
115         String appenderRef = getProperty(APPENDER_REF_TAG);
116         Filter filter = configuration.parseAppenderFilters(props, filterPrefix, name);
117         String policyPrefix = appenderPrefix + ".rewritePolicy";
118         String className = getProperty(policyPrefix);
119         RewritePolicy policy = configuration.getBuilderManager().parseRewritePolicy(className, policyPrefix,
120                 props, configuration);
121         String level = getProperty(THRESHOLD_PARAM);
122         if (appenderRef == null) {
123             LOGGER.warn("No appender references configured for AsyncAppender {}", name);
124             return null;
125         }
126         Appender appender = configuration.parseAppender(props, appenderRef);
127         if (appender == null) {
128             LOGGER.warn("Cannot locate Appender {}", appenderRef);
129             return null;
130         }
131         return createAppender(name, level, new String[] {appenderRef}, policy, filter, configuration);
132     }
133 
134     private <T extends Log4j1Configuration> Appender createAppender(String name, String level,
135             String[] appenderRefs, RewritePolicy policy, Filter filter, T configuration) {
136         org.apache.logging.log4j.Level logLevel = OptionConverter.convertLevel(level,
137                 org.apache.logging.log4j.Level.TRACE);
138         AppenderRef[] refs = new AppenderRef[appenderRefs.length];
139         int index = 0;
140         for (String appenderRef : appenderRefs) {
141             refs[index++] = AppenderRef.createAppenderRef(appenderRef, logLevel, null);
142         }
143         org.apache.logging.log4j.core.Filter rewriteFilter = buildFilters(level, filter);
144         org.apache.logging.log4j.core.appender.rewrite.RewritePolicy rewritePolicy;
145         if (policy instanceof RewritePolicyWrapper) {
146             rewritePolicy = ((RewritePolicyWrapper) policy).getPolicy();
147         } else {
148             rewritePolicy = new RewritePolicyAdapter(policy);
149         }
150         return new AppenderWrapper(RewriteAppender.createAppender(name, "true", refs, configuration,
151                 rewritePolicy, rewriteFilter));
152     }
153 }