但行好事
莫论前程❤

Log4j和Slf4j的比较

一直搞不清 Log4j 和 SLF4j 的关系。今天才若有所得。

  Log4j 出现的较早,而 SLF4j 则只是提供了一组接口,同时SLF4j 可以有不同的实现。  在 Java 中,接口是一个很重要的概念。抽象层的,面向服务的概念。用面向接口的方法编程,是这样的:接口 + 实现类。  只要接口统一,就可以方便的替换不同的实现类。而无需改动所有的业务层代码。 

​ 奇怪的是 SLF4j  是如何统一每一种实现类都去实现它的接口呢?

​ SLF4j 把主流的日志库统一起来,然后对它们各自写了对应的中间类。  而这些中间类,只需要实现 SLF4j 提供的统一接口即可。  所以在 SLF4j  中,是这样的:SLF4j 接口 + 中间类 + 实现类

​ 中间类是用来连接 接口 和 实现类的。  有一张图可以看的清楚一些:用的哪个实现类,就需要那个实现类的中间类。

img

正因为 SLF4j 对主流的日志库都统一支持,所以它是主流日志库的“门面”。

​ 简单日记门面(simple logging Facade for java) SLF4J 实现了对各种 loging Lib 的支持,并提供一个简单统一的接口。从而使得最终用户在部署的时候,能够灵活配置自己的 loging APIs 实现。准确的说,slf4j并不是一种具体的日志系统,而是一个用户日志系统的 facade,允许用户在部署最终应用时方便的变更其日志系统。

​ 在系统开发中,统一按照slf4j的API进行开发,在部署时,选择不同的日志系统包,即可自动转换到不同的日志系统上。比如:选择JDK自带的日志系统,则只需要将slf4j-api-1.5.10.jar和slf4j-jdk14-1.5.10.jar放置到classpath中即可,如果中途无法忍受JDK自带的日志系统了,想换成log4j的日志系统,仅需要用slf4j-log4j12-1.5.10.jar替换slf4j-jdk14-1.5.10.jar即可(当然也需要log4j的jar及配置文件)

LOG4J 获得 logger 对象:

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

SLF4J 获得 logger 对象:

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

在 LOG4J 中使用的方案:  这一点都不有趣,并且降低了代码可读性。

if (logger.isDebugEnabled()) {  
    logger.debug("Processing trade with id: " + id + " symbol: " + symbol);  
}  

使用SLF4J,你可以得到在极简洁的格式的结果,就像以下展示的一样:

logger.debug("Processing trade with id: {} and symbol : {} ", id, symbol);  

在 SLF4J 不需要字符串连接而且不会导致暂时不需要的字符串消耗。  取而代之的是在一个以占位符和以参数传递实际值的模板格式下写日志信息。

总结:

  1. 大部分人在程序里面会去写logger.error(exception),其实这个时候log4j会去把这个exception toString()。真正的写法应该是logger(message.exception);而slf4j就不会使得程序员犯这个错误。 

  2. log4j间接的在鼓励程序员使用string相加的写法,而slf4j就不会有这个问题。

  3. 你可以使用logger.error("{} is+serviceid",serviceid);  这不仅降低了代码中字符串连接次数,而且还节省了新建的String对象。 
  4. 使用slf4j可以方便的使用其提供的各种集体的实现的jar。(类似commons-logger)
  5. 从commons–logger和log4j merge非常方便,slf4j也提供了一个swing的tools来帮助大家完成这个merge。

如何使用 SLF4J 和 Log4J 来做日志

需要三个 jar 包: 

  1. SLF4J 的接口    slf4j-api-1.6.1.jar 
  2. 中间类              slf4j-log4j12-1.6.1.jar
  3. 实现类              log4j-1.2.16.jar 

如果使用 Maven ,只需要引用中间类的 dependency 即可

因为中间类依赖 SLF4j API 和 Log4j 实现类,Maven 会自动导入这些依赖。 

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

完整版:

           <properties>
               <slf4j.version>1.7.21</slf4j.version>
           </properties>
        <dependencies>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>${slf4j.version}</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>jcl-over-slf4j</artifactId>
                <version>${slf4j.version}</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>${slf4j.version}</version>
            </dependency>

            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.16</version>
            </dependency>
       </dependencies>

说明:

  • SLF4J,即简单日志门面(Simple Logging Facade for Java),不是具体的日志解决方案,它只服务于各种各样的日志系统。
  • slf4j-log4j12:如果仅仅引入slf4j,日志将不会生效。我们需要指定日志的具体实现类,slf4j-xxxx.jar,如slf4j-log4j12,将日志指定为log4j输出。
  • jcl-over-slf4j:把jcl实现的日志输出重定向到 SLF4J。

还需要 Log4j 的配置文件:

​ log4j.properties 

### 设置###
log4j.rootLogger = debug,stdout,D,E

### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout    
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

### 输出DEBUG 级别以上的日志到 =E://logs/log.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = E://logs/log.log
#log4j.appender.D.File = /home/duqi/logs/debug.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG 
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

### 输出ERROR 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://logs/error.log 
log4j.appender.E.File = /home/duqi/logs/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR 
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
赞(0) 打赏
未经允许不得转载:刘鹏博客 » Log4j和Slf4j的比较
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

 

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏