1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.appender;
18
19 import java.io.Serializable;
20 import java.util.HashMap;
21 import java.util.Map;
22 import java.util.concurrent.TimeUnit;
23
24 import org.apache.logging.log4j.core.Appender;
25 import org.apache.logging.log4j.core.Filter;
26 import org.apache.logging.log4j.core.Layout;
27 import org.apache.logging.log4j.core.config.Configuration;
28 import org.apache.logging.log4j.core.config.plugins.Plugin;
29 import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
30 import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
31 import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
32 import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
33 import org.apache.logging.log4j.core.net.Advertiser;
34 import org.apache.logging.log4j.core.util.Booleans;
35 import org.apache.logging.log4j.core.util.Integers;
36
37
38
39
40 @Plugin(name = FileAppender.PLUGIN_NAME, category = "Core", elementType = Appender.ELEMENT_TYPE, printObject = true)
41 public final class FileAppender extends AbstractOutputStreamAppender<FileManager> {
42
43 public static final String PLUGIN_NAME = "File";
44
45
46
47
48
49
50
51 public static class Builder<B extends Builder<B>> extends AbstractOutputStreamAppender.Builder<B>
52 implements org.apache.logging.log4j.core.util.Builder<FileAppender> {
53
54 @PluginBuilderAttribute
55 @Required
56 private String fileName;
57
58 @PluginBuilderAttribute
59 private boolean append = true;
60
61 @PluginBuilderAttribute
62 private boolean locking;
63
64 @PluginBuilderAttribute
65 private boolean advertise;
66
67 @PluginBuilderAttribute
68 private String advertiseUri;
69
70 @PluginBuilderAttribute
71 private boolean createOnDemand;
72
73 @PluginConfiguration
74 private Configuration configuration;
75
76 @Override
77 public FileAppender build() {
78 boolean bufferedIo = isBufferedIo();
79 final int bufferSize = getBufferSize();
80 if (locking && bufferedIo) {
81 LOGGER.warn("Locking and buffering are mutually exclusive. No buffering will occur for {}", fileName);
82 bufferedIo = false;
83 }
84 if (!bufferedIo && bufferSize > 0) {
85 LOGGER.warn("The bufferSize is set to {} but bufferedIo is false: {}", bufferSize, bufferedIo);
86 }
87 final Layout<? extends Serializable> layout = getOrCreateLayout();
88
89 final FileManager manager = FileManager.getFileManager(fileName, append, locking, bufferedIo, createOnDemand,
90 advertiseUri, layout, bufferSize, configuration);
91 if (manager == null) {
92 return null;
93 }
94
95 return new FileAppender(getName(), layout, getFilter(), manager, fileName, isIgnoreExceptions(),
96 !bufferedIo || isImmediateFlush(), advertise ? configuration.getAdvertiser() : null);
97 }
98
99 public String getAdvertiseUri() {
100 return advertiseUri;
101 }
102
103 public Configuration getConfiguration() {
104 return configuration;
105 }
106
107 public String getFileName() {
108 return fileName;
109 }
110
111 public boolean isAdvertise() {
112 return advertise;
113 }
114
115 public boolean isAppend() {
116 return append;
117 }
118
119 public boolean isCreateOnDemand() {
120 return createOnDemand;
121 }
122
123 public boolean isLocking() {
124 return locking;
125 }
126
127 public B withAdvertise(final boolean advertise) {
128 this.advertise = advertise;
129 return asBuilder();
130 }
131
132 public B withAdvertiseUri(final String advertiseUri) {
133 this.advertiseUri = advertiseUri;
134 return asBuilder();
135 }
136
137 public B withAppend(final boolean append) {
138 this.append = append;
139 return asBuilder();
140 }
141
142 public B withConfiguration(final Configuration config) {
143 this.configuration = config;
144 return asBuilder();
145 }
146
147 public B withFileName(final String fileName) {
148 this.fileName = fileName;
149 return asBuilder();
150 }
151
152 public B withCreateOnDemand(final boolean createOnDemand) {
153 this.createOnDemand = createOnDemand;
154 return asBuilder();
155 }
156
157 public B withLocking(final boolean locking) {
158 this.locking = locking;
159 return asBuilder();
160 }
161
162 }
163
164 private static final int DEFAULT_BUFFER_SIZE = 8192;
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188 @Deprecated
189 public static FileAppender createAppender(
190
191 final String fileName,
192 final String append,
193 final String locking,
194 final String name,
195 final String immediateFlush,
196 final String ignoreExceptions,
197 final String bufferedIo,
198 final String bufferSizeStr,
199 final Layout<? extends Serializable> layout,
200 final Filter filter,
201 final String advertise,
202 final String advertiseUri,
203 final Configuration config) {
204 return newBuilder()
205 .withAdvertise(Boolean.parseBoolean(advertise))
206 .withAdvertiseUri(advertiseUri)
207 .withAppend(Booleans.parseBoolean(append, true))
208 .withBufferedIo(Booleans.parseBoolean(bufferedIo, true))
209 .withBufferSize(Integers.parseInt(bufferSizeStr, DEFAULT_BUFFER_SIZE))
210 .withConfiguration(config)
211 .withFileName(fileName)
212 .withFilter(filter)
213 .withIgnoreExceptions(Booleans.parseBoolean(ignoreExceptions, true))
214 .withImmediateFlush(Booleans.parseBoolean(immediateFlush, true))
215 .withLayout(layout)
216 .withLocking(Boolean.parseBoolean(locking))
217 .withName(name)
218 .build();
219
220 }
221
222 @PluginBuilderFactory
223 public static <B extends Builder<B>> B newBuilder() {
224 return new Builder<B>().asBuilder();
225 }
226
227 private final String fileName;
228
229 private final Advertiser advertiser;
230
231 private final Object advertisement;
232
233 private FileAppender(final String name, final Layout<? extends Serializable> layout, final Filter filter,
234 final FileManager manager, final String filename, final boolean ignoreExceptions,
235 final boolean immediateFlush, final Advertiser advertiser) {
236
237 super(name, layout, filter, ignoreExceptions, immediateFlush, manager);
238 if (advertiser != null) {
239 final Map<String, String> configuration = new HashMap<>(layout.getContentFormat());
240 configuration.putAll(manager.getContentFormat());
241 configuration.put("contentType", layout.getContentType());
242 configuration.put("name", name);
243 advertisement = advertiser.advertise(configuration);
244 } else {
245 advertisement = null;
246 }
247 this.fileName = filename;
248 this.advertiser = advertiser;
249 }
250
251
252
253
254
255 public String getFileName() {
256 return this.fileName;
257 }
258
259 @Override
260 public boolean stop(final long timeout, final TimeUnit timeUnit) {
261 setStopping();
262 super.stop(timeout, timeUnit, false);
263 if (advertiser != null) {
264 advertiser.unadvertise(advertisement);
265 }
266 setStopped();
267 return true;
268 }
269 }