Slf4j
Simple logging facade for Java (简单日记门面):
是为各种loging APIs提供一个简单统一的接口 在部署时,选择不同的实现包,即可自动转换到不同的日志系统上
Log4j
依赖包
使用slf4j + log4j,实现日志管理:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.6</version>
</dependency>
会自动关联依赖slf4j-api-xxx.jar和log4j-xxx.jar
配置appender
配置日志信息输出目的的
log4j.appender.appenderName = appenderClass
log4j.appender.appenderName.option1 = value1
...
log4j.appender.appenderName.option = valueN
appender class :
implements Appender
,eg:- org.apache.log4j.ConsoleAppender:控制台
- org.apache.log4j.FileAppender:文件
- org.apache.log4j.DailyRollingFileAppender:每天产生一个日志文件
- org.apache.log4j.RollingFileAppender:文件大小到达指定尺寸的时候产生新文件
- org.apache.log4j.WriterAppender:将日志信息以流格式发送到任意指定的地方
- org.apache.log4j.JDBCAppender:将日志信息保存到数据库中
option (使用不同的Appender,option会有所不同,一般公有的option配置项如下)
Threshold
:设置此appender的日志输出级别(过滤器,不设置则依据父类中相应的配置)ImmediateFlush
:默认值是true,意谓着所有的消息都会被立即输出layout
:配置日志信息的格式(布局)log4j.appender.appenderName.layout = layoutClass log4j.appender.appenderName.layout.option1 = value1 .... log4j.appender.appenderName.layout.option = valueN
- layout class:
extends Layout
,不同layout class,使用不同的可配置项 例如:使用
org.apache.log4j.PatternLayout
log4j.appender.activiti.layout.ConversionPattern= %p %d | %C{1}.%M | %m%n
标识 含义 举例 %c
输出所属类的全名,%c{Num} ,Num类名输出的范围 "com.sun.aaa.classB", %C{2}将使日志输出输出范围为:aaa.classB %d
输出日志时间点的日期或时间,默认格式为ISO8601, 可指定格式 %d{yyy MMM dd HH:mm:ss,SSS} 2002年10月18日 22:10:28,921 %l
输出日志事件发生位置,包括类目名、发生线程,在代码中的行数 Testlog4.main(TestLog4.java:10) %n
换行符 Windows平台为“rn”,Unix平台为“n” %m
输出代码中指定信息 info(“message”),输出message %p
输出日志的优先级 即DEBUG,INFO,WARN,ERROR,FATAL %r
输出从启动到显示该条日志信息所耗费的时间(毫秒数) / %t
输出产生该日志事件的线程名 / %F
输出日志消息产生时所在的文件名称 / %L
输出代码中的行号 / PS:可以在
%
与模式字符之间加上修饰符来控制其最小宽度、最大宽度、和文本的对齐方式,eg:%-20c
指定输出category的名称最小的宽度是20,左对齐;%.30c
最大的长度是30,大于30的左边多出的字符截掉
- layout class:
示例:
# 控制台 log4j.appender.Stdout=org.apache.log4j.ConsoleAppender log4j.appender.Stdout.layout=org.apache.log4j.PatternLayout log4j.appender.Stdout.layout.ConversionPattern=[QC] %p %C{1}.%M | %m%n log4j.appender.Stdout.Target=System.err #默认值是System.out # 回滚文件 log4j.appender.RollingFile=org.apache.log4j.RollingFileAppender log4j.appender.RollingFile.layout=org.apache.log4j.PatternLayout log4j.appender.RollingFile.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n log4j.appender.RollingFile.ImmediateFlush=true log4j.appender.RollingFile.Append=true log4j.appender.RollingFile.File=D:/logs/log.log4j log4j.appender.RollingFile.MaxFileSize=200KB log4j.appender.RollingFile.MaxBackupIndex=50 # 定期回滚日志文件 log4j.appender.DailyFile=org.apache.log4j.DailyRollingFileAppender log4j.appender.DailyFile.layout=org.apache.log4j.PatternLayout log4j.appender.DailyFile.layout.ConversionPattern=[R] %p %d | %C{1}.%M | %m%n log4j.appender.DailyFile.File=D:/logs/shuttle/shuttle log4j.appender.DailyFile.DatePattern='.'yyyy-MM-dd'.log' # 发送日志到指定邮件 log4j.appender.Mail=org.apache.log4j.net.SMTPAppender log4j.appender.Mail.Threshold = ERROR log4j.appender.Mail.layout=org.apache.log4j.PatternLayout log4j.appender.Mail.layout.ConversionPattern=%-4r %-5p [%t] %37c %3x - %m%n log4j.appender.Mail.BufferSize=5 log4j.appender.Mail.Subject=ErrorLog log4j.appender.Mail.To=xxx@xxx.com log4j.appender.Mail.From=xxx@xxx.com log4j.appender.Mail.SMTPHost=smtp.xxx.net # 数据库 log4j.appender.Database=org.apache.log4j.jdbc.JDBCAppender log4j.appender.Database.layout=org.apache.log4j.PatternLayout log4j.appender.Database.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n log4j.appender.Database.URL=jdbc:mysql://localhost:3306/test log4j.appender.Database.driver=com.mysql.jdbc.Driver log4j.appender.Database.user=root log4j.appender.Database.password=xxx log4j.appender.Database.sql=INSERT INTO LOG4J (Message) VALUES('=[%-5p] %d(%r) --> [%t] %l: %m %x %n')
配置logger
定义了appender后,需将appender加入Logger,才可用
- 方式一:加入
log4j.rootLogger
(默认日志) - 方式二:加入
log4j.logger
(指定日志)
rootLogger
设置根日志的级别和输出,是所有的日志的父类(相当于默认日志)
log4j.rootLogger=[level],appenderName, ……,
[level]
:日志的级别- 指定这条日志信息的重要性,设置需要输出信息的级别:
ALL<DEBUG<INFO<WARN<ERROR<FATAL<OFF
,不区分大小写 - 一般常用的为
DEBUG
,INFO
,WARN
,ERROR
四种,分别对应Logger类的四种方法:- debug(Object message ) ;
- info(Object message ) ;
- warn(Object message ) ;
- error(Object message ) ;
- 若设置级别为INFO,则优先级大于等于INFO级别的日志信息可以被输出
- 指定这条日志信息的重要性,设置需要输出信息的级别:
appenderName
:日志信息输出目的地- 比如打印到控制台,输出到文件等
- 同一条日志信息可以配置多个输出目的地
例如:
log4j.rootLogger = info,stdout,F
Logger
例如:
log4j.properties
# appender
log4j.appender.test1=org.apache.log4j.FileAppender
log4j.appender.test1.File=${myweb.root}/WEB-INF/log/test1.log
log4j.appender.test1.layout=org.apache.log4j.PatternLayout
log4j.appender.test1.layout.ConversionPattern=%d %p [%c] - %m%n
# logger
log4j.logger.myTest1= info, test1
Test:
@Test
public void testLogger(){
Log logger = LogFactory.getLog("myTest1");
logger.info("xxxx");
}
分离日志
在log4j中子日志输出,父日志也会相应的输出代码,可通过配置additivity
分离日志
log4j.additivity.loggerName=false # 所需的内容从原有日志中分离,默认为true
(PS: additivity
的作用在于 children-logger是否使用顶层或父层的的配置)
示例:
log4j.properties:
log4j.rootLogger=debug,test
# appender: test
log4j.appender.test=org.apache.log4j.FileAppender
log4j.appender.test.File=D://output/test.log
log4j.appender.test.layout=org.apache.log4j.PatternLayout
log4j.appender.test.layout.ConversionPattern=%d %p [%c] - %m%n
# appender: test1
log4j.appender.test1=org.apache.log4j.FileAppender
log4j.appender.test1.File=D://output/test1.log
log4j.appender.test1.layout=org.apache.log4j.PatternLayout
log4j.appender.test1.layout.ConversionPattern=%d %p [%c] - %m%n
# appender: test2
log4j.appender.test2=org.apache.log4j.FileAppender
log4j.appender.test2.File=D://output/test2.log
log4j.appender.test2.layout=org.apache.log4j.PatternLayout
log4j.appender.test2.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.test2.Threshold = warn
# appender: test3
log4j.appender.test3=org.apache.log4j.FileAppender
log4j.appender.test3.File=D://output/test3.log
log4j.appender.test3.layout=org.apache.log4j.PatternLayout
log4j.appender.test3.layout.ConversionPattern=%d %p [%c] - %m%n
# logger
log4j.logger.myTest1= info, test1
log4j.logger.myTest2= info, test2
log4j.additivity.myTest2 = false
Test:
Logger logger=Logger.getLogger(this.getClass());
logger.debug("Debug Message");
logger.info("Info Message");
Logger logger1=Logger.getLogger("myTest1");
logger1.debug("Debug Message-1");
logger1.info("Info Message-1");
Logger logger2=Logger.getLogger("myTest2");
logger2.debug("Debug Message-2");
logger2.info("Info Message-2");
logger2.warn("Warn Message-2");
Result:
test.log:
使用class的logger输出信息(debug级别及以上)
使用myTest1的logger输出信息(info级别及以上)
不包含使用myTest2的logger输出信息 (因为additivity设置为false)
test1.log:
使用myTest1的logger输出信息(info级别及以上)
test2.log:
使用myTest2的logger输出信息(warn级别及以上,因为Threshold设置为warn,且logger中设置的为info,info<warn)
test3.log 不生成 (因为没有被加入到logger中,且rootLogger中也没有加入)
后台使用
读取配置文件
#自动快速地使用缺省Log4j环境:log4j.properties
BasicConfigurator.configure();
#读取使用Java的特性文件编写的配置文件
PropertyConfigurator.configure(String configFilename) ;
# 读取XML形式的配置文件
DOMConfigurator.configure(String filename);
获取日志记录器
//使用Log4j获得logger对象
Logger logger = Logger.getLogger(xxx);
//使用Slf4J获得logger对象
Logger logger = LoggerFactory.getLogger(xxx);
插入记录信息
Logger.debug ( Object message ) ;
Logger.info ( Object message ) ;
Logger.warn ( Object message ) ;
Logger.error ( Object message ) ;
在Spring中使用log4j
配置web.xml (在Spring配置基础上),也可什么都不配,使用默认的即可
<context-param> <param-name>log4jConfigLocation</param-name> <param-value>classpath*:log4j.properties</param-value> </context-param> <!-- 3000表示 开一条watchdog线程每60秒扫描一下配置文件的变化;这样便于日志存放位置的改变 --> <context-param> <param-name>log4jRefreshInterval</param-name> <param-value>3000</param-value> </context-param> <listener> <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> </listener>
Bean中使用
public class SystemAnnualTask { //log4j获取Logger //static Logger logger = Logger.getLogger(SystemAnnualTask.class); //通过slf4j获取Logger static Logger logger = LoggerFactory.getLogger(SystemAnnualTask.class); public void startAnnualProcess(){ ... logger.info(xxx); //这里增加判断,提高效率(可不判断,直接调用) if (logger.isDebugEnabled()){ logger.debug(xxx); } //若使用Slf4j,则可如下使用: logger.info("{} is {}", new String[]{“x",“y"}); ... } }