001: /*******************************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: *******************************************************************************/package org.ofbiz.base.util;
019:
020: import java.io.IOException;
021: import java.io.PrintStream;
022: import java.io.PrintWriter;
023: import java.text.DateFormat;
024: import java.util.Enumeration;
025: import java.util.HashMap;
026: import java.util.Map;
027:
028: import org.apache.avalon.util.exception.ExceptionHelper;
029: import org.apache.log4j.Level;
030: import org.apache.log4j.Logger;
031: import org.apache.log4j.PatternLayout;
032: import org.apache.log4j.PropertyConfigurator;
033: import org.apache.log4j.RollingFileAppender;
034: import org.apache.log4j.Appender;
035: import org.apache.log4j.Priority;
036: import org.apache.log4j.spi.LoggerRepository;
037:
038: import org.ofbiz.base.util.collections.FlexibleProperties;
039:
040: /**
041: * Configurable Debug logging wrapper class
042: *
043: */
044: public final class Debug {
045:
046: public static final boolean useLog4J = true;
047: public static final String noModuleModule = "NoModule"; // set to null for previous behavior
048:
049: static DateFormat dateFormat = DateFormat.getDateTimeInstance(
050: DateFormat.SHORT, DateFormat.MEDIUM);
051:
052: public static final String SYS_DEBUG = System.getProperty("DEBUG");
053: public static final int ALWAYS = 0;
054: public static final int VERBOSE = 1;
055: public static final int TIMING = 2;
056: public static final int INFO = 3;
057: public static final int IMPORTANT = 4;
058: public static final int WARNING = 5;
059: public static final int ERROR = 6;
060: public static final int FATAL = 7;
061:
062: public static final String[] levels = { "Always", "Verbose",
063: "Timing", "Info", "Important", "Warning", "Error", "Fatal" };
064: public static final String[] levelProps = { "", "print.verbose",
065: "print.timing", "print.info", "print.important",
066: "print.warning", "print.error", "print.fatal" };
067: public static final Level[] levelObjs = { Level.INFO, Level.DEBUG,
068: Level.DEBUG, Level.INFO, Level.INFO, Level.WARN,
069: Level.ERROR, Level.FATAL };
070:
071: protected static Map levelStringMap = new HashMap();
072:
073: protected static PrintStream printStream = System.out;
074: protected static PrintWriter printWriter = new PrintWriter(
075: printStream);
076:
077: protected static boolean levelOnCache[] = new boolean[8];
078: protected static boolean packException = true;
079: protected static final boolean useLevelOnCache = true;
080:
081: protected static Logger root = Logger.getRootLogger();
082:
083: static {
084: levelStringMap.put("verbose", new Integer(Debug.VERBOSE));
085: levelStringMap.put("timing", new Integer(Debug.TIMING));
086: levelStringMap.put("info", new Integer(Debug.INFO));
087: levelStringMap.put("important", new Integer(Debug.IMPORTANT));
088: levelStringMap.put("warning", new Integer(Debug.WARNING));
089: levelStringMap.put("error", new Integer(Debug.ERROR));
090: levelStringMap.put("fatal", new Integer(Debug.FATAL));
091: levelStringMap.put("always", new Integer(Debug.ALWAYS));
092:
093: // initialize Log4J
094: PropertyConfigurator.configure(FlexibleProperties
095: .makeFlexibleProperties(UtilURL
096: .fromResource("debug.properties")));
097:
098: // initialize levelOnCache
099: for (int i = 0; i < 8; i++) {
100: levelOnCache[i] = (i == Debug.ALWAYS || UtilProperties
101: .propertyValueEqualsIgnoreCase("debug.properties",
102: levelProps[i], "true"));
103: }
104:
105: if (SYS_DEBUG != null) {
106: for (int x = 0; x < 8; x++) {
107: levelOnCache[x] = true;
108: }
109: LoggerRepository repo = root.getLoggerRepository();
110: Enumeration en = repo.getCurrentLoggers();
111: while (en.hasMoreElements()) {
112: Logger this Logger = (Logger) en.nextElement();
113: this Logger.setLevel(Level.DEBUG);
114: }
115: }
116:
117: // configure exception packing
118: packException = UtilProperties.propertyValueEqualsIgnoreCase(
119: "debug.properties", "pack.exception", "true");
120: }
121:
122: public static PrintStream getPrintStream() {
123: return printStream;
124: }
125:
126: public static void setPrintStream(PrintStream printStream) {
127: Debug.printStream = printStream;
128: Debug.printWriter = new PrintWriter(printStream);
129: }
130:
131: public static PrintWriter getPrintWriter() {
132: return printWriter;
133: }
134:
135: public static Logger getLogger(String module) {
136: if (module != null && module.length() > 0) {
137: return Logger.getLogger(module);
138: } else {
139: return root;
140: }
141: }
142:
143: /** Gets an Integer representing the level number from a String representing the level name; will return null if not found */
144: public static Integer getLevelFromString(String levelName) {
145: if (levelName == null)
146: return null;
147: return (Integer) levelStringMap.get(levelName.toLowerCase());
148: }
149:
150: /** Gets an int representing the level number from a String representing the level name; if level not found defaults to Debug.INFO */
151: public static int getLevelFromStringWithDefault(String levelName) {
152: Integer levelInt = getLevelFromString(levelName);
153: if (levelInt == null) {
154: return Debug.INFO;
155: } else {
156: return levelInt.intValue();
157: }
158: }
159:
160: public static void log(int level, Throwable t, String msg,
161: String module) {
162: log(level, t, msg, module, "org.ofbiz.base.util.Debug");
163: }
164:
165: public static void log(int level, Throwable t, String msg,
166: String module, String callingClass) {
167: if (isOn(level)) {
168: // pack the exception
169: if (packException && t != null) {
170: msg = System.getProperty("line.separator")
171: + ExceptionHelper.packException(msg, t, true);
172: t = null;
173: }
174:
175: // log
176: if (useLog4J) {
177: Logger logger = getLogger(module);
178: if (SYS_DEBUG != null) {
179: logger.setLevel(Level.DEBUG);
180: }
181: logger.log(callingClass, levelObjs[level], msg, t);
182: } else {
183: StringBuffer prefixBuf = new StringBuffer();
184:
185: prefixBuf.append(dateFormat
186: .format(new java.util.Date()));
187: prefixBuf.append(" [OFBiz");
188: if (module != null) {
189: prefixBuf.append(":");
190: prefixBuf.append(module);
191: }
192: prefixBuf.append(":");
193: prefixBuf.append(levels[level]);
194: prefixBuf.append("] ");
195: if (msg != null) {
196: getPrintWriter().print(prefixBuf.toString());
197: getPrintWriter().println(msg);
198: }
199: if (t != null) {
200: getPrintWriter().print(prefixBuf.toString());
201: getPrintWriter().println("Received throwable:");
202: t.printStackTrace(getPrintWriter());
203: }
204: }
205: }
206: }
207:
208: public static boolean isOn(int level) {
209: if (useLevelOnCache) {
210: return levelOnCache[level];
211: } else {
212: return (level == Debug.ALWAYS || UtilProperties
213: .propertyValueEqualsIgnoreCase("debug",
214: levelProps[level], "true"));
215: }
216: }
217:
218: // leaving these here
219: public static void log(String msg) {
220: log(Debug.ALWAYS, null, msg, noModuleModule);
221: }
222:
223: public static void log(Throwable t) {
224: log(Debug.ALWAYS, t, null, noModuleModule);
225: }
226:
227: public static void log(String msg, String module) {
228: log(Debug.ALWAYS, null, msg, module);
229: }
230:
231: public static void log(Throwable t, String module) {
232: log(Debug.ALWAYS, t, null, module);
233: }
234:
235: public static void log(Throwable t, String msg, String module) {
236: log(Debug.ALWAYS, t, msg, module);
237: }
238:
239: public static boolean verboseOn() {
240: return isOn(Debug.VERBOSE);
241: }
242:
243: public static void logVerbose(String msg, String module) {
244: log(Debug.VERBOSE, null, msg, module);
245: }
246:
247: public static void logVerbose(Throwable t, String module) {
248: log(Debug.VERBOSE, t, null, module);
249: }
250:
251: public static void logVerbose(Throwable t, String msg, String module) {
252: log(Debug.VERBOSE, t, msg, module);
253: }
254:
255: public static boolean timingOn() {
256: return isOn(Debug.TIMING);
257: }
258:
259: public static void logTiming(String msg, String module) {
260: log(Debug.TIMING, null, msg, module);
261: }
262:
263: public static void logTiming(Throwable t, String module) {
264: log(Debug.TIMING, t, null, module);
265: }
266:
267: public static void logTiming(Throwable t, String msg, String module) {
268: log(Debug.TIMING, t, msg, module);
269: }
270:
271: public static boolean infoOn() {
272: return isOn(Debug.INFO);
273: }
274:
275: public static void logInfo(String msg, String module) {
276: log(Debug.INFO, null, msg, module);
277: }
278:
279: public static void logInfo(Throwable t, String module) {
280: log(Debug.INFO, t, null, module);
281: }
282:
283: public static void logInfo(Throwable t, String msg, String module) {
284: log(Debug.INFO, t, msg, module);
285: }
286:
287: public static boolean importantOn() {
288: return isOn(Debug.IMPORTANT);
289: }
290:
291: public static void logImportant(String msg, String module) {
292: log(Debug.IMPORTANT, null, msg, module);
293: }
294:
295: public static void logImportant(Throwable t, String module) {
296: log(Debug.IMPORTANT, t, null, module);
297: }
298:
299: public static void logImportant(Throwable t, String msg,
300: String module) {
301: log(Debug.IMPORTANT, t, msg, module);
302: }
303:
304: public static boolean warningOn() {
305: return isOn(Debug.WARNING);
306: }
307:
308: public static void logWarning(String msg, String module) {
309: log(Debug.WARNING, null, msg, module);
310: }
311:
312: public static void logWarning(Throwable t, String module) {
313: log(Debug.WARNING, t, null, module);
314: }
315:
316: public static void logWarning(Throwable t, String msg, String module) {
317: log(Debug.WARNING, t, msg, module);
318: }
319:
320: public static boolean errorOn() {
321: return isOn(Debug.ERROR);
322: }
323:
324: public static void logError(String msg, String module) {
325: log(Debug.ERROR, null, msg, module);
326: }
327:
328: public static void logError(Throwable t, String module) {
329: log(Debug.ERROR, t, null, module);
330: }
331:
332: public static void logError(Throwable t, String msg, String module) {
333: log(Debug.ERROR, t, msg, module);
334: }
335:
336: public static boolean fatalOn() {
337: return isOn(Debug.FATAL);
338: }
339:
340: public static void logFatal(String msg, String module) {
341: log(Debug.FATAL, null, msg, module);
342: }
343:
344: public static void logFatal(Throwable t, String module) {
345: log(Debug.FATAL, t, null, module);
346: }
347:
348: public static void logFatal(Throwable t, String msg, String module) {
349: log(Debug.FATAL, t, msg, module);
350: }
351:
352: public static void set(int level, boolean on) {
353: if (!useLevelOnCache)
354: return;
355: levelOnCache[level] = on;
356: }
357:
358: public static synchronized Appender getNewFileAppender(String name,
359: String logFile, long maxSize, int backupIdx, String pattern) {
360: if (pattern == null) {
361: pattern = "%-5r[%24F:%-3L:%-5p]%x %m%n";
362: }
363:
364: PatternLayout layout = new PatternLayout(pattern);
365: layout.activateOptions();
366:
367: RollingFileAppender newAppender = null;
368: try {
369: newAppender = new RollingFileAppender(layout, logFile, true);
370: } catch (IOException e) {
371: logFatal(e, Debug.class.getName());
372: }
373:
374: if (newAppender != null) {
375: if (backupIdx > 0) {
376: newAppender.setMaxBackupIndex(backupIdx);
377: }
378: if (maxSize > 0) {
379: newAppender.setMaximumFileSize(maxSize);
380: }
381: newAppender.setThreshold(Priority.DEBUG);
382: newAppender.activateOptions();
383: newAppender.setName(name);
384: }
385:
386: return newAppender;
387: }
388:
389: public static boolean registerFileAppender(String module,
390: String name, String logFile, long maxSize, int backupIdx,
391: String pattern) {
392: Logger logger = Logger.getLogger(module);
393: boolean found = false;
394:
395: Appender foundAppender = logger.getAppender(name);
396: if (foundAppender == null) {
397: Enumeration currentLoggerEnum = Logger.getRootLogger()
398: .getLoggerRepository().getCurrentLoggers();
399: while (currentLoggerEnum.hasMoreElements()
400: && foundAppender == null) {
401: Logger log = (Logger) currentLoggerEnum.nextElement();
402: foundAppender = log.getAppender(name);
403: }
404: } else {
405: return true;
406: }
407:
408: if (foundAppender == null) {
409: if (logFile != null) {
410: foundAppender = getNewFileAppender(name, logFile,
411: maxSize, backupIdx, pattern);
412: if (foundAppender != null) {
413: found = true;
414: }
415: }
416: } else {
417: found = true;
418: }
419:
420: logger.addAppender(foundAppender);
421: return found;
422: }
423:
424: public static boolean registerFileAppender(String module,
425: String name, String logFile) {
426: return registerFileAppender(module, name, logFile, 0, 10, null);
427: }
428:
429: public static boolean registerFileAppender(String module,
430: String name) {
431: return registerFileAppender(module, name, null, -1, -1, null);
432: }
433: }
|