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.NAME_ATTR;
23  import static org.apache.log4j.xml.XmlConfiguration.PARAM_TAG;
24  import static org.apache.log4j.xml.XmlConfiguration.VALUE_ATTR;
25  import static org.apache.log4j.xml.XmlConfiguration.forEachElement;
26  
27  import java.util.ArrayList;
28  import java.util.List;
29  import java.util.Properties;
30  import java.util.concurrent.atomic.AtomicBoolean;
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.builders.AbstractBuilder;
36  import org.apache.log4j.config.Log4j1Configuration;
37  import org.apache.log4j.config.PropertiesConfiguration;
38  import org.apache.log4j.helpers.OptionConverter;
39  import org.apache.log4j.xml.XmlConfiguration;
40  import org.apache.logging.log4j.Logger;
41  import org.apache.logging.log4j.core.appender.AsyncAppender;
42  import org.apache.logging.log4j.core.config.AppenderRef;
43  import org.apache.logging.log4j.core.config.plugins.Plugin;
44  import org.apache.logging.log4j.status.StatusLogger;
45  import org.apache.logging.log4j.util.Strings;
46  import org.w3c.dom.Element;
47  
48  
49  /**
50   * Build an Asynch Appender
51   */
52  @Plugin(name = "org.apache.log4j.AsyncAppender", category = CATEGORY)
53  public class AsyncAppenderBuilder extends AbstractBuilder implements AppenderBuilder {
54  
55      private static final Logger LOGGER = StatusLogger.getLogger();
56      private static final String BLOCKING_PARAM = "Blocking";
57      private static final String INCLUDE_LOCATION_PARAM = "IncludeLocation";
58  
59      public AsyncAppenderBuilder() {
60      }
61  
62      public AsyncAppenderBuilder(String prefix, Properties props) {
63          super(prefix, props);
64      }
65  
66      @Override
67      public Appender parseAppender(final Element appenderElement, final XmlConfiguration config) {
68          String name = appenderElement.getAttribute(NAME_ATTR);
69          AtomicReference<List<String>> appenderRefs = new AtomicReference<>(new ArrayList<>());
70          AtomicBoolean blocking = new AtomicBoolean();
71          AtomicBoolean includeLocation = new AtomicBoolean();
72          AtomicReference<String> level = new AtomicReference<>("trace");
73          AtomicReference<Integer> bufferSize = new AtomicReference<>(1024);
74          forEachElement(appenderElement.getChildNodes(), currentElement -> {
75              switch (currentElement.getTagName()) {
76                  case APPENDER_REF_TAG:
77                      Appender appender = config.findAppenderByReference(currentElement);
78                      if (appender != null) {
79                          appenderRefs.get().add(appender.getName());
80                      }
81                      break;
82                  case PARAM_TAG: {
83                      switch (currentElement.getAttribute(NAME_ATTR)) {
84                          case BUFFER_SIZE_PARAM: {
85                              String value = currentElement.getAttribute(VALUE_ATTR);
86                              if (value == null) {
87                                  LOGGER.warn("No value supplied for BufferSize parameter. Defaulting to 1024.");
88                              } else {
89                                  bufferSize.set(Integer.parseInt(value));
90                              }
91                              break;
92                          }
93                          case BLOCKING_PARAM: {
94                              String value = currentElement.getAttribute(VALUE_ATTR);
95                              if (value == null) {
96                                  LOGGER.warn("No value supplied for Blocking parameter. Defaulting to false.");
97                              } else {
98                                  blocking.set(Boolean.parseBoolean(value));
99                              }
100                             break;
101                         }
102                         case INCLUDE_LOCATION_PARAM: {
103                             String value = currentElement.getAttribute(VALUE_ATTR);
104                             if (value == null) {
105                                 LOGGER.warn("No value supplied for IncludeLocation parameter. Defaulting to false.");
106                             } else {
107                                 includeLocation.set(Boolean.parseBoolean(value));
108                             }
109                             break;
110                         }
111                         case THRESHOLD_PARAM: {
112                             String value = currentElement.getAttribute(VALUE_ATTR);
113                             if (value == null) {
114                                 LOGGER.warn("No value supplied for Threshold parameter, ignoring.");
115                             } else {
116                                 level.set(value);
117                             }
118                             break;
119                         }
120                     }
121                     break;
122                 }
123             }
124         });
125         return createAppender(name, level.get(), appenderRefs.get().toArray(Strings.EMPTY_ARRAY), blocking.get(),
126                 bufferSize.get(), includeLocation.get(), config);
127     }
128 
129     @Override
130     public Appender parseAppender(final String name, final String appenderPrefix, final String layoutPrefix,
131             final String filterPrefix, final Properties props, final PropertiesConfiguration configuration) {
132         String appenderRef = getProperty(APPENDER_REF_TAG);
133         boolean blocking = getBooleanProperty(BLOCKING_PARAM);
134         boolean includeLocation = getBooleanProperty(INCLUDE_LOCATION_PARAM);
135         String level = getProperty(THRESHOLD_PARAM);
136         int bufferSize = getIntegerProperty(BUFFER_SIZE_PARAM, 1024);
137         if (appenderRef == null) {
138             LOGGER.warn("No appender references configured for AsyncAppender {}", name);
139             return null;
140         }
141         Appender appender = configuration.parseAppender(props, appenderRef);
142         if (appender == null) {
143             LOGGER.warn("Cannot locate Appender {}", appenderRef);
144             return null;
145         }
146         return createAppender(name, level, new String[] {appenderRef}, blocking, bufferSize, includeLocation,
147                 configuration);
148     }
149 
150     private <T extends Log4j1Configuration> Appender createAppender(String name, String level,
151             String[] appenderRefs, boolean blocking, int bufferSize, boolean includeLocation,
152             T configuration) {
153         org.apache.logging.log4j.Level logLevel = OptionConverter.convertLevel(level,
154                 org.apache.logging.log4j.Level.TRACE);
155         AppenderRef[] refs = new AppenderRef[appenderRefs.length];
156         int index = 0;
157         for (String appenderRef : appenderRefs) {
158             refs[index++] = AppenderRef.createAppenderRef(appenderRef, logLevel, null);
159         }
160         return new AppenderWrapper(AsyncAppender.newBuilder()
161                 .setName(name)
162                 .setAppenderRefs(refs)
163                 .setBlocking(blocking)
164                 .setBufferSize(bufferSize)
165                 .setIncludeLocation(includeLocation)
166                 .setConfiguration(configuration)
167                 .build());
168     }
169 }