/* * Copyright (c) 2008-2010 by Bjoern Kolbeck, * Zuse Institute Berlin * * Licensed under the BSD License, see LICENSE file for details. * */ package de.mxro.thrd.xstreemfs.foundation.logging; import java.io.PrintStream; import java.text.SimpleDateFormat; import java.util.Date; /** * * @author bjko */ public class Logging { public enum Category { /** * enable logging for all categories (no real category) */ all, /** * logs messages pertaining to buffers */ buffer, /** * log messaages pertaining to service lifecycles (threads) */ lifecycle, /** * network-related log messages */ net, /** * authorization-related log messages */ auth, /** * log messages pertaining to the request flow through the stages */ stage, /** * log messages pertaining to any kind of request processing */ proc, /** * */ misc, /** * log messages pertaining storage on OSD or database access on MRC/DIR */ storage, /** * logs messages pertaining to replication */ replication, /** * logs messages from additional tools */ tool, /** * logs messages from tests */ test } protected static final char ABBREV_LEVEL_INFO = 'I'; protected static final char ABBREV_LEVEL_DEBUG = 'D'; protected static final char ABBREV_LEVEL_WARN = 'W'; protected static final char ABBREV_LEVEL_ERROR = 'E'; protected static final char ABBREV_LEVEL_TRACE = 'T'; public static final int LEVEL_EMERG = 0; public static final int LEVEL_ALERT = 1; public static final int LEVEL_CRIT = 2; public static final int LEVEL_ERROR = 3; public static final int LEVEL_WARN = 4; public static final int LEVEL_NOTICE = 5; public static final int LEVEL_INFO = 6; public static final int LEVEL_DEBUG = 7; public static final String FORMAT_PATTERN = "[ %c | %-20s | %-15s | %3d | %15s ] %s"; private static PrintStream out = System.out; protected static Logging instance; protected static boolean tracingEnabled = false; private final int level; private final int catMask; private static final SimpleDateFormat dateFormat = new SimpleDateFormat("MMM dd HH:mm:ss"); /** * Creates a new instance of Logging */ private Logging(int level, int catMask) { if (level < 0) this.level = 0; else this.level = level; this.catMask = catMask; instance = this; System.currentTimeMillis(); } public static void redirect(PrintStream out) { Logging.out = out; } public static void logMessage(int level, Category cat, Object me, String formatPattern, Object... args) { // if the level is appropriate as well as the category, or the category // is 'all', log the message if (level <= instance.level && (cat == Category.all || (2 << cat.ordinal() & instance.catMask) > 0)) { char levelName = getLevelName(level); out.println(String.format(FORMAT_PATTERN, levelName, me == null ? "-" : me.getClass() .getSimpleName(), Thread.currentThread().getName(), Thread.currentThread().getId(), getTimeStamp(), String.format(formatPattern, args))); } } public static void logMessage(int level, Object me, String formatPattern, Object... args) { logMessage(level, Category.all, me, formatPattern, args); } public static void logError(int level, Object me, Throwable msg) { // if the level is appropriate, log the message if (level <= instance.level) { char levelName = getLevelName(level); out.println(String.format(FORMAT_PATTERN, levelName, me == null ? "-" : me.getClass() .getSimpleName(), Thread.currentThread().getName(), Thread.currentThread().getId(), getTimeStamp(), msg.toString())); for (StackTraceElement elem : msg.getStackTrace()) { out.println(" ... " + elem.toString()); } if (msg.getCause() != null) { out.println(String.format(FORMAT_PATTERN, levelName, me == null ? "-" : me.getClass() .getSimpleName(), Thread.currentThread().getName(), Thread.currentThread().getId(), getTimeStamp(), "root cause: " + msg.getCause())); for (StackTraceElement elem : msg.getCause().getStackTrace()) { out.println(" ... " + elem.toString()); } } } } public static void logUserError(int level, Category cat, Object me, Throwable msg) { // if the level is appropriate as well as the category, or the category // is 'all', log the message if (level <= instance.level && (cat == Category.all || (2 << cat.ordinal() & instance.catMask) > 0)) { char levelName = getLevelName(level); out.println(String.format(FORMAT_PATTERN, levelName, me == null ? "-" : me.getClass() .getSimpleName(), Thread.currentThread().getName(), Thread.currentThread().getId(), getTimeStamp(), msg.toString())); for (StackTraceElement elem : msg.getStackTrace()) { out.println(" ... " + elem.toString()); } } } public static char getLevelName(int level) { switch (level) { case LEVEL_EMERG: case LEVEL_ALERT: case LEVEL_CRIT: case LEVEL_ERROR: return ABBREV_LEVEL_ERROR; case LEVEL_WARN: return ABBREV_LEVEL_WARN; case LEVEL_NOTICE: case LEVEL_INFO: return ABBREV_LEVEL_INFO; case LEVEL_DEBUG: return ABBREV_LEVEL_DEBUG; default: return '?'; } } public synchronized static void start(int level, Category... categories) { if (instance == null) { int catMask = 0; for (Category cat : categories) { if (cat == Category.all) catMask = -1; catMask |= 2 << cat.ordinal(); } if(categories.length == 0) catMask = -1; instance = new Logging(level, catMask); } } public static boolean isDebug() { if (instance == null) return false; else return instance.level >= LEVEL_DEBUG; } public static boolean isInfo() { if (instance == null) return false; else return instance.level >= LEVEL_INFO; } public static boolean isNotice() { if (instance == null) return false; else return instance.level >= LEVEL_NOTICE; } private static String getTimeStamp() { return dateFormat.format(new Date()); } }