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