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.Core;
26 import org.apache.logging.log4j.core.Filter;
27 import org.apache.logging.log4j.core.Layout;
28 import org.apache.logging.log4j.core.LogEvent;
29 import org.apache.logging.log4j.core.config.Configuration;
30 import org.apache.logging.log4j.core.config.plugins.Plugin;
31 import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
32 import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
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 = "RandomAccessFile", category = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE, printObject = true)
41 public final class RandomAccessFileAppender extends AbstractOutputStreamAppender<RandomAccessFileManager> {
42
43
44
45
46
47
48
49 public static class Builder<B extends Builder<B>> extends AbstractOutputStreamAppender.Builder<B>
50 implements org.apache.logging.log4j.core.util.Builder<RandomAccessFileAppender> {
51
52 @PluginBuilderAttribute("fileName")
53 private String fileName;
54
55 @PluginBuilderAttribute("append")
56 private boolean append = true;
57
58 @PluginBuilderAttribute("advertise")
59 private boolean advertise;
60
61 @PluginBuilderAttribute("advertiseURI")
62 private String advertiseURI;
63
64 @Override
65 public RandomAccessFileAppender build() {
66 final String name = getName();
67 if (name == null) {
68 LOGGER.error("No name provided for FileAppender");
69 return null;
70 }
71
72 if (fileName == null) {
73 LOGGER.error("No filename provided for FileAppender with name " + name);
74 return null;
75 }
76 final Layout<? extends Serializable> layout = getOrCreateLayout();
77 final boolean immediateFlush = isImmediateFlush();
78 final RandomAccessFileManager manager = RandomAccessFileManager.getFileManager(fileName, append,
79 immediateFlush, getBufferSize(), advertiseURI, layout, null);
80 if (manager == null) {
81 return null;
82 }
83
84 return new RandomAccessFileAppender(name, layout, getFilter(), manager, fileName, isIgnoreExceptions(),
85 immediateFlush, advertise ? getConfiguration().getAdvertiser() : null);
86 }
87
88 public B setFileName(final String fileName) {
89 this.fileName = fileName;
90 return asBuilder();
91 }
92
93 public B setAppend(final boolean append) {
94 this.append = append;
95 return asBuilder();
96 }
97
98 public B setAdvertise(final boolean advertise) {
99 this.advertise = advertise;
100 return asBuilder();
101 }
102
103 public B setAdvertiseURI(final String advertiseURI) {
104 this.advertiseURI = advertiseURI;
105 return asBuilder();
106 }
107
108 }
109
110 private final String fileName;
111 private Object advertisement;
112 private final Advertiser advertiser;
113
114 private RandomAccessFileAppender(final String name, final Layout<? extends Serializable> layout,
115 final Filter filter, final RandomAccessFileManager manager, final String filename,
116 final boolean ignoreExceptions, final boolean immediateFlush, final Advertiser advertiser) {
117
118 super(name, layout, filter, ignoreExceptions, immediateFlush, manager);
119 if (advertiser != null) {
120 final Map<String, String> configuration = new HashMap<>(
121 layout.getContentFormat());
122 configuration.putAll(manager.getContentFormat());
123 configuration.put("contentType", layout.getContentType());
124 configuration.put("name", name);
125 advertisement = advertiser.advertise(configuration);
126 }
127 this.fileName = filename;
128 this.advertiser = advertiser;
129 }
130
131 @Override
132 public boolean stop(final long timeout, final TimeUnit timeUnit) {
133 setStopping();
134 super.stop(timeout, timeUnit, false);
135 if (advertiser != null) {
136 advertiser.unadvertise(advertisement);
137 }
138 setStopped();
139 return true;
140 }
141
142
143
144
145
146
147 @Override
148 public void append(final LogEvent event) {
149
150
151
152
153
154
155
156 getManager().setEndOfBatch(event.isEndOfBatch());
157
158
159 super.append(event);
160 }
161
162
163
164
165
166
167 public String getFileName() {
168 return this.fileName;
169 }
170
171
172
173
174
175 public int getBufferSize() {
176 return getManager().getBufferSize();
177 }
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204 @Deprecated
205 public static <B extends Builder<B>> RandomAccessFileAppender createAppender(
206 final String fileName,
207 final String append,
208 final String name,
209 final String immediateFlush,
210 final String bufferSizeStr,
211 final String ignore,
212 final Layout<? extends Serializable> layout,
213 final Filter filter,
214 final String advertise,
215 final String advertiseURI,
216 final Configuration configuration) {
217
218 final boolean isAppend = Booleans.parseBoolean(append, true);
219 final boolean isFlush = Booleans.parseBoolean(immediateFlush, true);
220 final boolean ignoreExceptions = Booleans.parseBoolean(ignore, true);
221 final boolean isAdvertise = Boolean.parseBoolean(advertise);
222 final int bufferSize = Integers.parseInt(bufferSizeStr, RandomAccessFileManager.DEFAULT_BUFFER_SIZE);
223
224 return RandomAccessFileAppender.<B>newBuilder()
225 .setAdvertise(isAdvertise)
226 .setAdvertiseURI(advertiseURI)
227 .setAppend(isAppend)
228 .withBufferSize(bufferSize)
229 .setConfiguration(configuration)
230 .setFileName(fileName)
231 .withFilter(filter)
232 .withIgnoreExceptions(ignoreExceptions)
233 .withImmediateFlush(isFlush)
234 .withLayout(layout)
235 .withName(name)
236 .build();
237 }
238
239
240
241
242
243 @PluginBuilderFactory
244 public static <B extends Builder<B>> B newBuilder() {
245 return new Builder<B>().asBuilder();
246 }
247
248 }