/* * Log.java * * Created on April 18, 2002, 5:24 PM */ package org.ninjasoft.util; import org.apache.log4j.Logger; import org.apache.log4j.PropertyConfigurator; import org.apache.log4j.BasicConfigurator; import org.apache.log4j.Level; import java.io.PrintStream; import java.io.ByteArrayOutputStream; import org.apache.log4j.MDC; /** * Wrapper for log4j configuration and logging. Log4j will look for the * file log4j.properties in your classpath. */ public class Log { /** Whether the log4j system has been properly initialize */ private static boolean initialized = false; public static final String MDC_EXCEPTION = "exception"; /** Cannot instantiate */ private Log() {} /** Initialize the log4j system */ private static void initialize() { try{ // This will search for the log4j configutation file new PropertyConfigurator(); // Check that root logger has been configured, if not set a default config Logger root = Logger.getRootLogger(); if (!root.getAllAppenders().hasMoreElements()) { BasicConfigurator.configure(); root.setLevel(Level.INFO); root.info("log4j.properties not found, using default configuration"); root.setLevel(Level.ERROR); } }catch(VerifyError e){ System.err.println(); System.err.println("log4j not installed or too old. Be sure log4j 1.2 or greater is installed."); System.err.println("http://jakarta.apache.org/log4j/"); System.err.println(); throw e; } initialized = true; } /** * Log a debug message *@parm obj use this object's class name as the category name, or the literal name if a String object *@param message message to log */ public static void debug(Object obj, String message) { log(obj, Level.DEBUG, message); } /** * Log a debug message, with binary data * @param obj use this object's class name as the category name, or the literal name if a String object * @param message message to log * @param data binary data to log */ public static void debug(Object obj, String message, byte[] data) { log(obj, Level.DEBUG, message + "\n" + encode(data)); } /** * Log an error message *@parm obj use this object's class name as the category name, or the literal name if a String object *@param message message to log */ public static void error(Object obj, String message) { log(obj, Level.ERROR, message); } /** * Log an error message, with binary data * @param obj use this object's class name as the category name, or the literal name if a String object * @param message message to log * @param data binary data to log */ public static void error(Object obj, String message, byte[] data) { log(obj, Level.ERROR, message + "\n" + encode(data)); } /** * Log an info message *@parm obj use this object's class name as the category name, or the literal name if a String object *@param message message to log */ public static void info(Object obj, String message) { log(obj, Level.INFO, message); } /** * Log an info message, with binary data * @param obj use this object's class name as the category name, or the literal name if a String object * @param message message to log * @param data binary data to log */ public static void info(Object obj, String message, byte[] data) { log(obj, Level.INFO, message + "\n" + encode(data)); } /** * Log a warning message *@parm obj use this object's class name as the category name, or the literal name if a String object *@param message message to log */ public static void warn(Object obj, String message) { log(obj, Level.WARN, message); } /** * Log a warning message, with binary data * @param obj use this object's class name as the category name, or the literal name if a String object * @param message message to log * @param data binary data to log */ public static void warn(Object obj, String message, byte[] data) { log(obj, Level.WARN, message + "\n" + encode(data)); } /** * Log a fatal message *@parm obj use this object's class name as the category name, or the literal name if a String object *@param message message to log */ public static void fatal(Object obj, String message) { log(obj, Level.FATAL, message); } /** * Log a fatal message, with binary data * @param obj use this object's class name as the category name, or the literal name if a String object * @param message message to log * @param data binary data to log */ public static void fatal(Object obj, String message, byte[] data) { log(obj, Level.FATAL, message + "\n" + encode(data)); } /** * Log a debug message, tied to a Throwable object *@parm obj use this object's class name as the category name, or the literal name if a String object *@param message message to log */ public static void debug(Object obj, String message, Throwable throwable) { log(obj, Level.DEBUG, message, throwable); flagException (throwable ); } /** * Log an error message, tied to a Throwable object *@parm obj use this object's class name as the category name, or the literal name if a String object *@param message message to log */ public static void error(Object obj, String message, Throwable throwable) { log(obj, Level.ERROR, message, throwable); flagException (throwable ); } /** * Log an info message, tied to a Throwable object *@parm obj use this object's class name as the category name, or the literal name if a String object *@param message message to log */ public static void info(Object obj, String message, Throwable throwable) { log(obj, Level.INFO, message, throwable); flagException (throwable ); } /** * Log a warn message, tied to a Throwable object *@parm obj use this object's class name as the category name, or the literal name if a String object *@param message message to log */ public static void warn(Object obj, String message, Throwable throwable) { log(obj, Level.WARN, message, throwable); flagException (throwable ); } /** * Log a fatal message, tied to a Throwable object *@parm obj use this object's class name as the category name, or the literal name if a String object *@param message message to log */ public static void fatal(Object obj, String message, Throwable throwable) { log(obj, Level.FATAL, message, throwable); flagException (throwable ); } /** * Log a message in the log4j system *@param obj use this object's class name as the category name, of the literal name if a String *@param level log level to use *@param message the message to log *@param throwable the Throwable object to log with the message */ private static void log(Object obj, Level level, String message) { if (!initialized) initialize(); if (obj instanceof String) Logger.getLogger((String)obj).log(level, message); else Logger.getLogger(obj.getClass()).log(level, message); } /** * Log a message tied to a Throwable object in the log4j system *@param obj use this object's class name as the category name, of the literal name if a String *@param level log level to use *@param message the message to log *@param throwable the Throwable object to log with the message */ private static void log(Object obj, Level level, String message, Throwable throwable) { if (!initialized) initialize(); if (obj instanceof String) Logger.getLogger((String)obj).log(level, message, throwable); else Logger.getLogger(obj.getClass()).log(level, message, throwable); flagException (throwable ); } public static void main(String[] argv) { Log.error(new java.util.Hashtable(), "Logger test1"); Log.error(new java.util.Hashtable(), "Logger test2", new RuntimeException("My Exception1")); Log.error("com.certivo.test.of.logger", "Logger test3"); Log.error("com.certivo.test.of.logger", "Logger test4", new RuntimeException("My Exception2")); Log.debug("com.certivo.debug", "Logger test5, this may be ignored"); } /** * returns true if debug is enabled for this object * * @returns true/false */ public static boolean isDebugEnabled(Object obj){ Logger theLogger = null; if (obj instanceof String){ theLogger = Logger.getLogger((String)obj); } else{ theLogger = Logger.getLogger(obj.getClass()); } return theLogger.isDebugEnabled(); } public static void flagException ( Throwable t ) { // add throwable to MDC context if ( t != null ) { MDC.put(MDC_EXCEPTION,t); } } /** * Perform a basic HTTP URL-Encoded encoding. This allows us to escape the binary * characters, yet still be able to see any embedded ASCII characters. * @param b the binary block to encode * @return the encoded/escaped binary data as a string */ private static String encode(byte[] b) { StringBuffer result = new StringBuffer(); int pos = 1; boolean needsEncoding = false; // First, check if it even NEEDS encoding. If it consists of // strictly printable characters, we can just dump those // verbatim (and this will increase readibility in the // logs because the CRLF's are not going to be escaped). for (int i=0; i 0x7e)) && (binaryCharacter != 0x0a) && (binaryCharacter != 0x0d)) { needsEncoding = true; break; } result.append((char) binaryCharacter); } if (!needsEncoding) return "%TEXTBEGIN%\n" + result.toString() + "\n%TEXTEND%"; result = new StringBuffer(); // It looks like there are characters needing encoding. The encoding // is done below... for (int i=0; i= 0x20) && (binaryCharacter <= 0x7e) && (binaryCharacter != 0x25)) { result.append((char) binaryCharacter); pos++; }else{ result.append("%"); String hex = Integer.toString(binaryCharacter, 16); if (hex.length() == 1) hex = "0" + hex; result.append(hex); pos += 3; } if (pos >= 80) { result.append("\n"); pos = 1; } } return "%BINARYBEGIN%\n" + result.toString() + "\n%BINARYEND%"; } }