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