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