Source code: hk/hku/cecid/phoenix/common/util/Logger.java
1 /*
2 * Academic Free License
3 * Version 1.0
4 *
5 * This Academic Free License applies to any software and associated
6 * documentation (the "Software") whose owner (the "Licensor") has placed the
7 * statement "Licensed under the Academic Free License Version 1.0" immediately
8 * after the copyright notice that applies to the Software.
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of the Software (1) to use, copy, modify, merge, publish, perform,
12 * distribute, sublicense, and/or sell copies of the Software, and to permit
13 * persons to whom the Software is furnished to do so, and (2) under patent
14 * claims owned or controlled by the Licensor that are embodied in the Software
15 * as furnished by the Licensor, to make, use, sell and offer for sale the
16 * Software and derivative works thereof, subject to the following conditions:
17 *
18 * - Redistributions of the Software in source code form must retain all
19 * copyright notices in the Software as furnished by the Licensor, this list
20 * of conditions, and the following disclaimers.
21 * - Redistributions of the Software in executable form must reproduce all
22 * copyright notices in the Software as furnished by the Licensor, this list
23 * of conditions, and the following disclaimers in the documentation and/or
24 * other materials provided with the distribution.
25 * - Neither the names of Licensor, nor the names of any contributors to the
26 * Software, nor any of their trademarks or service marks, may be used to
27 * endorse or promote products derived from this Software without express
28 * prior written permission of the Licensor.
29 *
30 * DISCLAIMERS: LICENSOR WARRANTS THAT THE COPYRIGHT IN AND TO THE SOFTWARE IS
31 * OWNED BY THE LICENSOR OR THAT THE SOFTWARE IS DISTRIBUTED BY LICENSOR UNDER
32 * A VALID CURRENT LICENSE. EXCEPT AS EXPRESSLY STATED IN THE IMMEDIATELY
33 * PRECEDING SENTENCE, THE SOFTWARE IS PROVIDED BY THE LICENSOR, CONTRIBUTORS
34 * AND COPYRIGHT OWNERS "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
35 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
37 * LICENSOR, CONTRIBUTORS OR COPYRIGHT OWNERS BE LIABLE FOR ANY CLAIM, DAMAGES
38 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
39 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE.
40 *
41 * This license is Copyright (C) 2002 Lawrence E. Rosen. All rights reserved.
42 * Permission is hereby granted to copy and distribute this license without
43 * modification. This license may not be modified without the express written
44 * permission of its copyright owner.
45 */
46
47 /* =====
48 *
49 * $Header: /ebxml/staff/cecid/cvs_repository/common/src/hk/hku/cecid/phoenix/common/util/Logger.java,v 1.15 2002/12/13 03:59:03 kcyee Exp $
50 *
51 * Code authored by:
52 *
53 * kcyee [2002-05-28]
54 *
55 * Code reviewed by:
56 *
57 * username [YYYY-MM-DD]
58 *
59 * Remarks:
60 *
61 * =====
62 */
63
64 package hk.hku.cecid.phoenix.common.util;
65
66 import java.io.File;
67 import java.io.IOException;
68 import java.util.HashMap;
69
70 /**
71 * This is a wrapper class for logging. This class shields the complexity
72 * for using JDK1.3 or JDK1.4, using log4j or JDK Logging API. All
73 * configuration information are read from properties file.
74 *
75 * @author kcyee
76 * @version $Revision: 1.15 $
77 */
78 public abstract class Logger {
79
80 /**
81 * Default name of log file
82 */
83 protected static final String DEF_LOGFILE = "phoenix.log";
84
85 /**
86 * Minumum limit size for rolling log files
87 */
88 protected static final int MIN_ROLLING_SIZE = 1000;
89
90 /**
91 * Variable controlling whether to use JDK 1.4 Logging or not
92 */
93 protected static boolean useJDK;
94
95 /**
96 * Variable for full path of the log file
97 */
98 protected static String logFileName;
99
100 /**
101 * Variable for the log level
102 */
103 protected static int level;
104
105 /**
106 * Variable for the maximum log file size (rotating log)
107 */
108 protected static int size;
109
110 /**
111 * Variable holding the home directory of the user
112 */
113 protected static String homeDir;
114
115 /**
116 * Variable holding the file separator charactor
117 */
118 protected static String fileSep;
119
120 /**
121 * Cached logger
122 */
123 protected static HashMap cache;
124
125 static {
126
127 homeDir = System.getProperty("user.home");
128 fileSep = System.getProperty("file.separator");
129
130 // Default to use LOG4J logging
131 useJDK = false;
132
133 // Default log file path: $HOME/phoenix.log
134 logFileName = homeDir + fileSep + DEF_LOGFILE;
135
136 // initialize cache
137 cache = new HashMap();
138 }
139
140 /**
141 * The class name for logging in funcIn/fucnOut. This is to be the
142 * same as the name for use in getLogger().
143 */
144 protected String className;
145
146 /**
147 * Does a level 0 logging. Equivalent to debug() in Log4J.
148 *
149 * @param mesg message to be logged
150 */
151 public abstract void debug(String mesg); // level 0
152
153 /**
154 * Does a level 1 logging. Equivalent to info() in Log4J.
155 *
156 * @param mesg message to be logged
157 */
158 public abstract void info(String mesg); // level 1
159
160 /**
161 * Does a level 2 logging. Equivalent to warn() in Log4J.
162 *
163 * @param mesg message to be logged
164 */
165 public abstract void warn(String mesg); // level 2
166
167 /**
168 * Does a level 3 logging. Equivalent to error() in Log4J.
169 *
170 * @param mesg message to be logged
171 */
172 public abstract void error(String mesg); // level 3
173
174 /**
175 * Does a level 0 logging on function in/out.
176 *
177 * @param className the class name to be logged
178 * @param funcName the function name to be logged
179 */
180 public void funcIn(String funcName) {
181 StringBuffer sb = new StringBuffer("=> ");
182 sb.append(className).append(" ").append(funcName);
183 debug(sb.toString());
184 }
185
186 /**
187 * Does a level 0 logging on function in/out.
188 *
189 * @param className the class name to be logged
190 * @param funcName the function name to be logged
191 */
192 public void funcOut(String funcName) {
193 StringBuffer sb = new StringBuffer("<= ");
194 sb.append(className).append(" ").append(funcName);
195 debug(sb.toString());
196 }
197
198 protected void setLoggingClassName(String name) {
199 className = name;
200 int index = name.lastIndexOf(".");
201 if (index >= 0) {
202 try {
203 className = name.substring(index + 1);
204 }
205 catch (IndexOutOfBoundsException e) {}
206 }
207 }
208
209 /**
210 * Sets logging property by providing a <code>Property</code> object.
211 * The change of setting will affect the log objects created afterwards.
212 * All log objects created beforehand will not be affected.
213 *
214 * @param prop The property object controlling the logging behaviour
215 */
216 public static void setLoggingProperty(Property prop) {
217 if (prop != null) {
218 String useLogger = prop.get("Log/UseLogger");
219 String logPath = prop.get("Log/LogPath");
220 String logFile = prop.get("Log/LogFile");
221 String logLevel = prop.get("Log/LogLevel");
222 String logSize = prop.get("Log/MaxLogSize");
223 setLoggingProperty(useLogger, logPath, logFile, logLevel, logSize);
224 }
225 else {
226 useJDK = false;
227 logFileName = homeDir + fileSep + DEF_LOGFILE;
228 }
229 }
230
231 /**
232 * Sets logging property by providing individual property values.
233 * The change of setting will affect the log objects created afterwards.
234 * All log objects created beforehand will not be affected.
235 *
236 * @param useLogger the logger used (expected "LOG4J" or "JDK")
237 * @param logPath the directory to store the log file
238 * @param logFile the file name of the log file
239 * @param logLevel the log level (0-4)
240 */
241 public static void setLoggingProperty(String useLogger,
242 String logPath, String logFile, String logLevel, String logSize) {
243
244 double javaVersion = Version.getJDKVersion();
245 if (useLogger != null) {
246 useJDK = useLogger.equals("JDK") && (javaVersion >= 1.4);
247 }
248 else {
249 useJDK = false;
250 }
251
252 if (logPath != null && logFile != null) {
253 try {
254 File path = new File(logPath);
255 if (!path.exists()) {
256 path.mkdirs();
257 }
258 logFileName = logPath + fileSep + logFile;
259 }
260 catch (SecurityException e) {
261 logFileName = homeDir + fileSep + DEF_LOGFILE;
262 Logger log = getLogger(Logger.class.getName());
263 log.error("Cannot write to " + logFileName + "!");
264 }
265 }
266 else {
267 logFileName = homeDir + fileSep + DEF_LOGFILE;
268 }
269
270 File fileLog = new File(logFileName);
271 if (fileLog.exists() && !fileLog.canWrite()) {
272 String oldLogFileName = logFileName;
273 logFileName = homeDir + fileSep + DEF_LOGFILE;
274 Logger log = getLogger(Logger.class.getName());
275 log.error("Cannot write to " + oldLogFileName + "!");
276 }
277
278 if (logLevel != null) {
279 try {
280 level = Integer.parseInt(logLevel);
281 }
282 catch (NumberFormatException e) {
283 level = 0;
284 }
285 }
286 else {
287 level = 0;
288 }
289
290 if (logSize != null) {
291 try {
292 size = Integer.parseInt(logSize);
293 }
294 catch (NumberFormatException e) {
295 size = -1;
296 }
297 }
298 else {
299 size = -1;
300 }
301 }
302
303 /**
304 * Gets a logger instance by a specified name as key. Internally, passing
305 * the same name as parameters will always get the same Logger object.
306 * Whether the logger instance is a JDK-based, or Log4J-based in
307 * automatically determined.
308 *
309 * @param name the name associated with the Logger
310 * @return a logger instance for logging
311 */
312 public static Logger getLogger(String name) {
313
314 Logger logger = (Logger) cache.get(name);
315
316 if (logger != null) {
317 return logger;
318 }
319
320 if (useJDK) {
321 logger = new JDKLogger(name);
322 }
323 else {
324 logger = new Log4JLogger(name);
325 }
326
327 if (logger != null) {
328 cache.put(name, logger);
329 }
330
331 return logger;
332 }
333 }
334