1
2
3
4
5
6
7
8
9
10
11
12
13 package org.abstracthorizon.danube.support.logging;
14
15 import org.abstracthorizon.danube.connection.Connection;
16 import org.abstracthorizon.danube.connection.ConnectionHandler;
17 import org.abstracthorizon.danube.support.RuntimeIOException;
18
19 import java.io.File;
20 import java.io.FileNotFoundException;
21 import java.io.FileOutputStream;
22 import java.io.IOException;
23 import java.io.OutputStream;
24 import java.net.InetAddress;
25 import java.net.InetSocketAddress;
26 import java.net.Socket;
27 import java.text.MessageFormat;
28 import java.util.Date;
29 import java.util.regex.Pattern;
30
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34
35
36
37
38
39 public class LoggingConnectionHandler implements ConnectionHandler {
40
41
42 protected final Logger logger = LoggerFactory.getLogger(getClass());
43
44
45 private ConnectionHandler connectionHandler;
46
47
48 private boolean logging = true;
49
50
51 private boolean directional = true;
52
53
54 private boolean tempLogging = false;
55
56
57 private String addressPatternString;
58
59
60 protected Pattern addressPattern;
61
62
63 private File logsPath;
64
65
66 private String logFileNamePatternString;
67
68
69 protected String logFileNamePattern;
70
71
72 private boolean resolveRemoteHostNames = false;
73
74
75
76
77 public LoggingConnectionHandler() {
78 setLogsPath(new File(System.getProperty("java.io.tmpdir")));
79 setAddressPattern(".*");
80 setLogFileNamePattern("log-%D-%T-%a:%p.log");
81 }
82
83
84
85
86
87
88 public String getAddressPattern() {
89 return addressPatternString;
90 }
91
92
93
94
95
96
97
98
99 public void setAddressPattern(String addressPatternString) {
100 this.addressPatternString = addressPatternString;
101 this.addressPattern = Pattern.compile(addressPatternString);
102 }
103
104
105
106
107
108 public ConnectionHandler getConnectionHandler() {
109 return connectionHandler;
110 }
111
112
113
114
115
116 public void setConnectionHandler(ConnectionHandler connectionHandler) {
117 this.connectionHandler = connectionHandler;
118 }
119
120
121
122
123
124 public boolean isDirectional() {
125 return directional;
126 }
127
128
129
130
131
132 public void setDirectional(boolean directional) {
133 this.directional = directional;
134 }
135
136
137
138
139
140
141 public String getLogFileNamePattern() {
142 return logFileNamePatternString;
143 }
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160 public void setLogFileNamePattern(String logFileNamePatternString) {
161 this.logFileNamePatternString = logFileNamePatternString;
162 this.logFileNamePattern = logFileNamePatternString
163 .replaceAll("%c", "{1,number,#}")
164 .replaceAll("%D", "{0,date,yyyyMMdd}")
165 .replaceAll("%T", "{0,time,HHmmssSSSS}")
166 .replaceAll("%A", "{4}")
167 .replaceAll("%a", "{2}")
168 .replaceAll("%P", "{5,number,#}")
169 .replaceAll("%p", "{3,number,#}")
170 ;
171 }
172
173
174
175
176
177
178
179 public boolean isLogging() {
180 return logging;
181 }
182
183
184
185
186
187 public void setLogging(boolean logging) {
188 this.logging = logging;
189 }
190
191
192
193
194
195 public File getLogsPath() {
196 return logsPath;
197 }
198
199
200
201
202
203 public void setLogsPath(File logsPath) {
204 this.logsPath = logsPath;
205 }
206
207
208
209
210
211
212 public boolean isTempLogging() {
213 return tempLogging;
214 }
215
216
217
218
219
220
221
222
223
224
225 public void setTempLogging(boolean tempLogging) {
226 this.tempLogging = tempLogging;
227 }
228
229
230
231
232
233
234
235 public boolean isResolveRemoteHostNames() {
236 return resolveRemoteHostNames;
237 }
238
239
240
241
242
243
244
245 public void setResolveRemoteHostNames(boolean resolveRemoteHostNames) {
246 this.resolveRemoteHostNames = resolveRemoteHostNames;
247 }
248
249
250
251
252
253
254
255
256 public void handleConnection(Connection connection) {
257 boolean log = isLogging();
258 boolean temporary = false;
259 if (log) {
260 boolean socketMatched = false;
261 Socket socket = (Socket)connection.adapt(Socket.class);
262 if (socket != null) {
263 String remoteHost = null;
264 InetAddress remoteAddress = ((InetSocketAddress)socket.getRemoteSocketAddress()).getAddress();
265 if (isResolveRemoteHostNames()) {
266 remoteHost = remoteAddress.getHostName();
267 } else {
268 remoteHost = remoteAddress.getHostAddress();
269 }
270 socketMatched = addressPattern.matcher(remoteHost).matches();
271 }
272 if (!socketMatched) {
273 if (isTempLogging()) {
274 temporary = true;
275 } else {
276 log = false;
277 }
278 } else {
279 temporary = false;
280 }
281 }
282
283 if (log) {
284 OutputStream logOutputStream = createLogOutputStream(connection, temporary);
285 LoggingConnection loggingConnection = null;
286 try {
287 loggingConnection = new LoggingConnection(connection, logOutputStream, directional, temporary);
288 loggingConnection.setTemporaryLog(temporary);
289 connectionHandler.handleConnection(loggingConnection);
290 } finally {
291
292 closeOutputStream(loggingConnection, logOutputStream);
293 }
294 } else {
295 connectionHandler.handleConnection(connection);
296 }
297 }
298
299
300
301
302
303
304
305
306
307
308 protected OutputStream createLogOutputStream(Connection connection, boolean temporary) {
309 String fileName;
310 Socket socket = (Socket)connection.adapt(Socket.class);
311 Date now = new Date();
312 if (socket != null) {
313 InetSocketAddress remote = (InetSocketAddress)socket.getRemoteSocketAddress();
314 InetSocketAddress local = (InetSocketAddress)socket.getLocalSocketAddress();
315 fileName = MessageFormat.format(logFileNamePattern, new Object[]{
316 now,
317 now.getTime(),
318 remote.getHostName(),
319 remote.getPort(),
320 local.getHostName(),
321 local.getPort()
322 }
323 );
324 } else {
325 fileName = MessageFormat.format(logFileNamePattern, new Object[]{
326 System.currentTimeMillis(),
327 null,
328 null,
329 null,
330 null
331 }
332 );
333 }
334
335 try {
336 File file = new File(logsPath, fileName);
337 if (logger.isDebugEnabled()) {
338 if (temporary) {
339 logger.debug("Creating temporary log file " + file.getAbsolutePath());
340 } else {
341 logger.debug("Creating log file " + file.getAbsolutePath());
342 }
343 }
344 FileOutputStream fileOutputStream = new InternalFileOutputStream(file);
345 return fileOutputStream;
346 } catch (IOException e) {
347 throw new RuntimeIOException(e);
348 }
349 }
350
351
352
353
354
355
356
357 protected void closeOutputStream(LoggingConnection loggingConnection, OutputStream logOutputStream) {
358 try {
359 logOutputStream.close();
360 } catch (IOException ignore) {
361 }
362 if ((loggingConnection == null) || loggingConnection.isTermporaryLog()) {
363 if (logOutputStream instanceof InternalFileOutputStream) {
364 InternalFileOutputStream fileOutputStream = (InternalFileOutputStream)logOutputStream;
365 File file = fileOutputStream.getFile();
366 if (logger.isDebugEnabled()) {
367 logger.debug("Removing temporary log file " + file.getAbsolutePath());
368 }
369 file.delete();
370 }
371 }
372 }
373
374
375
376
377
378
379
380 public static class InternalFileOutputStream extends FileOutputStream {
381
382
383 protected File file;
384
385
386
387
388
389
390 public InternalFileOutputStream(File file) throws FileNotFoundException {
391 super(file);
392 this.file = file;
393 }
394
395
396
397
398
399
400 public File getFile() {
401 return file;
402 }
403
404 }
405 }