1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.core;
15
16 import java.io.BufferedWriter;
17 import java.io.File;
18 import java.io.FileOutputStream;
19 import java.io.IOException;
20 import java.io.Writer;
21 import java.nio.channels.FileChannel;
22 import java.nio.channels.FileLock;
23
24 import ch.qos.logback.core.util.FileUtil;
25
26
27
28
29
30
31
32
33
34 public class FileAppender<E> extends WriterAppender<E> {
35
36
37
38
39
40
41 protected boolean append = true;
42
43
44
45
46 protected String fileName = null;
47
48
49
50
51 protected boolean bufferedIO = false;
52
53
54
55
56 protected int bufferSize = 8 * 1024;
57
58 private boolean prudent = false;
59
60 private FileChannel fileChannel = null;
61
62
63
64
65 public FileAppender() {
66 }
67
68
69
70
71
72 public void setFile(String file) {
73 if (file == null) {
74 fileName = file;
75 } else {
76
77
78 String val = file.trim();
79 fileName = val;
80 }
81 }
82
83
84
85
86 public boolean getAppend() {
87 return append;
88 }
89
90
91
92
93 public boolean isAppend() {
94 return append;
95 }
96
97
98
99
100
101
102
103 final public String rawFileProperty() {
104 return fileName;
105 }
106
107
108
109
110
111
112
113 public String getFile() {
114 return fileName;
115 }
116
117
118
119
120
121
122 public void start() {
123 int errors = 0;
124 if (getFile() != null) {
125 addInfo("File property is set to [" + fileName + "]");
126
127 if (prudent) {
128 if (isAppend() == false) {
129 setAppend(true);
130 addWarn("Setting \"Append\" property to true on account of \"Prudent\" mode");
131 }
132 if (getImmediateFlush() == false) {
133 setImmediateFlush(true);
134 addWarn("Setting \"ImmediateFlush\" to true on account of \"Prudent\" mode");
135 }
136
137 if (bufferedIO == true) {
138 setBufferedIO(false);
139 addWarn("Setting \"BufferedIO\" property to false on account of \"Prudent\" mode");
140 }
141 }
142
143
144
145
146
147 if (bufferedIO) {
148 setImmediateFlush(false);
149 addInfo("Setting \"ImmediateFlush\" property to false on account of \"bufferedIO\" property");
150 }
151
152 try {
153 openFile(getFile());
154 } catch (java.io.IOException e) {
155 errors++;
156 addError("openFile(" + fileName + "," + append + ") call failed.", e);
157 }
158 } else {
159 errors++;
160 addError("\"File\" property not set for appender named [" + name + "].");
161 }
162 if (errors == 0) {
163 super.start();
164 }
165 }
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188 public synchronized void openFile(String file_name) throws IOException {
189 File file = new File(file_name);
190 if (FileUtil.mustCreateParentDirectories(file)) {
191 boolean result = FileUtil.createMissingParentDirectories(file);
192 if (!result) {
193 addError("Failed to create parent directories for ["
194 + file.getAbsolutePath() + "]");
195 }
196 }
197
198 FileOutputStream fileOutputStream = new FileOutputStream(file_name, append);
199 if (prudent) {
200 fileChannel = fileOutputStream.getChannel();
201 }
202 Writer w = createWriter(fileOutputStream);
203 if (bufferedIO) {
204 w = new BufferedWriter(w, bufferSize);
205 }
206 setWriter(w);
207 }
208
209 public boolean isBufferedIO() {
210 return bufferedIO;
211 }
212
213 public void setBufferedIO(boolean bufferedIO) {
214 this.bufferedIO = bufferedIO;
215 }
216
217 public int getBufferSize() {
218 return bufferSize;
219 }
220
221 public void setBufferSize(int bufferSize) {
222 this.bufferSize = bufferSize;
223 }
224
225
226
227
228
229
230 public boolean isPrudent() {
231 return prudent;
232 }
233
234
235
236
237
238
239
240 public void setPrudent(boolean prudent) {
241 this.prudent = prudent;
242 }
243
244 public void setAppend(boolean append) {
245 this.append = append;
246 }
247
248 final private void safeWrite(String s) throws IOException {
249 FileLock fileLock = null;
250 try {
251 fileLock = fileChannel.lock();
252 long position = fileChannel.position();
253 long size = fileChannel.size();
254 if (size != position) {
255 fileChannel.position(size);
256 }
257 super.writerWrite(s, true);
258 } finally {
259 if (fileLock != null) {
260 fileLock.release();
261 }
262 }
263 }
264
265 @Override
266 protected void writerWrite(String s, boolean flush) throws IOException {
267 if (prudent && fileChannel != null) {
268 safeWrite(s);
269 } else {
270 super.writerWrite(s, flush);
271 }
272 }
273 }