package es.upm.dit.gsi.logger; import java.io.*; import java.util.HashMap; import java.util.Map; import java.util.Properties; public class Logger { /** * Nivel máximo de traza: no se traza nada. */ public static final int OFF = Integer.MAX_VALUE; /** * Nivel de traza: WARNING < SEVERE < OFF. */ public static final int SEVERE = 1000; /** * Nivel de traza: INFO < WARNING < SEVERE. */ public static final int WARNING = 900; /** * Nivel de traza: CONFIG < INFO < WARNING. */ public static final int INFO = 800; /** * Nivel de traza: FINE < CONFIG < INFO. */ public static final int CONFIG = 700; /** * Nivel de traza: FINER < FINE < CONFIG. */ public static final int FINE = 500; /** * Nivel de traza: FINEST < FINER < FINE. */ public static final int FINER = 400; /** * Nivel de traza: ALL < FINEST < FINER. */ public static final int FINEST = 300; /** * Nivel mínimo de traza: se traza todo. */ public static final int ALL = Integer.MIN_VALUE; private static final Map<String, Logger> loggers = new HashMap<String, Logger>(); private static final Properties properties = new Properties(); private static int default_console_level = INFO; private static PrintStream console = System.err; private String name; private int console_level; private static int getLevel(String code, int def) { if (code == null) { return def; } code = code.trim(); // noinspection EmptyCatchBlock try { return Integer.parseInt(code); } catch (Exception e) { } if (code.equalsIgnoreCase("OFF")) { return OFF; } if (code.equalsIgnoreCase("SEVERE")) { return SEVERE; } if (code.equalsIgnoreCase("WARNING")) { return WARNING; } if (code.equalsIgnoreCase("INFO")) { return INFO; } if (code.equalsIgnoreCase("CONFIG")) { return CONFIG; } if (code.equalsIgnoreCase("FINE")) { return FINE; } if (code.equalsIgnoreCase("FINER")) { return FINER; } if (code.equalsIgnoreCase("FINEST")) { return FINEST; } if (code.equalsIgnoreCase("ALL")) { return ALL; } return INFO; } private static String getLevelString(int level) { if (level >= SEVERE) { return " [severe]: "; } if (level >= WARNING) { return " [warning]: "; } if (level >= INFO) { return " [info]: "; } if (level >= CONFIG) { return " [config]: "; } if (level >= FINE) { return " [fine]: "; } if (level >= FINER) { return " [finer]: "; } if (level >= FINEST) { return " [finest]: "; } return " []: "; } private int getMyLevel(String name) { String p = properties.getProperty(name); if (p != null) { return getLevel(p, INFO); } p = properties.getProperty(name + ".level"); if (p != null) { return getLevel(p, INFO); } int dot = name.lastIndexOf('.'); while (dot > 0) { name = name.substring(0, dot); p = properties.getProperty(name); if (p != null) { return getLevel(p, INFO); } p = properties.getProperty(name + ".level"); if (p != null) { return getLevel(p, INFO); } dot = name.lastIndexOf('.'); } return ALL; } /** * Crea un logger. * Se trata de que para cada nombre el logger sea único. * * @param name Nombre del logger. * @return un objeto Logger */ public static Logger getLogger(String name) { if (name == null || name.length() == 0) { name = "default"; } Logger logger = loggers.get(name); if (logger == null) { logger = new Logger(name); loggers.put(name, logger); } return logger; } private Logger(String name) { this.name = name; int myLevel = getMyLevel(name); console_level = Math.max(myLevel, default_console_level); } /** * Marca un nivel de aceptación de trazas. * Se imprimen por consola las trazas de nivel * mayor o igual que el marcado. * * @param level Nivel de traza. */ public void acceptConsoleLevel(int level) { console_level = Math.min(console_level, level); } /** * Traza a nivel SEVERE. * * @param msg Mensaje de la traza. */ public final void severe(String msg) { log(SEVERE, msg); } /** * Traza a nivel SEVERE. * * @param msg1 Mensaje de la traza (parte 1). * @param msg2 Mensaje de la traza (parte 2). */ public final void severe(String msg1, String msg2) { log(SEVERE, msg1, msg2); } /** * Traza a nivel WARNING. * * @param msg Mensaje de la traza. */ public final void warning(String msg) { log(WARNING, msg); } /** * Traza a nivel WARNING. * * @param msg1 Mensaje de la traza (parte 1). * @param msg2 Mensaje de la traza (parte 2). */ public final void warning(String msg1, String msg2) { log(WARNING, msg1, msg2); } /** * Traza a nivel INFO. * * @param msg Mensaje de la traza. */ public final void info(String msg) { log(INFO, msg); } /** * Traza a nivel INFO. * * @param msg1 Mensaje de la traza (parte 1). * @param msg2 Mensaje de la traza (parte 2). */ public final void info(String msg1, String msg2) { log(INFO, msg1, msg2); } /** * Traza a nivel CONFIG. * * @param msg Mensaje de la traza. */ public final void config(String msg) { log(CONFIG, msg); } /** * Traza a nivel CONFIG. * * @param msg1 Mensaje de la traza (parte 1). * @param msg2 Mensaje de la traza (parte 2). */ public final void config(String msg1, String msg2) { log(CONFIG, msg1, msg2); } /** * Traza a nivel FINE. * * @param msg Mensaje de la traza. */ public final void fine(String msg) { log(FINE, msg); } /** * Traza a nivel FINE. * * @param msg1 Mensaje de la traza (parte 1). * @param msg2 Mensaje de la traza (parte 2). */ public final void fine(String msg1, String msg2) { log(FINE, msg1, msg2); } /** * Traza a nivel FINER. * * @param msg Mensaje de la traza. */ public final void finer(String msg) { log(FINER, msg); } /** * Traza a nivel FINER. * * @param msg1 Mensaje de la traza (parte 1). * @param msg2 Mensaje de la traza (parte 2). */ public final void finer(String msg1, String msg2) { log(FINER, msg1, msg2); } /** * Traza a nivel FINEST. * * @param msg Mensaje de la traza. */ public final void finest(String msg) { log(FINEST, msg); } /** * Traza a nivel FINEST. * * @param msg1 Mensaje de la traza (parte 1). * @param msg2 Mensaje de la traza (parte 2). */ public final void finest(String msg1, String msg2) { log(FINEST, msg1, msg2); } /** * Chequeo de si una traza de un cierto nivel aparecería en consola. * * @param level Nivel por el que se pregunta. * @return TRUE si aparecería en consola. */ public final boolean inConsole(int level) { return level >= console_level; } /** * Genera una traza del nivel indicado. * * @param level Nivel de la traza. */ public final void log(int level) { if (level >= console_level) { console.println(name); } } /** * Genera una traza del nivel indicado. * * @param level Nivel de la traza. * @param msg Mensaje de la traza. */ public final void log(int level, String msg) { if (level >= console_level) { console.print(name); console.print(getLevelString(level)); console.println(msg); } } /** * Genera una traza del nivel indicado. * * @param level Nivel de la traza. * @param msg1 Mensaje de la traza (parte 1). * @param msg2 Mensaje de la traza (parte 2). */ public final void log(int level, String msg1, String msg2) { if (level >= console_level) { console.print(name); console.print(getLevelString(level)); console.print(msg1); console.print(' '); console.println(msg2); } } /** * Genera una traza del nivel indicado. * * @param level Nivel de la traza. * @param msg Mensaje de la traza. * @param throwable Excepción que se quiere trazar. */ public final void log(int level, String msg, Throwable throwable) { if (level >= console_level) { console.print(name); console.print(getLevelString(level)); console.println(msg); throwable.printStackTrace(console); } } }