通常日志都是基于slf4j+log4j或slf4j+logback来打印。slf4j作为门面,只是提供接口,实际的打印还是使用log4j或logback提供的功能。本文以log4j为例。
1. log4j的基础:
http://www.cnblogs.com/Fskjb/archive/2011/01/29/1947592.html
要点:Log4J中总是存在一个rootLogger,logger可以继承,可以自定义logger名称,这个名称跟Logger.getLogger("name")的name相关。
Logger.getLogger()还是LogFactory.getLog()
Logger来自log4j自己的包。如果用Logger.getLogger,需要一个log4j的jar包,用此方式你只能依log4j:
LogFactory来自common-logging包。如果用LogFactory.getLog,你可以用任何实现了通用日志接口的日志记录器替换log4j,而程序不受影响。apache的common-logging包是通用日志接口,通过这个中间层,你可以随便指定到底用哪个日志系统。增加系统的灵活性。若log4j它不存在, commons-logging 会另行选择其它的日志实现类。 这样保证了程序中不一定要使用log4j这个日志文件了。
http://www.jb51.net/article/41291.htm
2. slf4j的优点及jar包引用可以参考:
http://www.importnew.com/7450.html
要点:
(1) slf4j是独立与具体打印日志框架的,可以与log4j结合,也可以方便切换到logback。
(2) 相比log4j,slf4j可以使用占位符,比如log4j的写法:
logger.debug("Processing trade with id: " + id + " symbol: " + symbol);
使用slf4j可以:
logger.debug("Processing trade with id: {} and symbol : {} ", id, symbol);
注意:不能{1},{2},{3}这种形式。
这样会在运行时被某个提供的实际字符串所替换。这不仅降低了你代码中字符串连接次数,而且还节省了新建的String对象。
(3) 省去了isDebugEnabled()、isInfoEnabled()的判断,slf4j自动提供了判断。
3. slf4j打印异常
需要打印带有可变参数的日志同时要打印异常信息,用slf4j不能直接把exception放在参数最后,也就是不能:
logger.error("error info {}#{}",new Object[]{a, b}, e);// e 是exception类型
只能:
logger.error("error info {}#{}",new Object[]{a, b, e});// e 是exception类型
把e放到可变对象数组的最后,需要两个参数的时候,把e当做第三个元素即可。
第一种写法会把e当做普通Object,调用e.toString()方法打印,无法打印出异常的堆栈信息。
注意:关于这一点,资料上说slf4j 1.7.*以上版本可以按照第一种写法,1.7.*以下必须按照第二种写法。但本人测试1.7.*也只能按照第二种写法。
4. 关于如何把
不同级别的日志输出到不同文件里,已经有不少文章描述了,完全可以参考。比如:
http://blog.csdn.net/wangchsh2008/article/details/8812857
http://www.cprogramdevelop.com/4496123/
这里有一点需要解释下,如果自定义了logger,比如:log4j.logger.A.B.C=info,ferror,finfo,fdebug
并且分别对为ferror,finfo,fdebug定义了3个文件。
## error appender
log4j.appender.ferror.Threshold = error
log4j.appender.ferror = A.B.C.common.util.MyDailyRollingFileAppender
log4j.appender.ferror.File = ${log.root}/error.log
log4j.appender.ferror.Append = true
log4j.appender.ferror.DatePattern = '.'yyyy-MM-dd'.log'
log4j.appender.ferror.layout = org.apache.log4j.PatternLayout
log4j.appender.ferror.layout.ConversionPattern = %-d{yyyy-MM-dd HH\:mm\:ss} [%p] %X{requestID} [%c-%L]- %m%n
## info appender
log4j.appender.finfo.Threshold = info
log4j.appender.finfo = A.B.C.common.util.MyDailyRollingFileAppender
log4j.appender.finfo.File = ${log.root}/info.log
log4j.appender.finfo.Append = true
log4j.appender.finfo.DatePattern = '.'yyyy-MM-dd'.log'
log4j.appender.finfo.layout = org.apache.log4j.PatternLayout
log4j.appender.finfo.layout.ConversionPattern = %-d{yyyy-MM-dd HH\:mm\:ss} [%p] %X{requestID} [%c-%L]- %m%n
## debug appender
log4j.appender.fdebug.Threshold = debug
log4j.appender.fdebug = A.B.C.common.util.MyDailyRollingFileAppender
log4j.appender.fdebug.File = ${log.root}/debug.log
log4j.appender.fdebug.Append = true
log4j.appender.fdebug.DatePattern = '.'yyyy-MM-dd'.log'
log4j.appender.fdebug.layout = org.apache.log4j.PatternLayout
log4j.appender.fdebug.layout.ConversionPattern = %-d{yyyy-MM-dd HH\:mm\:ss} [%p] %X{requestID} [%c-%L]- %m%n
###root log
log4j.rootLogger = ${log.level},finfo
## my log
log4j.logger.A.B.C=info,ferror,finfo,fdebug
那最后哪些级别的日志会打出来取决于log4j.logger.A.B.C定义的级别。如上配置则debug日志不会打印。
原因:
log4j会自动调用log4jLoggerAdapter的isDebugEnabled()方法:
public boolean isDebugEnabled() {
return this.logger.isDebugEnabled();
}
public boolean isDebugEnabled() {
return this.repository.isDisabled(10000)?false:Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel());
}
这里的getEffectiveLevel()就会返回log4j.logger.A.B.C定义的级别info,debug小于这个级别就直接忽略不打了。
如果这里配置成debug级别,则可以验证通过,后面再打印时会调用自己重写的继承DailyRollingFileAppender类实现的public boolean isAsSevereAsThreshold(Priority priority)方法,这个方法的参数priority就是实际打印日志时调用的方法,比如调用logger.debug(“这是日志”);则priority= Level.DEBUG。然后拿这个级别跟分别配置的ferror,finfo,fdebug的Threshold值比,比较的规则在isAsSevereAsThreshold()里自定义。
分享到:
相关推荐
一个简单的例子slf4j实现热加载日志级别
slf4j-log4j12-1.7.2.jar.zip,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过...
slf4j日志级别有五种:ERROR、WARN、INFO、DEBUG、TRACE,级别从高到底 其示例中取warn级别及写入数据库配置:database 三、配置文件db.properties、log4j.properties两个配置文件可以通过servlet配置来使用,也...
Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过...
从某种程度上,SLF4J有点类似JDBC,不过比JDBC更简单,在JDBC中,你需要指定驱动程序,而在使用SLF4J的时候,不需要在代码中或配置文件中指定你打算使用那个具体的日志系统。如同使用JDBC基本不用考虑具体数据库一样...
SLF4J "日志门面的使用 日志的绑定 日志的桥接 日志门面的原理" log-back "log-back的日志框架 log-back的配置 logback记录tomcat的访问日志" log4j2 "log4j2的日志框架 log4j2的配置 异步日志的使用" spring整合log...
logback-classic:它是log4j的一个改良版本,同时它完整实现了slf4j API使你可以很方便地更换成其它日志系统如log4j或JDK14 Logging。 logback-access:访问模块与Servlet容器集成提供通过Http来访问日志的功能。 ...
Logevents-一个简单的SLF4J实现 无论是使用配置文件还是使用代码,设置和配置日志记录都应该很容易。 日志事件是在SLF4J之上构建的小型(265kb,无依赖项)日志记录框架-用于Java的日志记录语言。 特征: 使用...
Log4j组件解析3. Layout格式4. Appender输出5. 自定义Logger章节四:JCL1. 快速入门2. 原理解析章节五:Slf4j1. 快速入门2. 绑定日志实现3. 桥接旧日志实现4. 原理解析章节六:Logback1. 快速入门2. 配置文件3. ...
---10-slf4j与其他日志的配合与总结.mp4 ---11-log4j2的配置与日志发展历程总结.mp4 ---12-日志组件配置概述.mp4 ---13-jul配置文件与级别.mp4 ---14-jul打印级别与其他配置项.mp4 ---15-log4j配置文件与配置项.mp4 ...
---10-slf4j与其他日志的配合与总结.mp4 ---11-log4j2的配置与日志发展历程总结.mp4 ---12-日志组件配置概述.mp4 ---13-jul配置文件与级别.mp4 ---14-jul打印级别与其他配置项.mp4 ---15-log4j配置文件与配置项.mp4 ...
logback-classic:它是log4j的一个改良版本,同时它完整实现了slf4j API使你可以很方便地更换成其它日志系统如log4j或JDK14 Logging。() logback-access:访问模块与Servlet容器集成提供通过Http来访问日志的功能。...
输出日志到文件 多种日志级别 不依赖第三方库 按文件大小切割 使用 加入依赖 <groupId>com.bladejava</groupId> <artifactId>blade-log <version>0.1.6 配置 com.blade.logger.rootLevel=INFO ...
这意味着您只能将用作实现,它是唯一支持Markers的SLF4J绑定。 目录 日志级别和标记 标记配置 个别配置 全局配置 默认值 主题 计时器 使用PL4J的项目 学分 用法 将其作为Maven依赖项添加到pom.xml文件中: ...
如果您以前使用过log4j,切换到logback将会很顺利。 您需要做的只是: 将logback-classic-0.9.29.jar,logback-core-0.9.29.jar和slf4japi-1.6.1.jar添加到类路径中; 准备一个登录配置文件。 否则,将使用默认的...
JDk版本: 11.0编译/运行编译//不跳过测试mvn clean package //跳过...ps:支持动态调整存活时间功能概述:日志采用slf4j和logback做日志组件同时向控制台和文件输出日志,文件输出错误级别的日志单独放置log_error.l
<artifactId>slf4j-log4j12 ${slf4j.version} <!-- Mybatis --> <groupId>org.mybatis <artifactId>mybatis ${mybatis.version} <groupId>org.mybatis <artifactId>mybatis-spring ${...