请注意红色字体!

Java 日志 API

现在比较流行的java日志api包括 log4j /log4j2 及其后继者 logback。除了真正的日志记录实现之外,还有一类与日志记录相关的封装 API,如 Apache Commons Logging 和 SLF4J。这类库的作用是在日志记录实现的基础上提供一个封装的 API 层次,对日志记录 API 的使用者提供一个统一的接口,使得可以自由切换不同的日志记录实现。比如从 JDK 的默认日志记录实现 JUL 切换到 log4j。这类封装 API 库在框架的实现中比较常用,因为需要考虑到框架使用者的不同需求。

在通过日志记录器对象记录日志时,需要指定日志的严重性级别。根据每个记录器对象的不同配置,低于某个级别的日志消息可能不会被记录下来。该级别是日志 API 的使用者根据日志记录中所包含的信息来自行决定的。不同的日志记录 API 所定义的级别也不尽相同。日志记录封装 API 也会定义自己的级别并映射到底层实现中相对应的实际级别。比如 JDK 标准的日志 API 使用的级别包括 OFF、SEVERE、WARNING、INFO、CONFIG、FINE、FINER、FINEST 和 ALL 等,Log4j 使用的级别则包括 OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE 和 ALL 等。一般情况下,使用得比较多的级别是 FATAL、ERROR、WARN、INFO、DEBUG 和 TRACE 等。这 6 个级别所对应的情况也有所不同:

  • FATAL:导致程序提前结束的严重错误。
  • ERROR:运行时异常以及预期之外的错误。
  • WARN:预期之外的运行时状况,不一定是错误的情况。
  • INFO:运行时产生的事件。
  • DEBUG:与程序运行时的流程相关的详细信息。
  • TRACE:更加具体的详细信息。


注意!

在这 6 个级别中,FATAL、ERROR级别为运维严密监控的级别,请正确设置logger的级别,避免误报。

logger级别请已info为基准,可适当调低部分logger的级别至debug,避免大量无价值日志。



一般来说,日志 API 由下面几个部分组成:

  • 记录器(Logger):日志 API 的使用者通过记录器来发出日志记录请求,并提供日志的内容。在记录日志时,需要指定日志的严重性级别。
  • 格式化器(Formatter):对记录器所记录的文本进行格式化,并添加额外的元数据。
  • 处理器(Handler):把经过格式化之后的日志记录输出到不同的地方。常见的日志输出目标包括控制台、文件和数据库等。

记录器


SLF4J 库的使用方式与 Apache Commons Logging 库比较类似。SLF4J 库中核心的 API 是提供工厂方法的 org.slf4j.LoggerFactory 类和记录日志的 org.slf4j.Logger 接口。
通过 LoggerFactory 类的 getLogger 方法来获取日志记录器对象。与 Apache Commons Logging 库中的 Log 接口类似,Logger 接口中的方法也是按照不同的严重性级别来进行分组的。Logger 接口中有同样 isDebugEnabled 方法。
不过 Logger 接口中发出日志记录请求的 debug 等方法使用 String 类型来表示消息,同时可以使用包含参数的消息


示例

import org.slf4j.Logger;
 import org.slf4j.LoggerFactory; 
private static final Logger LOGGER = LoggerFactory.getLogger(Slf4jBasic.class); 
 public void logBasic() { if (LOGGER.isInfoEnabled()) { 

LOGGER.info("My log message for %s", "Alex");         }     }  }


格式化器


实际记录的日志中除了使用记录器对象时提供的消息之外,还包括一些元数据。这些元数据由日志记录框架来提供。常用的信息包括记录器的名称、时间戳、线程名等。格式化器用来确定所有这些信息在日志记录中的展示方式。不同的日志记录实现提供各自默认的格式化方式和自定义支持。


易联的格式统一如下:

%d [%t] %-5p [%c] - %m%n
logback为 :  %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level [%logger] - %msg%n

展示效果

2015-08-20 00:00:00,001 [pool-6-thread-1] DEBUG [com.snowstore.apollo.service.task.ScheduleService] - 后台Timer开始执行检查有效状态>的数字证书的有效时间



处理器 


 以log4j2为例子:Appender使用RollingFileAppender,采用时间策略备份日志。为方便运维采集日志,采用固定路径放置日志。


/home/logs/${appName}/${appName}.log

日志文件名:

其中appName为应用名


示例


<RollingFile name="RollingFile" fileName="/home/logs/apollo/apollo.log" filePattern=""/home/logs/apollo/apollo-%d{MM-dd-yyyy}.log.gz" ignoreExceptions="false">
       <PatternLayout>
            <Pattern>%d [%t] %-5p [%c] - %m%n</Pattern>
       </PatternLayout>
     <TimeBasedTriggeringPolicy />
 </RollingFile>




完整例子:


<?xml version="1.0" encoding="UTF-8"?>
 <Configuration monitorInterval="60">
  <Properties>
   <Property name="appName">logObserver</Property>
   <Property name="logPath">/home/logs/${appName}</Property>
  </Properties>
  <Appenders>
   <Console name="STDOUT" target="SYSTEM_OUT">
    <PatternLayout pattern="%d [%t] %-5p [%c] - %m%n" />
   </Console>
  
   <RollingFile name="RollingFile" fileName="${logPath}/${appName}.log"
    filePattern="${logPath}/${appName}-%d{MM-dd-yyyy}.log.gz"
    ignoreExceptions="false">
    <PatternLayout>
     <Pattern>%d [%t] %-5p [%c] - %m%n</Pattern>
    </PatternLayout>
    <TimeBasedTriggeringPolicy />
   </RollingFile> </Appenders>
  <Loggers>
   <Logger name="org.apache.log4j.xml" level="info" />
   <!-- project default level -->
   <logger name="com.snowstore.log" level="debug" />
   <logger name="org.springframework" level="info" />  <!--log4jdbc -->
   <logger name="jdbc.sqltiming" level="debug" />
   <logger name="jdbc.sqlonly" level="OFF" />
   <logger name="jdbc.audit" level="OFF" />
   <logger name="jdbc.resultset" level="OFF" />
   <logger name="jdbc.connection" level="OFF" />
   <logger name="jdbc.resultsettable" level="OFF" />
   <Root level="INFO">
    <AppenderRef ref="STDOUT" />
    <AppenderRef ref="RollingFile" />
   </Root>
  </Loggers>
 </Configuration>