日志系统为什么需要SLF4J 4.slf4j结合log4j配置日志系统

1.什么是SLF4J

SLF4J:Simple Logging Facade for Java,为java提供的简单日志Facade。Facade门面,更底层一点说就是接口。它允许用户以自己的喜好,在工程中通过slf4j接入不同的日志系统。更直观一点,slf4j是个数据线,一端嵌入程序,另一端链接日志系统,从而实现将程序中的信息导入到日志系统并记录。

因此slf4j入口就是众多接口的集合,它不负责具体的日志实现,只在编译时负责寻找合适的日志系统进行绑定。具体有哪些接口,全部都定义在slf4j-api中。查看slf4j-api源码就可以发现,里面除了public final class LoggerFactory类之外,都是接口定义。因此slf4j-api本质就是一个接口定义。

SLF4J只是一个接口,而实际的日志操作还是由你绑定的Log4J之类的日志系统(例如log4j)来实现的

2.使用SLF4J便于维护

SLF4J使你的代码独立于任意一个特定的日志API

所有日志系统都使用同一种操作接口,当系统更改日志框架时,可以不用修改分散在各处的日志代码,只是替换个绑定的配置文件

3.占位符(place holder)

占位符是一个非常类似于在String的format()方法中的%s,因为它会在运行时被某个提供的实际字符串所替换。这不仅降低了你代码中字符串连接次数,而且还节省了新建的String对象。即使你可能没需要那些对象,例如在DEBUG或者INFO级别的字符串连接。因为String对象是不可修改的并且它们建立在一个String池中,它们消耗堆内存( heap memory)而且大多数时间他们是不被需要的,例如当你的应用程序在生产环境以ERROR级别运行时候,一个String使用在DEBUG语句就是不被需要的。通过使用SLF4J,你可以在运行时延迟字符串的建立,这意味着只有需要的String对象才被建立。而如果你已经使用log4j,那么你已经对于在if条件中使用debug语句这种变通方案十分熟悉了,但SLF4J的占位符就比这个好用得多。

使用条件输出形式或者使用占位符的方式,否则大量的对象toString和字符串拼接带来严重的性能问题。

例如:

if (logger.isDebugEnabled()) {

logger.debug("Processing trade with id: " + id + " symbol: " + symbol);

}

改成占位符方式:

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

 

 
  • slf4j-api-1.6.1.jar – JAR for SLF4J API
  • log4j-1.2.16.jar – JAR for Log4J API
  • slf4j-log4j12-1.6.1.jar – Log4J Adapter for SLF4J

如果你在使用Maven去管理你的项目依赖,你只需要包含SLF4J JAR包,maven会包含它的依赖的相关包。为了和SLF4J一起中使用Log4J,你可以包含以下的依赖在你项目中的pom.xml。

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

5。其他注意点
 

1.避免重复打印日志,务必设置additivity=false,避免重复打印日志并存储在磁盘上,浪费磁盘空间。

properties配置:log4j.additivity.handler=false

2.禁止直接使用System.out或System.err输出日志或使用e.printStackTrace()打印异常堆栈,由于标准日志输出与标准错误输出文件每次Jboss重启时才滚动,因此,如果大量输出送往这两个文件,容易造成文件大小超过操作系统大小限制。注意,这与 catch(Exception e){} 性质一样恶劣。

3.异常信息应该包括两类信息:案发现场信息 + 异常堆栈追溯信息。如果不处理,那么往上抛。输出POJO对象类必须有toString方法,否则只输出此对象的hashCode值(地址值),没啥参考意义。例如:

logger.error(各类参数或者对象toString +“_”+ e.getMessage(), e); 

 

参考文章:http://www.importnew.com/7450.html