code: private LogInfo makeInfo(Object obj, Object... args) {
          if (obj == null)
              return LOGINFO_NULL;
          try {
              LogInfo info = new LogInfo();
              if (obj instanceof Throwable) {
                  info.e = (Throwable) obj;
                  info.message = info.e.getMessage();
              } else if (args == null || args.length == 0) {
                  info.message = obj.toString();
              }
              // //map to another mehtod
              // else if (args.length == 1 && args[0] instanceof Throwable) {
              // info.message = obj.toString();
              // info.e = (Throwable)args[0];
              // }
              else {
                  info.message = String.format(obj.toString(), args);
                  if (args[args.length - 1] instanceof Throwable)
                      info.e = (Throwable) args[args.length - 1];
              }
              return info;
          }
          catch (Throwable e) { // 即使格式错误也继续log
              if (isWarnEnabled())
                  warn("String format fail in log , fmt = "
                       + obj
                       + " , args = "
                       + Arrays.toString(args),
                       e);
              return LOGINFO_ERROR;
          }
      }
docs: 产生一个LogInfo对象,以支持以下调用方式:
  <p/>
  <code>log.warn(e)</code>
  <p/>
  <code>log.warnf("User(name=%s) login fail",username,e)</code>