LogUtil工具类

记录: 一个实用的log4jUtil类:

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * <pre>
 * File name : LogUtil.java
 * Created on : 2007-11-2 10:10:01
 * Description : 日志工具类
 * @author Jonathan Wong
 * </pre>
 */
public class LogUtil {

  public static final String LOG4J_PROPERTIES = "log4j.properties";

  public static final String LOG_FOLDER = "log"; //日志目录,系统启动时自动创建

  public static final String ERROR_LOG = "error.log";

  private static Log log;

  private static ThreadLocal<Object> threadFlag = new ThreadLocal<Object>();

  static {
    init();
  }

  /**
   * 初始化
   */
  private static void init() {
    try {
      createLogFolder();
      redirectSystemErrInfo();
      info("LogUtil initialized!");
    }
    catch(Throwable t) {
      warn("System error info redirect failed!");
    }
  }

  /*
   * 创建日志文件目录
   */
  private static void createLogFolder() {
    File logFolder = new File(LOG_FOLDER);
    boolean isLogFolderCreated = logFolder.mkdir();
    if(isLogFolderCreated)
      info(LOG_FOLDER + " folder created! " + logFolder.getAbsolutePath());
  }

  /*
   * 将系统错误信息重定向到文件
   * 这里文件主要记录的是运行时非预期的异常。
   */
  private static void redirectSystemErrInfo() throws Throwable {
    Properties properties = new Properties();
    properties.load(LogUtil.class.getClassLoader().getResourceAsStream(LOG4J_PROPERTIES));
    String errLogFileName = properties.getProperty(ERROR_LOG);
    PrintStream oldErrPS = System.err;
    PrintStream errPS = createNewErrPS(errLogFileName, oldErrPS);
    System.setErr(errPS);
    info("Redirect SystemErrInfo successfully!");
  }

  private static PrintStream createNewErrPS(String errLogFileName, final PrintStream oldErrPS) throws Throwable {
    return new PrintStream(new FileOutputStream(errLogFileName)) {
      @Override
      public void println(String x) {
        super.println(x);
        oldErrPS.println(x);
      }

      @Override
      public void println(Object x) {
        super.println(x);
        oldErrPS.println(x);
      }
    };
  }

  /*
   * 取得日志实例
   * @return
   */
  private synchronized static Log getLog() {
    if(log == null)
      log = LogFactory.getLog(LogUtil.class);
    return log;
  }

  /**
   * 严重错误(1/6)
   * 非常严重的错误,导致系统中止。
   * @param msg
   */
  public static void fatal(Object msg) {
    getLog().fatal(constructMsg(msg));
  }

  /**
   * 非预期的运行时错误(2/6)
   * 其它运行期错误或不是预期的条件。
   * @param msg
   */
  public static void error(Object msg) {
    getLog().error(constructMsg(msg));
  }

  /**
   * 警告(3/6)
   * 使用了不赞成使用的API、非常拙劣使用API, '几乎就是'错误, 其它运行时不合需要和不合预期的状态但还没必要称为 "错误"。
   * @param msg
   */
  public static void warn(Object msg) {
    getLog().warn(constructMsg(msg));
  }

  /**
   * 一般信息(4/6)
   * 运行时产生的有意义的事件。
   * @param msg
   */
  public static void info(Object msg) {
    getLog().info(constructMsg(msg));
  }

  /**
   * 调试信息(5/6)
   * 系统流程中的细节信息,一般正常运行时不被打印。
   * @param msg
   */
  public static void debug(Object msg) {
    getLog().debug(constructMsg(msg));
  }

  /**
   * 更细节的调试信息(6/6)
   * 比debug更加细节的信息,一般正常运行时不被打印。
   * @param msg
   */
  public static void trace(Object msg) {
    getLog().trace(constructMsg(msg));
  }

  /**
   * 一般捕获的异常信息
   * 所有捕获到的异常务必调用此方法处理,无需 e.printStackTrace() 。
   * @param e
   */
  public static void exception(Exception e) {
    exception(e.getMessage(), e);
  }

  public static void exception(Object msg, Exception e) {
    getLog().info(constructExceptionMsg(msg), e);
  }

  /*
   * 构造异常日志信息
   */
  private static String constructExceptionMsg(Object msg) {
    return constructMsg("Exception:" + String.valueOf(msg));
  }

  /*
   * 构造完整的日志信息
   */
  private static String constructMsg(Object msg) {
    StringBuffer cMsg = new StringBuffer();
    //1.DEBUG 模式下的附加信息
    constructMsgForDebug(cMsg);
    //2.添置FLAG标记下的附加信息
    constructMsgForFlag(cMsg);
    //3.主体信息
    cMsg.append(msg);
    return cMsg.toString();
  }

  @SuppressWarnings("unchecked")
  private static void constructMsgForDebug(StringBuffer cMsg) {
    if(getLog().isDebugEnabled()) {
      try {
        Class locationInfoCls = Class.forName("org.apache.log4j.spi.LocationInfo");
        Object locationInfo = locationInfoCls.getConstructor(Throwable.class, String.class).newInstance(new Throwable(), LogUtil.class.getName());
        cMsg.append("[");
        cMsg.append(locationInfoCls.getMethod("getClassName", (Class [])null).invoke(locationInfo, (Object [])null));
        cMsg.append(":");
        cMsg.append(locationInfoCls.getMethod("getLineNumber", (Class [])null).invoke(locationInfo, (Object [])null));
        cMsg.append("] ");
      }
      catch(Exception e) {
        warn("Could not log with line number and class name, maybe org.apache.log4j.spi.LocationInfo not found!");
        exception(e);
      }
    }
  }

  private static void constructMsgForFlag(StringBuffer cMsg) {
    Object flag = threadFlag.get();
    if(flag != null) {
      cMsg.append("( ");
      cMsg.append(flag);
      cMsg.append(" ) ");
    }
  }

  /**
   * 释放当前线程日志标记
   */
  public static void releaseFlag() {
    threadFlag.remove();
  }

  /**
   * 给当前线程日志创建一个标记
   * @param flag
   */
  public static void setFlag(Object flag) {
    threadFlag.set(flag);
  }
  
  public static boolean isDebugEnabled() {
    return getLog().isDebugEnabled();
  }
  
  public static boolean isTraceEnabled() {
    return getLog().isTraceEnabled();
  }
  
  public static Log getLog(Class clazz) throws Exception {
    return LogFactory.getLog(clazz);
  }

  public static Log getLog(String name) throws Exception {
    return LogFactory.getLog(name);
  }  
}

 

 

你可能感兴趣的:(util)