Source code: nl/aidministrator/util/servlets/ServletLog.java
1 /* Sesame - Storage and Querying architecture for RDF and RDF Schema
2 * Copyright (C) 2002 Aidministrator Nederland b.v.
3 *
4 * Contact:
5 * Aidministrator Nederland b.v.
6 * Julianaplein 14b
7 * 3817 CS Amersfoort
8 * The Netherlands
9 * tel. +31(0)33 4659987
10 * fax. +31(0)33 4659987
11 * sesame@aidministrator.nl
12 *
13 * http://www.aidministrator.nl/
14 *
15 * This library is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU Lesser General Public
17 * License as published by the Free Software Foundation; either
18 * version 2.1 of the License, or (at your option) any later version.
19 *
20 * This library is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * Lesser General Public License for more details.
24 *
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with this library; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 */
29
30 package nl.aidministrator.util.servlets;
31
32 import java.io.*;
33 import java.text.*;
34 import java.util.*;
35
36 /**
37 * Servlet Logging Util. The ServletLog requires servlets to register
38 * themselves when their doGet() or doPost() method is called. In this
39 * registration procedure, a mapping is made between the thread that the
40 * servlet is running in and the host that it handles the request for. This
41 * mapping is later used in all calls to logging-methods to look-up the
42 * host for the thread calling the logging-methods.
43 */
44 public class ServletLog {
45
46 /*------------------------------------------------+
47 | Constants |
48 +------------------------------------------------*/
49
50 public static final int NONE = 0;
51 public static final int ERROR = 1;
52 public static final int WARNING = 2;
53 public static final int STATUS = 3;
54 public static final int TRACE = 4;
55 public static final int ALL = 5;
56
57 /*------------------------------------------------+
58 | Static variables |
59 +------------------------------------------------*/
60
61 protected static SimpleDateFormat _formatter =
62 new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
63
64 protected static String[] _levelNames =
65 { "NONE ", "ERROR ", "WARNING", "STATUS ", "TRACE ", "ALL " };
66
67
68 /** Maps Threads to ServletLogs. **/
69 protected static HashMap _threadTable = new HashMap();
70
71 /** Maps (absolute) file paths to PrintWriters. **/
72 protected static HashMap _writerTable = new HashMap();
73
74 /*------------------------------------------------+
75 | Static methods |
76 +------------------------------------------------*/
77
78 /**
79 * Sets the log file and log level for the thread calling this method.
80 * All following log messages sent by this thread with a priority equal to
81 * or higher than the indicated logLevel will be written to the indicated
82 * log file. If 'logFile' is equal to 'null', messages will be printed
83 * to System.err.
84 **/
85 public static void initThread(String logFile, int logLevel)
86 {
87 ServletLog servletLog = _createServletLog();
88 Writer logWriter = null;
89 try {
90 logWriter = _getLogWriter(logFile);
91 }
92 catch (IOException e) {
93 System.err.println(e.getMessage());
94 e.printStackTrace();
95
96 try {
97 logWriter = _getLogWriter(null);
98 }
99 catch (IOException ignore) { }
100 }
101 servletLog.setLogWriter(logWriter);
102 servletLog.setLogLevel(logLevel);
103
104 Thread currentThread = Thread.currentThread();
105 servletLog.setThreadName(currentThread.getName());
106 }
107
108 /**
109 * Creates a ServletLog for the thread calling this method. If the
110 * thread has already created a ServletLog before, this existing
111 * ServletLog will be returned.
112 **/
113 private static ServletLog _createServletLog() {
114 ServletLog servletLog = null;
115
116 Thread currentThread = Thread.currentThread();
117
118 synchronized (_threadTable) {
119 servletLog = (ServletLog)_threadTable.get(currentThread);
120 if (servletLog == null) {
121 servletLog = new ServletLog();
122 _threadTable.put(currentThread, servletLog);
123 }
124 }
125
126 return servletLog;
127 }
128
129 /**
130 * Gets the ServletLog for the thread calling this method. If no
131 * ServletLog is available, null will be returned.
132 **/
133 private static ServletLog _getServletLog() {
134 ServletLog servletLog = null;
135
136 Thread currentThread = Thread.currentThread();
137
138 synchronized (_threadTable) {
139 servletLog = (ServletLog)_threadTable.get(currentThread);
140 }
141
142 return servletLog;
143 }
144
145 private static Writer _getLogWriter(String logFile)
146 throws IOException
147 {
148 Writer logWriter = null;
149
150 String absPath = null;
151 File file = null;
152 if (logFile != null) {
153 file = new File(logFile);
154 absPath = file.getAbsolutePath();
155 }
156
157 synchronized (_writerTable) {
158 logWriter = (Writer)_writerTable.get(absPath);
159 if (logWriter == null) {
160 // Create a new log writer
161 if (absPath != null) {
162 // Check if parent directory exists yet
163 if (!file.getParentFile().exists()) {
164 file.getParentFile().mkdirs();
165 }
166 logWriter = new FileWriter(absPath, true);
167 }
168 else {
169 logWriter = new OutputStreamWriter(System.err);
170 }
171 _writerTable.put(absPath, logWriter);
172 }
173 }
174
175 return logWriter;
176 }
177
178
179 /*------------------------------------------------+
180 | Variables |
181 +------------------------------------------------*/
182
183 /** Writer for the log file. **/
184 protected Writer _logWriter;
185
186 /** Log level **/
187 protected int _logLevel;
188
189 /**
190 * Name of the thread.
191 **/
192 protected String _threadName;
193
194 /*------------------------------------------------+
195 | Constructors |
196 +------------------------------------------------*/
197
198 public ServletLog() {
199 this(null, ALL);
200 }
201
202 public ServletLog(Writer logWriter) {
203 this(logWriter, ALL);
204 }
205
206 public ServletLog(Writer logWriter, int logLevel) {
207 setLogWriter(logWriter);
208 setLogLevel(logLevel);
209 _threadName = null;
210 }
211
212
213 /*------------------------------------------------+
214 | Methods |
215 +------------------------------------------------*/
216
217 public void setLogWriter(Writer logWriter) {
218 _logWriter = logWriter;
219 }
220
221 public void setLogLevel(int logLevel) {
222 _logLevel = logLevel;
223 }
224
225 public int getLogLevel() {
226 return _logLevel;
227 }
228
229 public void setThreadName(String threadName) {
230 _threadName = threadName;
231 }
232
233 public String getThreadName() {
234 return _threadName;
235 }
236
237 public void doLog(String msg, Object arg, int level) {
238 // First check log level
239 if (_logLevel < level) {
240 return;
241 }
242
243 // Create log message
244 String logMsg = _createLogMessage(msg, arg, level, _threadName);
245
246 // Write log message
247 // Synchronize on _logWriter to prevent mixed lines
248 try {
249 synchronized(_logWriter) {
250 _logWriter.write(logMsg);
251 _logWriter.flush();
252 }
253 }
254 catch(Exception e) {
255 e.printStackTrace();
256 }
257 }
258
259 private static String _createLogMessage(String msg, Object arg,
260 int level, String threadName)
261 {
262 StringBuffer logMsg = new StringBuffer();
263
264 logMsg.append(_formatter.format(new Date()));
265 if (threadName != null) {
266 logMsg.append(" [");
267 logMsg.append(threadName);
268 logMsg.append("]");
269 }
270 logMsg.append(" [");
271 logMsg.append(_levelNames[level]);
272 logMsg.append("] ");
273
274 logMsg.append(msg);
275 if(arg != null) {
276 logMsg.append(": ");
277 logMsg.append(arg);
278 }
279 logMsg.append("\n");
280
281 return logMsg.toString();
282 }
283
284 /*------------------------------------------------+
285 | Static utility methods |
286 +------------------------------------------------*/
287
288 // ERROR
289 public static void error(String msg) {
290 _log(msg, null, ERROR);
291 }
292 public static void error(String msg, int c) {
293 _log(msg, String.valueOf(c), ERROR);
294 }
295 public static void error(String msg, Object arg) {
296 _log(msg, arg, ERROR);
297 }
298
299 // WARNING
300 public static void warning(String msg) {
301 _log(msg, null, WARNING);
302 }
303 public static void warning(String msg, int c) {
304 _log(msg, String.valueOf(c), WARNING);
305 }
306 public static void warning(String msg, Object arg) {
307 _log(msg, arg, WARNING);
308 }
309
310 // LOG
311 public static void log(String msg) {
312 _log(msg, null, STATUS);
313 }
314 public static void log(String msg, int c) {
315 _log(msg, String.valueOf(c), STATUS);
316 }
317 public static void log(String msg, Object arg) {
318 _log(msg, arg, STATUS);
319 }
320
321 // TRACE
322 public static void trace(String msg) {
323 _log(msg, null, TRACE);
324 }
325 public static void trace(String msg, int c) {
326 _log(msg, String.valueOf(c), TRACE);
327 }
328 public static void trace(String msg, Object arg) {
329 _log(msg, arg, TRACE);
330 }
331
332 protected static void _log(String msg, Object arg, int level) {
333 ServletLog servletLog = _getServletLog();
334 if (servletLog != null) {
335 servletLog.doLog(msg, arg, level);
336 }
337 else {
338 String logMsg = _createLogMessage(msg, arg, level, null);
339 System.err.println(logMsg);
340 }
341 }
342 }