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