SLF4J不是具体的日志解决方案,它只服务于各种各样的日志系统。按照官方的说法,SLF4J是一个用于日志系统的简单Facade,允许最终用户在部署其应用时使用其所希望的日志系统。
实际上,SLF4J所提供的核心API是一些接口以及一个LoggerFactory的工厂类。从某种程度上,SLF4J有点类似JDBC,不过比JDBC更简单,在JDBC中,你需要指定驱动程序,而在使用SLF4J
的时候,不需要在代码中或配置文件中指定你打算使用那个具体的日志系统。如同使用JDBC基本不用考虑具体数据库一样,SLF4J提供了统一的记录日志的接口,只要按照其提供的方法记录即
可,最终日志的格式、记录级别、输出方式等通过具体日志系统的配置来实现,因此可以在应用中灵活切换日志系统。
如果你开发的是类库或者嵌入式组件,那么就应该考虑采用SLF4J,因为不可能影响最终用户选择哪种日志系统。在另一方面,如果是一个简单或者独立的应用,确定只有一种日志系统,
那么就没有使用SLF4J的必要。假设你打算将你使用log4j的产品卖给要求使用JDK 1.4 Logging的用户时,面对成千上万的log4j调用的修改,相信这绝对不是一件轻松的事情。但是如果开始
便使用SLF4J,那么这种转换将是非常轻松的事情。
配置SLF4J是非常简单的一件事,只要将与你打算使用的日志系统对应的jar包加入到项目中,SLF4J就会自动选择使用你加入的日志系统。
日志系统绑定原理:
在应用中,通过LoggerFactory类的静态getLogger()获取logger。通过查看该类的代码可以看出,最终是通过StaticLoggerBinder.SINGLETON.getLoggerFactory()方法获取
LoggerFactory然后,在通过该具体的LoggerFactory来获取logger的。类org.slf4j.impl.StaticLoggerBinder并不在slf4j-api-1.5.2.jar包中,仔细查看每个与具体日志系统对应的jar包,
就会发现,相应的jar包都有一个org.slf4j.impl.StaticLoggerBinder的实现,不同的实现返回与该日志系统对应的LoggerFactory,因此就实现了所谓的静态绑定,达到只要选取不同jar包
就能简单灵活配置的目的。所以这就解答开始的疑问。
一些开源的架包 比如spring 是如何实现对具体日志解耦的呢,虽然不是使用slf4j,却是用的是Jakarta Commons Logging+log4j,也就是为什么commons-logging出现的频率如此高的原因。他
的功能就是提供了底层的log接口。
Slf4j只提供一个slf4j api(就是slf4j-api.jar包),这个包只有日志的接口,并没有实现,所以要使用得给它提供一个实现了些接口的日志包,比如:log4j,common logging,jdk log等,但
是这些日志实现又不能通过接口直接调用,实现上他们根本就和slf4j-api不一致,因此slf4j又增加了一层来转换各日志实现包的使用,当然slf4j-simple除外。其结构如下:
slf4j-api(接口层)
|
各日志实现包的连接层( slf4j-jdk14, slf4j-log4j)
|
各日志实现包
下面这个图更能说明其原理:
在这里还需要注意的是,连接层的jar包和实现的jar的版本要一致。
配置如下:
1.在web.xml中最上面加入如下配置代码
<!--log4j配置文件加载--> <context-param> <param-name>log4jConfigLocation</param-name> <param-value>/WEB-INF/log4j.properties</param-value> </context-param> <!--启动一个watchdog线程每1800秒扫描一下log4j配置文件的变化--> <context-param> <param-name>log4jRefreshInterval</param-name> <param-value>1800000</param-value> </context-param> <!--spring log4j监听器--> <listener> <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> </listener>
2.把log4j.properties配置文件放在上面配置的指定的目录下
log4j.properties配置文件
###################################### # log4j配置相关说明 ###################################### #%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL #%r 输出自应用启动到输出该log信息耗费的毫秒数 #%c 输出所属的类目,通常就是所在类的全名 #%t 输出产生该日志事件的线程名 #%m 输出代码中指定的信息 #%n 输出一个回车换行符,Windows平台为“\r\n”,Unix平台为“\n” #%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyyy MM dd HH:mm:ss,SSS},输出类似: 2002年10月18日 22:10:28,921 #%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10) #log4j提供4种布局: #org.apache.log4j.HTMLLayout(以HTML表格形式布局) #org.apache.log4j.PatternLayout(可以灵活地指定布局模式), #org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串), #org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息 #log4j中有五级logger 输出级别: #FATAL 0 #ERROR 3 #WARN 4 #INFO 6 #DEBUG 7 ###################################### # log4j相关配置 ###################################### #日志输出级别 log4j.rootLogger=INFO,stdout,other #设置stdout的日志输出控制台 log4j.appender.stdout=org.apache.log4j.ConsoleAppender #输出日志到控制台的方式,默认为System.out log4j.appender.stdout.Target = System.out #设置使用灵活布局 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout #灵活定义输出格式 log4j.appender.stdout.layout.ConversionPattern=[%p][%d{yyyy-MM-dd HH:mm:ss}] %l %m %n #设置other的日志输出控制台 log4j.appender.other=org.apache.log4j.RollingFileAppender #设置other的输出日志 log4j.appender.other.File=${webapp.root}/WEB-INF/logs/log.log #设置other的日志最大限制 log4j.appender.other.MaxFileSize=1024KB #最多只保存20个备份文件 log4j.appender.other.MaxBackupIndex=1000 #输出INFO级别以上的日志 og4j.appender.other.Threshold=INFO #设置使用灵活布局 log4j.appender.other.layout=org.apache.log4j.PatternLayout #灵活定义输出格式 log4j.appender.other.layout.ConversionPattern=[%p][%d{yyyy-MM-dd HH:mm:ss}] %l %t %m %n ###################################### # hibernate相关配置 ###################################### #输出hibernate调试过程中的错误日志 log4j.logger.org.hibernate=other #输出HQL查询调试日志 log4j.logger.org.hibernate.hql.ast.AST=other #输出SQL语句调试日志 log4j.logger.org.hibernate.SQL=other #输出 JDBC参数查询的日志 log4j.logger.org.hibernate.type=other #输出缓存日志 log4j.logger.org.hibernate.cache=other #输出事务日志 log4j.logger.org.hibernate.transaction=other #输出获取JDBC资源日志 log4j.logger.org.hibernate.jdbc=other
首先我们写一个使用的hello world 程序.
1.在classpath中导入"slf4j-api-1.5.5.jar","slf4j-simple-1.5.5.jar" 文件.