资料参考自:http://www.codeceo.com/article/log4j-usage.html
关于日志的基本概念以及从入门到实战,请参见:http://www.cnblogs.com/LinkinPark/p/5232854.html
(关于简单日志门面slf4j,请参见另外一篇随笔)
经典log4j:
# Global logging configuration log4j.rootLogger=DEBUG, stdout # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
一、log4j概念
Log4j由三个重要的组件构成:
日志信息的优先级,
日志信息的优先级从高到低有ERROR、WARN、 INFO、DEBUG,分别用来指定这条日志信息的重要程度;
级别高的会自动屏蔽级别低的日志,也就是说,设置了WARN的日志,则INFO、DEBUG的日志级别的日志不会显示
日志信息的输出目的地,
日志信息的输出目的地指定了日志将打印到控制台还是文件中;
日志信息的输出格式。
而输出格式则控制了日志信息的显示内容。
二、log4j入门程序
我们这里采用maven进行构建项目,引入的依赖如下:
<dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>${log4j.version}</version> </dependency>
在classpath下新建log4j.properties配置文件,内容如下(细节将会在下节进行讲解):
# 可设置级别:TRACE→DEBUG→INFO→WARNING→ERROR→FATAL→OFF
# 高级别level会屏蔽低级别level。
# debug:显示debug、info、error
# info:显示info、error
#log4j.rootLogger=DEBUG,console,file
log4j.rootLogger=INFO,console
#输出到控制台
log4j.appender.console=org.apache.log4j.ConsoleAppender
#设置输出样式
log4j.appender.console.layout=org.apache.log4j.PatternLayout
#日志输出信息格式为
log4j.appender.console.layout.ConversionPattern=[%-d{yyyy-MM-dd HH:mm:ss}]-[%t-%5p]-[%C-%M(%L)]: %m%n
#输出到文件(这里默认为追加方式)
#log4j.appender.file=org.apache.log4j.FileAppender
#log4j.appender.file.File=F:/LinkinPark/logs/Log4J.log
#样式为TTCCLayout
#log4j.appender.file.layout=org.apache.log4j.TTCCLayout
#自定义样式
#%c 输出所属的类目,通常就是所在类的全名
#%C 输出Logger所在类的名称,通常就是所在类的全名
#%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss , SSS},%d{ABSOLUTE},%d{DATE}
#%F 输出所在类的类名称,只有类名。
#%l 输出语句所在的行数,包括类名+方法名+文件名+行数
#%L 输出语句所在的行数,只输出数字
#%m 输出代码中指定的讯息,如log(message)中的message
#%M 输出方法名
#%p 输出日志级别,即DEBUG,INFO,WARN,ERROR,FATAL
#%r 输出自应用启动到输出该log信息耗费的毫秒数
#%t 输出产生该日志事件的线程名
#%n 输出一个回车换行符,Windows平台为“/r/n”,Unix平台为“/n”
#%% 用来输出百分号“%”
#log4j.appender.Linkin.layout.ConversionPattern=%n[%l%d{yy/MM/dd HH:mm:ss:SSS}][%C-%M] %m
#log4j.appender.Linkin.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss}[%C]-[%p] %m%n
#log4j.appender.Linkin.layout.ConversionPattern = %d{ABSOLUTE} %5p %t %c{2}:%L - %m%n
测试代码如下(测试类叫LogTest):
// 获取日志对象
public static Logger log = Logger.getLogger(LogTest.class);
public static void log() {
log.debug("debug....");
log.info("info...");
log.warn("warn...");
log.error("error...");
try {
int i = 10 / 0;
} catch (Exception e) {
log.error(e.getMessage());
}
}
public static void main(String[] args) {
log();
}
执行结果:
看了入门程序后我们来详解一下log4j的配置文件:
三、log4j的配置文件
Log4j默认的配置文件为log4j.properties。启动时,会加载classpath(比如maven项目放在src/main/resources)下的log4j.properties初始化Log4j。如果文件不存在,Log4j会在控制台打印如下信息,提示说没有找到Log4j配置
log4j:WARN No appenders could be found for logger (org.linkinpark.commons.logtest.Log4jTest). log4j:WARN Please initialize the log4j system properly. log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
一般而言都不推荐自定义配置文件(约定大于配置),所以这里就暂不展开自定义配置文件名称与路径的做法了。
log4j的三大组件
Loggers(记录器),Appenders(输出源)和Layouts(布局)。
其中,Logger负责记录日志,Appender负责输出到什么地方,Layout负责以什么格式输出
日志记录器——Logger
Logger也就是我们代码中出现的Logger:
public static Logger log = Logger.getLogger(LogTest.class);
其中,以类名.class作为参数的Logger,则logger的名字为类的全限定名
logger是单例的,相同名字的logger只会返回一个实例
logger具有继承性,配置文件中可以通过名称来配置logger的属性
log4j中的根记录器rootLogger,它是所有logger的父类
配置文件中的log4j.logger后配置的是logger,一般而言全局只需配置根记录器rootLogger,其它logger继承它的配置即可,而log4j.appender后配置的便是一个Appender
1..配置根Logger,其语法为:
log4j.rootLogger = [ level ] , appenderName, appenderName, …
level 是日志记录的优先级,分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者您定义的级别。
Log4j建议只使用四个级别,优 先级从高到低分别是ERROR、WARN、INFO、DEBUG。
appenderName 就是指日志信息输出到哪个地方。您可以同时指定多个输出目的地。
如果想要某个logger拥有特定配置,可以采用如下方式:(但是只建议修改输出级别,因为即使覆盖了输出地,仍旧会继承父类的appender,相当于两份日志输出,一份按照重写的格式,一份按照父类的格式)
log4j.logger.org.linkinpark.commons.logtest.Log4jTest1=ERROR
log4j.rootLogger=INFO,console
2.配置日志信息输出目的地Appender,其语法为:
log4j.appender.appenderName = fully.qualified.name.of.appender.class
log4j.appender.appenderName.option1 = value1
…
log4j.appender.appenderName.option = valueN
其中,Log4j提供的appender有以下几种:
org.apache.log4j.ConsoleAppender(控制台),
org.apache.log4j.FileAppender(文件),
org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),
org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件),
org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)
其中,输出到文件的实例如下:
#输出到文件(这里默认为追加方式)
log4j.appender.file=org.apache.log4j.FileAppender
#输出文件位置
log4j.appender.file.File=/Users/LinkinPark/WorkSpace/linkin-log-test/log/log4j.log
log4j.appender.file.Append=true
#样式为TTCCLayout
#log4j.appender.file.layout=org.apache.log4j.TTCCLayout
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%-d{yyyy-MM-dd HH:mm:ss}]-[%t-%5p]-[%C-%M(%L)]: %m%n
(1)如果是要指定日志文件的位置为D盘下的log.txt文件。
log4j.appender.thisProject.file.out.File=d:\log.txt
(2)如果指定日志文件的位置为当前的tomcat的工作目录下的某个文件
log4j.appender.thisProject.file.out.File=${catalina.home}/logs/logs_tomcat.log
更加详细的Appender的介绍,请参见:http://www.cnblogs.com/LinkinPark/p/5232850.html
3.配置日志信息的格式(布局),其语法为:
log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class
log4j.appender.appenderName.layout.option1 = value1
…
log4j.appender.appenderName.layout.option = valueN
其中,Log4j提供的layout有以下几种:
org.apache.log4j.HTMLLayout(以HTML表格形式布局),
org.apache.log4j.PatternLayout(可以灵活地指定布局模式),
org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),
org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)
Log4J采用类似C语言中的printf函数的打印格式格式化日志信息,打印参数如下: %m 输出代码中指定的消息
#自定义样式
#%c 输出所属的类目,通常就是所在类的全名
#%C 输出Logger所在类的名称,通常就是所在类的全名
#%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss , SSS},%d{ABSOLUTE},%d{DATE}
#%F 输出所在类的类名称,只有类名。
#%l 输出语句所在的行数,包括类名+方法名+文件名+行数
#%L 输出语句所在的行数,只输出数字
#%m 输出代码中指定的讯息,如log(message)中的message
#%M 输出方法名
#%p 输出日志级别,即DEBUG,INFO,WARN,ERROR,FATAL
#%r 输出自应用启动到输出该log信息耗费的毫秒数
#%t 输出产生该日志事件的线程名
#%n 输出一个回车换行符,Windows平台为“/r/n”,Unix平台为“/n”
#%% 用来输出百分号“%”
我们可以设置日志输出的长度来使得日志变得整齐可读:
在%与参数符号间添加数字,例如%20p,%-20p等。正数表示右对齐,负数表示左对齐,数字表示最小宽度,不足时用空格补齐。
完整格式介绍,请参见::http://www.yiibai.com/log4j/log4j_patternlayout.html
更多详细的layout的配置,参见:http://www.cnblogs.com/LinkinPark/p/5232849.html
三、commons-logging
严格的说,commons-logging不是一个日志控件,没有日志功能,它只是统一了JDK Logging与Log4j的API,并把日志功能交给JDK Loggings或者是log4j。对于不能确定日志方式的系统,commons-logging是一个不错的选择,Spring,Hibernate,Struts等使用的都是commons-logging。
四、Spring中使用Log4j
// TODO
将log4j.properties放在src下,而spring配置文件无需修改。
就放在classpath下,如果配置文件的名字叫"log4j.properties",就不用再自己指定文件名了,Log4j初始化时会自动找到它。
关键部分是web.xml中配置log4j的启动:
<!-- Spring 容器加载 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- 设置根目录--如果不设,默认为web.root,但最好设置,以免项目间冲突 -->
<!--在log4j.properties配置文件,就可以按下面的方式使用${webapp.root}:
log4j.appender.file.File=${webapp.root}/WEB-INF/logs/sample.log
就可以在运行时动态的找出项目的路径-->
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>webapp.root</param-value>
</context-param>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/classes/log4j.properties</param-value>
</context-param>
<!-- 3000表示 开一条watchdog线程每60秒扫描一下配置文件的变化;这样便于日志存放位置的改变 -->
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>3000</param-value>
</context-param>
<listener> //使用了spring的监听器,会在项目启动的时候,启动Log4j
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
</web-app>
对比:
Spring 中log4j配置
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>WEB-INF/log4j.properties</param-value>
</context-param>
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>60000</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.util.Log4jConfigListener
</listener-class>
</listener>