package fr.inria.diversify.util; /** * User: Simon * Date: 9/4/13 * Time: 2:40 PM */ import java.io.PrintStream; import java.io.PrintWriter; import java.io.StringWriter; import java.util.Date; public class Log { private static boolean GET_CALLER_CLASS_SUN_AVAILABLE = false; private static boolean printCaller = false; static public void setPrintCaller(Boolean addCaller) { if (addCaller) { try { sun.reflect.Reflection.getCallerClass(2); GET_CALLER_CLASS_SUN_AVAILABLE = addCaller; printCaller = addCaller; } catch (NoClassDefFoundError e) { } catch (NoSuchMethodError e) { } catch (Throwable e) { System.err.println("Unexpected exception while initializing Sun Caller"); e.printStackTrace(); } } else { printCaller = false; GET_CALLER_CLASS_SUN_AVAILABLE = false; } } /** * No logging at all. */ static public final int LEVEL_NONE = 6; /** * Critical errors. The application may no longer work correctly. */ static public final int LEVEL_ERROR = 5; /** * Important warnings. The application will continue to work correctly. */ static public final int LEVEL_WARN = 4; /** * Informative messages. Typically used for deployment. */ static public final int LEVEL_INFO = 3; /** * Debug messages. This level is useful during development. */ static public final int LEVEL_DEBUG = 2; /** * Trace messages. A lot of information is logged, so this level is usually only needed when debugging a problem. */ static public final int LEVEL_TRACE = 1; /** * The level of messages that will be logged. Compiling this and the booleans below as "final" will cause the compiler to * remove all "if (Log.info) ..." type statements below the set level. */ static private int level = LEVEL_INFO; /** * True when the ERROR level will be logged. */ static public boolean ERROR = level <= LEVEL_ERROR; /** * True when the WARN level will be logged. */ static public boolean WARN = level <= LEVEL_WARN; /** * True when the INFO level will be logged. */ static public boolean INFO = level <= LEVEL_INFO; /** * True when the DEBUG level will be logged. */ static public boolean DEBUG = level <= LEVEL_DEBUG; /** * True when the TRACE level will be logged. */ static public boolean TRACE = level <= LEVEL_TRACE; /** * Sets the level to log. If a version of this class is being used that has a final log level, this has no affect. */ static public void set(int level) { // Comment out method contents when compiling fixed level JARs. Log.level = level; ERROR = level <= LEVEL_ERROR; WARN = level <= LEVEL_WARN; INFO = level <= LEVEL_INFO; DEBUG = level <= LEVEL_DEBUG; TRACE = level <= LEVEL_TRACE; } static public void NONE() { set(LEVEL_NONE); } static public void ERROR() { set(LEVEL_ERROR); } static public void WARN() { set(LEVEL_WARN); } static public void INFO() { set(LEVEL_INFO); } static public void DEBUG() { set(LEVEL_DEBUG); } static public void TRACE() { set(LEVEL_TRACE); } /** * Sets the logger that will write the log messages. */ static public void setLogger(Logger logger) { Log.logger = logger; } private Log() { } private Log(Logger plogger) { logger = plogger; } static public Log getLog(String category) { Logger newLogger = new Logger(); newLogger.setCategory(category); return new Log(newLogger); } static private Logger logger = new Logger(); private static final char beginParam = '{'; private static final char endParam = '}'; private static String processMessage(String message, Object p1, Object p2, Object p3, Object p4, Object p5) { if (p1 == null) { return message; } StringBuilder buffer = null; boolean previousCharfound = false; int param = 0; for (int i = 0; i < message.length(); i++) { char currentChar = message.charAt(i); if (previousCharfound) { if (currentChar == endParam) { param++; switch (param) { case 1: { buffer = new StringBuilder(); buffer.append(message.substring(0, i - 1)); buffer.append(p1); } break; case 2: { buffer.append(p2); } break; case 3: { buffer.append(p3); } break; case 4: { buffer.append(p4); } break; case 5: { buffer.append(p5); } break; } previousCharfound = false; } else { if (buffer != null) { message.charAt(i - 1); buffer.append(currentChar); } previousCharfound = false; } } else { if (currentChar == beginParam) { previousCharfound = true; //next round } else { if (buffer != null) { buffer.append(currentChar); } } } } if (buffer != null) { return buffer.toString(); } else { return message; } } static public void error(String message) { if (ERROR) logger.log(LEVEL_ERROR, message, null); } static public void error(String message, Throwable ex) { if (ERROR) logger.log(LEVEL_ERROR, message, ex); } static public void error(String message, Throwable ex, Object p1) { if (ERROR) { error(processMessage(message, p1, null, null, null, null), ex); } } static public void error(String message, Throwable ex, Object p1, Object p2) { if (ERROR) { error(processMessage(message, p1, p2, null, null, null), ex); } } static public void error(String message, Throwable ex, Object p1, Object p2, Object p3) { if (ERROR) { error(processMessage(message, p1, p2, p3, null, null), ex); } } static public void error(String message, Throwable ex, Object p1, Object p2, Object p3, Object p4) { if (ERROR) { error(processMessage(message, p1, p2, p3, p4, null), ex); } } static public void error(String message, Throwable ex, Object p1, Object p2, Object p3, Object p4, Object p5) { if (ERROR) { error(processMessage(message, p1, p2, p3, p4, p5), ex); } } static public void error(String message, Object p1) { if (ERROR) { error(processMessage(message, p1, null, null, null, null), null); } } static public void error(String message, Object p1, Object p2) { if (ERROR) { error(processMessage(message, p1, p2, null, null, null), null); } } static public void error(String message, Object p1, Object p2, Object p3) { if (ERROR) { error(processMessage(message, p1, p2, p3, null, null), null); } } static public void error(String message, Object p1, Object p2, Object p3, Object p4) { if (ERROR) { error(processMessage(message, p1, p2, p3, p4, null), null); } } static public void error(String message, Object p1, Object p2, Object p3, Object p4, Object p5) { if (ERROR) { error(processMessage(message, p1, p2, p3, p4, p5), null); } } /* WARN */ static public void warn(String message, Throwable ex) { if (WARN) logger.log(LEVEL_WARN, message, ex); } static public void warn(String message) { if (WARN) logger.log(LEVEL_WARN, message, null); } static public void warn(String message, Throwable ex, Object p1) { if (WARN) { warn(processMessage(message, p1, null, null, null, null), ex); } } static public void warn(String message, Throwable ex, Object p1, Object p2) { if (WARN) { warn(processMessage(message, p1, p2, null, null, null), ex); } } static public void warn(String message, Throwable ex, Object p1, Object p2, Object p3) { if (WARN) { warn(processMessage(message, p1, p2, p3, null, null), ex); } } static public void warn(String message, Throwable ex, Object p1, Object p2, Object p3, Object p4) { if (WARN) { warn(processMessage(message, p1, p2, p3, p4, null), ex); } } static public void warn(String message, Throwable ex, Object p1, Object p2, Object p3, Object p4, Object p5) { if (WARN) { warn(processMessage(message, p1, p2, p3, p4, p5), ex); } } static public void warn(String message, Object p1) { if (WARN) { warn(processMessage(message, p1, null, null, null, null), null); } } static public void warn(String message, Object p1, Object p2) { if (WARN) { warn(processMessage(message, p1, p2, null, null, null), null); } } static public void warn(String message, Object p1, Object p2, Object p3) { if (WARN) { warn(processMessage(message, p1, p2, p3, null, null), null); } } static public void warn(String message, Object p1, Object p2, Object p3, Object p4) { if (WARN) { warn(processMessage(message, p1, p2, p3, p4, null), null); } } static public void warn(String message, Object p1, Object p2, Object p3, Object p4, Object p5) { if (WARN) { warn(processMessage(message, p1, p2, p3, p4, p5), null); } } /* INFO */ static public void info(String message, Throwable ex) { if (INFO) logger.log(LEVEL_INFO, message, ex); } static public void info(String message) { if (INFO) logger.log(LEVEL_INFO, message, null); } static public void info(String message, Throwable ex, Object p1) { if (INFO) { info(processMessage(message, p1, null, null, null, null), ex); } } static public void info(String message, Throwable ex, Object p1, Object p2) { if (INFO) { info(processMessage(message, p1, p2, null, null, null), ex); } } static public void info(String message, Throwable ex, Object p1, Object p2, Object p3) { if (INFO) { info(processMessage(message, p1, p2, p3, null, null), ex); } } static public void info(String message, Throwable ex, Object p1, Object p2, Object p3, Object p4) { if (INFO) { info(processMessage(message, p1, p2, p3, p4, null), ex); } } static public void info(String message, Throwable ex, Object p1, Object p2, Object p3, Object p4, Object p5) { if (INFO) { info(processMessage(message, p1, p2, p3, p4, p5), ex); } } static public void info(String message, Object p1) { if (INFO) { info(processMessage(message, p1, null, null, null, null), null); } } static public void info(String message, Object p1, Object p2) { if (INFO) { info(processMessage(message, p1, p2, null, null, null), null); } } static public void info(String message, Object p1, Object p2, Object p3) { if (INFO) { info(processMessage(message, p1, p2, p3, null, null), null); } } static public void info(String message, Object p1, Object p2, Object p3, Object p4) { if (INFO) { info(processMessage(message, p1, p2, p3, p4, null), null); } } static public void info(String message, Object p1, Object p2, Object p3, Object p4, Object p5) { if (INFO) { info(processMessage(message, p1, p2, p3, p4, p5), null); } } /* DEBUG */ static public void debug(String message, Throwable ex) { if (DEBUG) logger.log(LEVEL_DEBUG, message, ex); } static public void debug(String message) { if (DEBUG) logger.log(LEVEL_DEBUG, message, null); } static public void debug(String message, Throwable ex, Object p1) { if (DEBUG) { debug(processMessage(message, p1, null, null, null, null), ex); } } static public void debug(String message, Throwable ex, Object p1, Object p2) { if (DEBUG) { debug(processMessage(message, p1, p2, null, null, null), ex); } } static public void debug(String message, Throwable ex, Object p1, Object p2, Object p3) { if (DEBUG) { debug(processMessage(message, p1, p2, p3, null, null), ex); } } static public void debug(String message, Throwable ex, Object p1, Object p2, Object p3, Object p4) { if (DEBUG) { debug(processMessage(message, p1, p2, p3, p4, null), ex); } } static public void debug(String message, Throwable ex, Object p1, Object p2, Object p3, Object p4, Object p5) { if (DEBUG) { debug(processMessage(message, p1, p2, p3, p4, p5), ex); } } static public void debug(String message, Object p1) { if (DEBUG) { debug(processMessage(message, p1, null, null, null, null), null); } } static public void debug(String message, Object p1, Object p2) { if (DEBUG) { debug(processMessage(message, p1, p2, null, null, null), null); } } static public void debug(String message, Object p1, Object p2, Object p3) { if (DEBUG) { debug(processMessage(message, p1, p2, p3, null, null), null); } } static public void debug(String message, Object p1, Object p2, Object p3, Object p4) { if (DEBUG) { debug(processMessage(message, p1, p2, p3, p4, null), null); } } static public void debug(String message, Object p1, Object p2, Object p3, Object p4, Object p5) { if (DEBUG) { debug(processMessage(message, p1, p2, p3, p4, p5), null); } } static public void trace(String message, Throwable ex) { if (TRACE) logger.log(LEVEL_TRACE, message, ex); } static public void trace(String message) { if (TRACE) logger.log(LEVEL_TRACE, message, null); } static public void trace(String message, Throwable ex, Object p1) { if (TRACE) { trace(processMessage(message, p1, null, null, null, null), ex); } } static public void trace(String message, Throwable ex, Object p1, Object p2) { if (TRACE) { trace(processMessage(message, p1, p2, null, null, null), ex); } } static public void trace(String message, Throwable ex, Object p1, Object p2, Object p3) { if (TRACE) { trace(processMessage(message, p1, p2, p3, null, null), ex); } } static public void trace(String message, Throwable ex, Object p1, Object p2, Object p3, Object p4) { if (TRACE) { trace(processMessage(message, p1, p2, p3, p4, null), ex); } } static public void trace(String message, Throwable ex, Object p1, Object p2, Object p3, Object p4, Object p5) { if (TRACE) { trace(processMessage(message, p1, p2, p3, p4, p5), ex); } } static public void trace(String message, Object p1) { if (TRACE) { trace(processMessage(message, p1, null, null, null, null), null); } } static public void trace(String message, Object p1, Object p2) { if (TRACE) { trace(processMessage(message, p1, p2, null, null, null), null); } } static public void trace(String message, Object p1, Object p2, Object p3) { if (TRACE) { trace(processMessage(message, p1, p2, p3, null, null), null); } } static public void trace(String message, Object p1, Object p2, Object p3, Object p4) { if (TRACE) { trace(processMessage(message, p1, p2, p3, p4, null), null); } } static public void trace(String message, Object p1, Object p2, Object p3, Object p4, Object p5) { if (TRACE) { trace(processMessage(message, p1, p2, p3, p4, p5), null); } } /** * Performs the actual logging. Default implementation logs to System.out. Extended and use {@link Log#logger} set to handle * logging differently. */ static public class Logger { private long firstLogTime = new Date().getTime(); private static final String error_msg = " ERROR: "; private static final String warn_msg = " WARN: "; private static final String info_msg = " INFO: "; private static final String debug_msg = " DEBUG: "; private static final String trace_msg = " TRACE: "; private String category = null; public void setCategory(String category) { this.category = category; } public void log(int level, String message, Throwable ex) { StringBuilder builder = new StringBuilder(256); long time = new Date().getTime() - firstLogTime; long minutes = time / (1000 * 60); long seconds = time / (1000) % 60; if (minutes <= 9) builder.append('0'); builder.append(minutes); builder.append(':'); if (seconds <= 9) builder.append('0'); builder.append(seconds); switch (level) { case LEVEL_ERROR: builder.append(error_msg); break; case LEVEL_WARN: builder.append(warn_msg); break; case LEVEL_INFO: builder.append(info_msg); break; case LEVEL_DEBUG: builder.append(debug_msg); break; case LEVEL_TRACE: builder.append(trace_msg); break; } if (printCaller && GET_CALLER_CLASS_SUN_AVAILABLE) { String callerName = sun.reflect.Reflection.getCallerClass(3).getName(); builder.append(callerName); builder.append(':'); builder.append(' '); } if (category != null) { builder.append('['); builder.append(category); builder.append("] "); } builder.append(message); if (ex != null) { StringWriter writer = new StringWriter(256); ex.printStackTrace(new PrintWriter(writer)); builder.append('\n'); builder.append(writer.toString().trim()); } print(builder.toString()); } /** * Prints the message to System.out. Called by the default implementation of {@link #log(int, String, Throwable)}. */ protected void print(String message) { System.out.println(message); } } }