slf4j 和 log4j

Posted by Xsp on December 10, 2018

slf4j 提供了统一的接口规范,log4j是具体的实现。

slf4j相当于提供了一个中间层,它兼容多种日志框架,在应用中屏蔽掉底层日志框架的具体实现。这样,如果需要更换日志框架,应用层写的代码几乎不用修改。

【强制】应用中不可直接使用日志系统(Log4j、Logback)中的 API,而应依赖使用日志框架

SLF4J 中的 API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

private static final Logger logger = LoggerFactory.getLogger(Abc.class); 

–《阿里巴巴java开发手册》

log4j

log4j.rootLogger

log4j.rootLogger = level, appenderName, appenderName, ...

level是定义的输出级别,低于该级别的将不会输出,主要级别有OFF、ALL、FATAL、ERROR、WARN、INFO、DEBUG或自定义级别,其中OFF设定的话将不输出任何信息,ALL设定的话将输出所有信息;另外5个的级别FATAL>ERROR>WARN>INFO>DEBUG,如果你的lenel设定为INFO,那么不能输出DEBUG信息。

appenderName是指定日志信息输出到哪个地方,控制台,文件等等,可同时指定多个输出目的地。

log4j.appender

负责控制日志记录操作的输出

log4j.appender.appenderName=someAppender(选择一种输出平台)
log4j.appender.appenderName.File=文件名(文件输出定义路径)
log4j.appender.appenderName.layout=输出布局
log4j.appender.appenderName.layout.ConversionPattern=输出格式

log4j.appender.appenderName指定输出appender,Log4J提供了以下几种appender:

  1. org.apache.log4j.ConsoleAppender(控制台)
  2. org.apache.log4j.FileAppender(文件)
  3. org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件)
  4. org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)
    1. 可通过log4j.appender.R.MaxFileSize=100KB设置文件大小,还可通过log4j.appender.R.MaxBackupIndex=1设置为保存一个备份文件)
  5. org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)

log4j.appender.appenderName.layout指定日志信息的格式(布局)Layout,它负责格式化Appender的输出。Log4j提供的layout有以下几种:

  1. org.apache.log4j.HTMLLayout(以HTML表格形式布局)
  2. org.apache.log4j.PatternLayout(可以灵活地指定布局模式)
  3. org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串)
  4. org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)

log4j.appender.appenderName.layout.ConversionPattern格式化日志信息,Log4J采用类似C语言中的printf函数的打印格式格式化日志信息,打印参数如下:

%m 输出代码中指定的消息
%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
%r 输出自应用启动到输出该log信息耗费的毫秒数
%c 输出所属的类目,通常就是所在类的全名
%t 输出产生该日志事件的线程名
%n 输出一个回车换行符,Windows平台为“rn”,Unix平台为“n”
%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyyy MMM dd HH:mm:ss,SSS},输出类似:2012年06月24日 23:55:28,92
%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。

log4j.logger

不是必需的,如果不配置这个,则采用log4j.rootLogger的level级别。它主要是具体到package、Class级别的info,它的定义格式如下:

log4j.logger.packageName[.ClassName]=level[,appender]

它也可以输出到指定的appender,也可以不指定输出到默认appender。

LOG4J日志级别

Level 描述
ALL 各级包括自定义级别
DEBUG 指定细粒度信息事件是最有用的应用程序调试
ERROR 错误事件可能仍然允许应用程序继续运行
FATAL 指定非常严重的错误事件,这可能导致应用程序中止
INFO 指定能够突出在粗粒度级别的应用程序运行情况的信息的消息
OFF 这是最高等级,为了关闭日志记录
TRACE 指定细粒度比DEBUG更低的信息事件
WARN 指定具有潜在危害的情况

spring-boot 使用log4j

spring-boot 默认使用的是logback。感觉默认的logback输出的日志的颜色高亮可能更好看一点。

修改pom文件

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j</artifactId>
    <version>1.3.8.RELEASE</version>
</dependency>

在resources目录添加 log4j.properties 文件

# LOG4J配置
log4j.rootCategory=INFO,stdout,file
# 控制台输出
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n

# 日志输出到文件
log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
# 这里的目录表示项目文件夹根目录的 ./log/log4j.log 文件
log4j.appender.file.file=./log/log4j.log
log4j.appender.file.DatePattern='.'yyyy-MM-dd
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n

另外,如果想用 log4j2,可以参考官方的demo:https://github.com/spring-projects/spring-boot/blob/master/spring-boot-samples/spring-boot-sample-actuator-log4j2/pom.xml

log4j2 是用xml配置的。感觉比properties文件更繁琐一些。

maven 配置

可以直接在maven中添加配置

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.2</version>
</dependency>

log4j.properties 参考上面的spring-boot的配置。

代码中使用

private static final Logger logger = LoggerFactory.getLogger(Test.class);

logger.info("now {}" , "starting server");

log4j 加载时,默认是同步输出日志,当日志较多时,可能会有性能问题。

所以可以采用异步日志。异步和同步的主要区别在于,异步会设置一个缓冲区,当缓冲区写满会,才会刷新到文件,没有同步竞争的环节,效率更高。

异步配置需要用xml。

参考