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.Layout;
21 import org.apache.log4j.bridge.AppenderWrapper;
22 import org.apache.log4j.bridge.FilterAdapter;
23 import org.apache.log4j.bridge.FilterWrapper;
24 import org.apache.log4j.bridge.LayoutAdapter;
25 import org.apache.log4j.bridge.LayoutWrapper;
26 import org.apache.log4j.builders.AbstractBuilder;
27 import org.apache.log4j.builders.BooleanHolder;
28 import org.apache.log4j.builders.Holder;
29 import org.apache.log4j.config.Log4j1Configuration;
30 import org.apache.log4j.config.PropertiesConfiguration;
31 import org.apache.log4j.spi.Filter;
32 import org.apache.log4j.xml.XmlConfiguration;
33 import org.apache.logging.log4j.Logger;
34 import org.apache.logging.log4j.core.appender.FileAppender;
35 import org.apache.logging.log4j.core.config.plugins.Plugin;
36 import org.apache.logging.log4j.status.StatusLogger;
37 import org.w3c.dom.Element;
38
39 import java.util.Properties;
40
41 import static org.apache.log4j.builders.BuilderManager.CATEGORY;
42 import static org.apache.log4j.config.Log4j1Configuration.THRESHOLD_PARAM;
43 import static org.apache.log4j.xml.XmlConfiguration.FILTER_TAG;
44 import static org.apache.log4j.xml.XmlConfiguration.LAYOUT_TAG;
45 import static org.apache.log4j.xml.XmlConfiguration.PARAM_TAG;
46 import static org.apache.log4j.xml.XmlConfiguration.forEachElement;
47 import static org.apache.log4j.xml.XmlConfiguration.NAME_ATTR;
48 import static org.apache.log4j.xml.XmlConfiguration.VALUE_ATTR;
49
50
51
52
53 @Plugin(name = "org.apache.log4j.FileAppender", category = CATEGORY)
54 public class FileAppenderBuilder extends AbstractBuilder implements AppenderBuilder {
55
56 private static final Logger LOGGER = StatusLogger.getLogger();
57
58 public FileAppenderBuilder() {
59 }
60
61 public FileAppenderBuilder(String prefix, Properties props) {
62 super(prefix, props);
63 }
64
65 @Override
66 public Appender parseAppender(Element appenderElement, XmlConfiguration config) {
67 String name = appenderElement.getAttribute(NAME_ATTR);
68 Holder<Layout> layout = new Holder<>();
69 Holder<Filter> filter = new Holder<>();
70 Holder<String> fileName = new Holder<>();
71 Holder<String> level = new Holder<>();
72 Holder<Boolean> immediateFlush = new BooleanHolder();
73 Holder<Boolean> append = new BooleanHolder();
74 Holder<Boolean> bufferedIo = new BooleanHolder();
75 Holder<Integer> bufferSize = new Holder<>(8192);
76 forEachElement(appenderElement.getChildNodes(), (currentElement) -> {
77 switch (currentElement.getTagName()) {
78 case LAYOUT_TAG:
79 layout.set(config.parseLayout(currentElement));
80 break;
81 case FILTER_TAG:
82 filter.set(config.parseFilters(currentElement));
83 break;
84 case PARAM_TAG: {
85 switch (currentElement.getAttribute(NAME_ATTR)) {
86 case FILE_PARAM:
87 fileName.set(currentElement.getAttribute(VALUE_ATTR));
88 break;
89 case APPEND_PARAM: {
90 String bool = currentElement.getAttribute(VALUE_ATTR);
91 if (bool != null) {
92 append.set(Boolean.parseBoolean(bool));
93 } else {
94 LOGGER.warn("No value provided for append parameter");
95 }
96 break;
97 }
98 case BUFFERED_IO_PARAM: {
99 String bool = currentElement.getAttribute(VALUE_ATTR);
100 if (bool != null) {
101 bufferedIo.set(Boolean.parseBoolean(bool));
102 } else {
103 LOGGER.warn("No value provided for bufferedIo parameter");
104 }
105 break;
106 }
107 case BUFFER_SIZE_PARAM: {
108 String size = currentElement.getAttribute(VALUE_ATTR);
109 if (size != null) {
110 bufferSize.set(Integer.parseInt(size));
111 } else {
112 LOGGER.warn("No value provide for bufferSize parameter");
113 }
114 break;
115 }
116 case THRESHOLD_PARAM: {
117 String value = currentElement.getAttribute(VALUE_ATTR);
118 if (value == null) {
119 LOGGER.warn("No value supplied for Threshold parameter, ignoring.");
120 } else {
121 level.set(value);
122 }
123 break;
124 }
125 }
126 break;
127 }
128 }
129 });
130
131 return createAppender(name, config, layout.get(), filter.get(), fileName.get(), level.get(),
132 immediateFlush.get(), append.get(), bufferedIo.get(), bufferSize.get());
133 }
134
135
136 @Override
137 public Appender parseAppender(final String name, final String appenderPrefix, final String layoutPrefix,
138 final String filterPrefix, final Properties props, final PropertiesConfiguration configuration) {
139 Layout layout = configuration.parseLayout(layoutPrefix, name, props);
140 Filter filter = configuration.parseAppenderFilters(props, filterPrefix, name);
141 String level = getProperty(THRESHOLD_PARAM);
142 String fileName = getProperty(FILE_PARAM);
143 boolean append = getBooleanProperty(APPEND_PARAM);
144 boolean immediateFlush = false;
145 boolean bufferedIo = getBooleanProperty(BUFFERED_IO_PARAM);
146 int bufferSize = Integer.parseInt(getProperty(BUFFER_SIZE_PARAM, "8192"));
147 return createAppender(name, configuration, layout, filter, fileName, level, immediateFlush,
148 append, bufferedIo, bufferSize);
149 }
150
151 private Appender createAppender(final String name, final Log4j1Configuration configuration, final Layout layout,
152 final Filter filter, final String fileName, String level, boolean immediateFlush, final boolean append,
153 final boolean bufferedIo, final int bufferSize) {
154 org.apache.logging.log4j.core.Layout<?> fileLayout = null;
155 if (bufferedIo) {
156 immediateFlush = true;
157 }
158 if (layout instanceof LayoutWrapper) {
159 fileLayout = ((LayoutWrapper) layout).getLayout();
160 } else if (layout != null) {
161 fileLayout = new LayoutAdapter(layout);
162 }
163 org.apache.logging.log4j.core.Filter fileFilter = buildFilters(level, filter);
164 if (fileName == null) {
165 LOGGER.warn("Unable to create File Appender, no file name provided");
166 return null;
167 }
168 return new AppenderWrapper(FileAppender.newBuilder()
169 .setName(name)
170 .setConfiguration(configuration)
171 .setLayout(fileLayout)
172 .setFilter(fileFilter)
173 .withFileName(fileName)
174 .withImmediateFlush(immediateFlush)
175 .withAppend(append)
176 .withBufferedIo(bufferedIo)
177 .withBufferSize(bufferSize)
178 .build());
179 }
180 }