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.BufferedOutputStream;
20 import java.io.File;
21 import java.io.FileNotFoundException;
22 import java.io.FileOutputStream;
23 import java.io.IOException;
24 import java.io.OutputStream;
25 import java.io.Serializable;
26 import java.nio.channels.FileChannel;
27 import java.nio.channels.FileLock;
28 import java.util.HashMap;
29 import java.util.Map;
30
31 import org.apache.logging.log4j.core.Layout;
32
33
34
35
36
37 public class FileManager extends OutputStreamManager {
38
39 private static final FileManagerFactory FACTORY = new FileManagerFactory();
40
41 private final boolean isAppend;
42 private final boolean isLocking;
43 private final String advertiseURI;
44
45 protected FileManager(final String fileName, final OutputStream os, final boolean append, final boolean locking,
46 final String advertiseURI, final Layout<? extends Serializable> layout) {
47 super(os, fileName, layout);
48 this.isAppend = append;
49 this.isLocking = locking;
50 this.advertiseURI = advertiseURI;
51 }
52
53
54
55
56
57
58
59
60
61
62
63
64 public static FileManager getFileManager(final String fileName, final boolean append, boolean locking,
65 final boolean bufferedIO, final String advertiseURI, final Layout<? extends Serializable> layout,
66 final int bufferSize) {
67
68 if (locking && bufferedIO) {
69 locking = false;
70 }
71 return (FileManager) getManager(fileName, new FactoryData(append, locking, bufferedIO, bufferSize,
72 advertiseURI, layout), FACTORY);
73 }
74
75 @Override
76 protected synchronized void write(final byte[] bytes, final int offset, final int length) {
77
78 if (isLocking) {
79 final FileChannel channel = ((FileOutputStream) getOutputStream()).getChannel();
80 try {
81
82
83
84
85
86
87
88 final FileLock lock = channel.lock(0, Long.MAX_VALUE, false);
89 try {
90 super.write(bytes, offset, length);
91 } finally {
92 lock.release();
93 }
94 } catch (final IOException ex) {
95 throw new AppenderLoggingException("Unable to obtain lock on " + getName(), ex);
96 }
97
98 } else {
99 super.write(bytes, offset, length);
100 }
101 }
102
103
104
105
106
107 public String getFileName() {
108 return getName();
109 }
110
111
112
113
114
115 public boolean isAppend() {
116 return isAppend;
117 }
118
119
120
121
122
123 public boolean isLocking() {
124 return isLocking;
125 }
126
127
128
129
130
131
132 @Override
133 public Map<String, String> getContentFormat() {
134 final Map<String, String> result = new HashMap<String, String>(super.getContentFormat());
135 result.put("fileURI", advertiseURI);
136 return result;
137 }
138
139
140
141
142 private static class FactoryData {
143 private final boolean append;
144 private final boolean locking;
145 private final boolean bufferedIO;
146 private final int bufferSize;
147 private final String advertiseURI;
148 private final Layout<? extends Serializable> layout;
149
150
151
152
153
154
155
156
157
158 public FactoryData(final boolean append, final boolean locking, final boolean bufferedIO, final int bufferSize,
159 final String advertiseURI, final Layout<? extends Serializable> layout) {
160 this.append = append;
161 this.locking = locking;
162 this.bufferedIO = bufferedIO;
163 this.bufferSize = bufferSize;
164 this.advertiseURI = advertiseURI;
165 this.layout = layout;
166 }
167 }
168
169
170
171
172 private static class FileManagerFactory implements ManagerFactory<FileManager, FactoryData> {
173
174
175
176
177
178
179
180 @Override
181 public FileManager createManager(final String name, final FactoryData data) {
182 final File file = new File(name);
183 final File parent = file.getParentFile();
184 if (null != parent && !parent.exists()) {
185 parent.mkdirs();
186 }
187
188 OutputStream os;
189 try {
190 os = new FileOutputStream(name, data.append);
191 if (data.bufferedIO) {
192 os = new BufferedOutputStream(os, data.bufferSize);
193 }
194 return new FileManager(name, os, data.append, data.locking, data.advertiseURI, data.layout);
195 } catch (final FileNotFoundException ex) {
196 LOGGER.error("FileManager (" + name + ") " + ex);
197 }
198 return null;
199 }
200 }
201
202 }