日志结构

commons和slf4j是日志规范;其他的是日志的具体实现

071507136869713.jpg

日志使用

  1. //001 声明使用 外观接口
  2. private static final Logger LOGGER = LoggerFactory.getLogger(DeployRecordController.class);

具体分析

//002 获得类名
public static Logger getLogger(Class clazz) {
  return getLogger(clazz.getName());
}

public static Logger getLogger(String name) {
    //003 获得logger工厂
  ILoggerFactory iLoggerFactory = getILoggerFactory();  
  //034 通过类名返回logger对象
  return iLoggerFactory.getLogger(name);
}
  public static ILoggerFactory getILoggerFactory() {
    //004 判断是否进行初始化
    if (INITIALIZATION_STATE == UNINITIALIZED) {
      INITIALIZATION_STATE = ONGOING_INITIALIZATION;
      //005 初始化
      performInitialization();
    }
    //033 错误处理
    switch (INITIALIZATION_STATE) {
      case SUCCESSFUL_INITIALIZATION:
        return StaticLoggerBinder.getSingleton().getLoggerFactory();
      case NOP_FALLBACK_INITIALIZATION:
        return NOP_FALLBACK_FACTORY;
      case FAILED_INITIALIZATION:
        throw new IllegalStateException(UNSUCCESSFUL_INIT_MSG);
      case ONGOING_INITIALIZATION:
        // support re-entrant behavior.
        // See also http://bugzilla.slf4j.org/show_bug.cgi?id=106
        return TEMP_FACTORY;
    }
    throw new IllegalStateException("Unreachable code");
  }
private final static void performInitialization() {
    //006 
    bind();
    if (INITIALIZATION_STATE == SUCCESSFUL_INITIALIZATION) {
      //020 获取JDK的版本与Slf4j支持的版本进行比较,如果版本相同则通过,如果不相同,那么进行失败提示
      versionSanityCheck();
    }
}
private final static void bind() {

    try {
      //007 获得实现日志的加载路径
      Set staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();
      //014 查看路径是否合法
      reportMultipleBindingAmbiguity(staticLoggerBinderPathSet);
      //015 初始化StaticLoggerBinder对象
      StaticLoggerBinder.getSingleton();
      INITIALIZATION_STATE = SUCCESSFUL_INITIALIZATION;
      //016 寻找合适的实现方式使用
      reportActualBinding(staticLoggerBinderPathSet);
      emitSubstituteLoggerWarning();
    } catch (NoClassDefFoundError ncde) {
      //017 如果找不到指定的类,就会报错!
      String msg = ncde.getMessage();
      if (messageContainsOrgSlf4jImplStaticLoggerBinder(msg)) {
        INITIALIZATION_STATE = NOP_FALLBACK_INITIALIZATION;
        Util.report("Failed to load class \"org.slf4j.impl.StaticLoggerBinder\".");
        Util.report("Defaulting to no-operation (NOP) logger implementation");
        Util.report("See " + NO_STATICLOGGERBINDER_URL
                + " for further details.");
      } else {
        failedBinding(ncde);
        throw ncde;
      }
    } catch (java.lang.NoSuchMethodError nsme) {
      //018 如果找不到指定的类,就会报错!
      String msg = nsme.getMessage();
      if (msg != null && msg.indexOf("org.slf4j.impl.StaticLoggerBinder.getSingleton()") != -1) {
        INITIALIZATION_STATE = FAILED_INITIALIZATION;
        Util.report("slf4j-api 1.6.x (or later) is incompatible with this binding.");
        Util.report("Your binding is version 1.5.5 or earlier.");
        Util.report("Upgrade your binding to version 1.6.x.");
      }
      throw nsme;
    } catch (Exception e) {
      //019 报错!
      failedBinding(e);
      throw new IllegalStateException("Unexpected initialization failure", e);
    }
 private static Set findPossibleStaticLoggerBinderPathSet() {
    //008 创建一个Set,因为有可能有多个实现。
    Set staticLoggerBinderPathSet = new LinkedHashSet();
    try {
      //009 获取LoggerFactory的类加载器!
      ClassLoader loggerFactoryClassLoader = LoggerFactory.class.getClassLoader();
      Enumeration paths;
      //010 如果获取不到类加载器则说明是系统加载器,那么在系统路径下获取该资源文件
      if (loggerFactoryClassLoader == null) {
        paths = ClassLoader.getSystemResources(STATIC_LOGGER_BINDER_PATH);
      } else {
        //011 获取到了类加载器,则用该类加载器加载指定的资源文件。
        paths = loggerFactoryClassLoader.getResources(STATIC_LOGGER_BINDER_PATH);
      }
      //012 解析类加载器的地址。
      while (paths.hasMoreElements()) {
        URL path = (URL) paths.nextElement();
        staticLoggerBinderPathSet.add(path);
      }
    } catch (IOException ioe) {
      Util.report("Error getting resources from path", ioe);
    }
   //013 返回加载器地址的集合
    return staticLoggerBinderPathSet;
  }
//021 对比jdk和slfj4的版本
private final static void versionSanityCheck() {
    try {
      String requested = StaticLoggerBinder.REQUESTED_API_VERSION;

      boolean match = false;
      for (int i = 0; i < API_COMPATIBILITY_LIST.length; i++) {
        if (requested.startsWith(API_COMPATIBILITY_LIST[i])) {
          match = true;
        }
      }
      if (!match) {
        Util.report("The requested version " + requested
                + " by your slf4j binding is not compatible with "
                + Arrays.asList(API_COMPATIBILITY_LIST).toString());
        Util.report("See " + VERSION_MISMATCH + " for further details.");
      }
    } catch (java.lang.NoSuchFieldError nsfe) {
      // given our large user base and SLF4J's commitment to backward
      // compatibility, we cannot cry here. Only for implementations
      // which willingly declare a REQUESTED_API_VERSION field do we
      // emit compatibility warnings.
    } catch (Throwable e) {
      // we should never reach here
      Util.report("Unexpected problem occured during version sanity check", e);
    }
  }