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