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