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 }