您的位置:首页 > 其它

Log4j的配置说明与使用原则

2013-11-14 00:00 323 查看
一、Log4j简介与配置参数说明

Log4j有三个主要的组件:Loggers(记录器),Appenders (输出源)和Layouts(布局)。这里可简单理解为日志类别,日志要输出的地方和日志以何种形式输出。综合使用这三个组件可以轻松地记录信息的类型和级别,并可以在运行时控制日志输出的样式和位置。

1、Loggers

Loggers组件在此系统中被分为五个级别:DEBUG、INFO、WARN、ERROR和FATAL。这五个级别是有顺序的,DEBUG < INFO < WARN < ERROR < FATAL,分别用来指定这条日志信息的重要程度,明白这一点很重要,Log4j有一个规则:只输出级别不低于设定级别的日志信息,假设Loggers级别设定为INFO,则INFO、WARN、ERROR和FATAL级别的日志信息都会输出,而级别比INFO低的DEBUG则不会输出。

2、Appenders

禁用和使用日志请求只是Log4j的基本功能,Log4j日志系统还提供许多强大的功能,比如允许把日志输出到不同的地方,如控制台(Console)、文件(Files)等,可以根据天数或者文件大小产生新的文件,可以以流的形式发送到其它地方等等。

常使用的类如下:

org.apache.log4j.ConsoleAppender(控制台)

org.apache.log4j.FileAppender(文件)

org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件)

org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)

org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)

配置模式:

log4j.appender.appenderName = className

log4j.appender.appenderName.Option1 = value1

log4j.appender.appenderName.OptionN = valueN

3、Layouts

有时用户希望根据自己的喜好格式化自己的日志输出,Log4j可以在Appenders的后面附加Layouts来完成这个功能。Layouts提供四种日志输出样式,如根据HTML样式、自由指定样式、包含日志级别与信息的样式和包含日志时间、线程、类别等信息的样式。

常使用的类如下:

org.apache.log4j.HTMLLayout(以HTML表格形式布局)

org.apache.log4j.PatternLayout(可以灵活地指定布局模式)

org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串)

org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等信息)

配置模式:

log4j.appender.appenderName.layout =className

log4j.appender.appenderName.layout.Option1 = value1



log4j.appender.appenderName.layout.OptionN = valueN

二、配置详解

在实际应用中,要使Log4j在系统中运行须事先设定配置文件。配置文件事实上也就是对Logger、Appender及Layout进行相应设定。 Log4j支持两种配置文件格式,一种是XML格式的文件,一种是properties属性文件。下面以properties属性文件为例介绍 log4j.properties的配置。

1、配置根Logger:

log4j.rootLogger = [ level ] , appenderName1, appenderName2, …

log4j.additivity.org.apache=false:表示Logger不会在父Logger的appender里输出,默认为true。

level :设定日志记录的最低级别,可设的值有OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者自定义的级别,Log4j建议只使用中间四个级别。通过在这里设定级别,您可以控制应用程序中相应级别的日志信息的开关,比如在这里设定了INFO级别,则应用程序中所有DEBUG级别的日志信息将不会被打印出来。

appenderName:就是指定日志信息要输出到哪里。可以同时指定多个输出目的地,用逗号隔开。

例如:log4j.rootLogger=INFO,A1,B2,C3

2、配置日志信息输出目的地(appender):

log4j.appender.appenderName = className

appenderName:自定义appderName,在log4j.rootLogger设置中使用;

className:可设值如下:

(1)org.apache.log4j.ConsoleAppender(控制台)

(2)org.apache.log4j.FileAppender(文件)

(3)org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件)

(4)org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)

(5)org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)

(1)ConsoleAppender选项:

Threshold=WARN:指定日志信息的最低输出级别,默认为DEBUG。

ImmediateFlush=true:表示所有消息都会被立即输出,设为false则不输出,默认值是true。

Target=System.err:默认值是System.out。

(2)FileAppender选项:

Threshold=WARN:指定日志信息的最低输出级别,默认为DEBUG。

ImmediateFlush=true:表示所有消息都会被立即输出,设为false则不输出,默认值是true。

Append=false:true表示消息增加到指定文件中,false则将消息覆盖指定的文件内容,默认值是true。

File=D:/logs/logging.log4j:指定消息输出到logging.log4j文件中。

(3)DailyRollingFileAppender选项:

Threshold=WARN:指定日志信息的最低输出级别,默认为DEBUG。

ImmediateFlush=true:表示所有消息都会被立即输出,设为false则不输出,默认值是true。

Append=false:true表示消息增加到指定文件中,false则将消息覆盖指定的文件内容,默认值是true。

File=D:/logs/logging.log4j:指定当前消息输出到logging.log4j文件中。

DatePattern='.'yyyy-MM:每月滚动一次日志文件,即每月产生一个新的日志文件。当前月的日志文件名为logging.log4j,前一个月的日志文件名为logging.log4j.yyyy-MM。

另外,也可以指定按周、天、时、分等来滚动日志文件,对应的格式如下:

1)'.'yyyy-MM:每月

2)'.'yyyy-ww:每周

3)'.'yyyy-MM-dd:每天

4)'.'yyyy-MM-dd-a:每天两次

5)'.'yyyy-MM-dd-HH:每小时

6)'.'yyyy-MM-dd-HH-mm:每分钟

(4)RollingFileAppender选项:

Threshold=WARN:指定日志信息的最低输出级别,默认为DEBUG。

ImmediateFlush=true:表示所有消息都会被立即输出,设为false则不输出,默认值是true。

Append=false:true表示消息增加到指定文件中,false则将消息覆盖指定的文件内容,默认值是true。

File=D:/logs/logging.log4j:指定消息输出到logging.log4j文件中。

MaxFileSize=100KB:后缀可以是KB, MB 或者GB。在日志文件到达该大小时,将会自动滚动,即将原来的内容移到logging.log4j.1文件中。

MaxBackupIndex=2:指定可以产生的滚动文件的最大数,例如,设为2则可以产生logging.log4j.1,logging.log4j.2两个滚动文件和一个logging.log4j文件。

3、配置日志信息的输出格式(Layout):

log4j.appender.appenderName.layout=className

className:可设值如下:

(1)org.apache.log4j.HTMLLayout(以HTML表格形式布局)

(2)org.apache.log4j.PatternLayout(可以灵活地指定布局模式)

(3)org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串)

(4)org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)

(1)HTMLLayout选项:

LocationInfo=true:输出java文件名称和行号,默认值是false。

Title=My Logging: 默认值是Log4J Log Messages。

(2)PatternLayout选项:

ConversionPattern=%m%n:设定以怎样的格式显示消息。

格式化符号说明:

格式化符号 说明 例子
%p 输出日志信息的优先级,即DEBUG,INFO,WARN
,ERROR,FATAL。
%d 输出日志时间点的日期或时间,默认格式为ISO8601,
也可以在其后指定格式
如:%d{yyyy/MM/dd HH:mm:ss,SSS}
%r 输出自应用程序启动到输出该log信息耗费的毫秒数
%t 输出产生该日志事件的线程名
%l 输出日志事件的发生位置,相当于%c.%M(%F:%L)的组合,包括类全名、方法、文件名以及在代码中的行数 例如:com.buy360.restFul.AsTest.main(AsTest.java:10)
%c 输出日志信息所属的类目,通常就是所在类的全名 com.buy360.restFul.AsTest
%M 输出产生日志信息的方法名
%F 输出日志消息产生时所在的文件名称
%L 输出代码中的行号
%m 输出代码中指定的具体日志信息
%n 输出一个回车换行符,Windows平台为"\r\n",Unix平台为"\n"
%x 输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中
另外,还可以在%与格式字符之间加上修饰符来控制其最小长度、最大长度、和文本的对齐方式。如:

1) c:指定输出category的名称,最小的长度是20,如果category的名称长度小于20的话,默认的情况下右对齐。

2)%-20c:"-"号表示左对齐。

3)%.30c:指定输出category的名称,最大的长度是30,如果category的名称长度大于30的话,就会将左边多出的字符截掉,但小于30的话也不会补空格。

三、如何正确地输出日志。

1、理解正确的日志输出级别
很多程序员都忽略了日志输出级别, 甚至不知道如何指定日志的输出级别. 相对于System.out来说, 日志框架有两个最大的优点就是可以指定输出类别(category)和级别(level). 对于日志输出级别来说, 下面是我们应该记住的一些原则:

ERROR 系统发生了严重的错误, 必须马上进行处理, 否则系统将无法继续运行. 比如数据库不可用等
WARN 系统能继续运行, 但是必须引起关注. 对于存在的问题一般可以分为两类: 一种系统存在明显的问题
(比如, 数据不可用), 另一种就是系统存在潜在的问题, 需要引起注意或者给出一些建议(比如, 系统运
行在安全模式或者访问当前系统的账号存在安全隐患). 总之就是系统仍然可用, 但是最好进行检查和调整.
INFO 重要的业务逻辑处理完成. 在理想情况下, INFO的日志信息要能让高级用户和系统管理员理解, 并从日
志信息中能知道系统当前的运行状态. 比如
DEBUG 主要用于调试、测试时使用,一般是在程序中不是非常重要的地方,这部分的日志较多,但是在线上运行
时我们一般会将日志级别设置为INFO,避免DEBUG日志过多影响性能.
TRACE 系统详细信息, 主要给开发人员用, 一般来说, 如果是线上系统的话, 可以认为是临时输出, 而且随时可以
通过开关将其关闭. 有时候我们很难将DEBUG和TRACE区分开, 一般情况下, 如果是一个已经开发测试完
成的系统, 再往系统中添加日志输出, 那么应该设为TRACE级别
2、日志的作用:

首先,它能在程序运行过程中精确的提供运行时的上下文(context)方便开发人员找到 BUG,一旦在程序中加入了Log 输出的代码,程序运行过程中就能自动的生成并输出logging信息。其次,log信息可以输出到不同的地方(控制台,文件,日志服务器等等)以备时候研究、统计。

3、日志的副作用:

降低应用性能(日志的输出必然会有字符串的创建、合并,然后输出到文件又必然会有IO的消耗,在一个100万次的循环中,输出日志和不输出日志的性能差距甚至可以达到100倍,千倍),增加代码的编写量,这个大家都懂的。

4、日志输出的原则:

Log4j建议只使用四个级别,优先级从高到低分别是 ERROR、WARN、INFO、DEBUG。通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。
(1)、对程序的输入输出要以DEBUG记录下来,常包括从文件、数据库、网络、用户等输入的信息,向文件、数据库、网络输出的信息。
(2)、对重要对象或程序状态的修改,要以INFO记录修改前的信息和修改后的状态。
(3)、不能忽视每个调用错误,异常日志的内容要能清晰描述运行上下文,这样有助于排查错误,输出异常日志时, 第一个参数一定是一个字符串, 一般都是对问题的描述信息, 而不能是异常message(因为堆栈里面会有), 第二个参数才是具体的异常实例. ,例如:log.error("导入数据失败,错误信息为:", e); 。
(4)、记下打印信息时所在的文件名和函数名(必须能区分开重载函数),有行数最好。
(5)、
对于高并发系统,能不打印日志就不打印日志,
输出的
日志数量、
级别、内容都要经过评估,避免日志输出影响性能,
,可以采用初期上线时多打印一些日志,上线运行一段时间后,通过观察方法调用次数,响应性能来决定减少那些日志的打印或者改变打印日志的级别

(6)、对于异常日志的内容要能清晰描述运行上下文,这样有助于排查错误。

四、使用Log4j需要注意的地方

1、打印DEBUG日志时最好加上isDebugalbe()的判断,虽然Log4j不会输出debug的日志内容(日志级别是INFO),但是调用log.debug的时候必然会传参进去,对于参数又是字符串拼接的时候,对于方法调用次数特别大的场景下,对性能的影响是明显的,加上isDebugalbe()的判断,这样做会减少字段串的合并,理论上可以减少JVM的垃圾回收次数。

2、对于
日志内容,
通常应该包含当前时间、日志级别、线程名称、日志描述信息,也可以包含方法名,类名,行号(但是让log4j输出这些信息对性能是很有影响的),所以对于要求高性能的应用最好不要输出这些信息。

五、Log4j按级别输出日志到不同的文件

会按日存分割日志文件,并且根据级别输出到不同的文件

log4j.rootLogger=info,stdout,info,debug,error
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%-5p] [%d{HH:mm:ss}] %c - %m%n

log4j.logger.info=info
log4j.appender.info=org.apache.log4j.DailyRollingFileAppender
log4j.appender.info.layout=org.apache.log4j.PatternLayout
log4j.appender.info.layout.ConversionPattern=[%-5p] [%d{HH:mm:ss}] %c - %m%n
log4j.appender.info.datePattern='.'yyyy-MM-dd
log4j.appender.info.Threshold = INFO
log4j.appender.info.append=true
log4j.appender.info.File=${webApp.root}/WEB-INF/logs/info.log

log4j.logger.debug=debug
log4j.appender.debug=org.apache.log4j.DailyRollingFileAppender
log4j.appender.debug.layout=org.apache.log4j.PatternLayout
log4j.appender.debug.layout.ConversionPattern=[%-5p] [%d{HH:mm:ss}] %c - %m%n
log4j.appender.debug.datePattern='.'yyyy-MM-dd
log4j.appender.debug.Threshold = DEBUG
log4j.appender.debug.append=true
log4j.appender.debug.File=${webApp.root}/WEB-INF/logs/debug.log

log4j.logger.error=error
log4j.appender.error=org.apache.log4j.DailyRollingFileAppender
log4j.appender.error.layout=org.apache.log4j.PatternLayout
log4j.appender.error.layout.ConversionPattern=[%-5p] [%d{HH:mm:ss}] %c - %m%n
log4j.appender.error.datePattern='.'yyyy-MM-dd
log4j.appender.error.Threshold = ERROR
log4j.appender.error.append=true
log4j.appender.error.File=${webApp.root}/WEB-INF/logs/error.log

六、在程序中使用
SLF4J
来隔离log4j

1、SLF4J简介

SLF4J,即简单日志门面(Simple Logging Facade for Java),不是具体的日志解决方案,它只服务于各种各样的日志系统。按照官方的说法,SLF4J是一个用于日志系统的简单Facade,允许最终用户在部署其应用时使用其所希望的日志系统。
实际上,SLF4J所提供的核心API是一些接口以及一个LoggerFactory的工厂类。从某种程度上,SLF4J有点类似JDBC,不过比JDBC更简单,在JDBC中,你需要指定驱动程序,而在使用SLF4J的时候,不需要在代码中或配置文件中指定你打算使用那个具体的日志系统。如同使用JDBC基本不用考虑具体数据库一样,SLF4J提供了统一的记录日志的接口,只要按照其提供的方法记录即可,最终日志的格式、记录级别、输出方式等通过具体日志系统的配置来实现,因此可以在应用中灵活切换日志系统。

2、什么情况可以使用

如果你开发的是类库或者嵌入式组件,那么就应该考虑采用SLF4J,因为不可能影响最终用户选择哪种日志系统。在另一方面,如果是一个简单或者独立的应用,确定只有一种日志系统,那么就没有使用SLF4J的必要。假设你打算将你使用log4j的产品卖给要求使用JDK 1.4 Logging的用户时,面对成千上万的log4j调用的修改,相信这绝对不是一件轻松的事情。但是如果开始便使用SLF4J,那么这种转换将是非常轻松的事情。

采用SLF4J可以轻松切换到性能更高、实现更完善的日志组件,比如LogBack,关于LogBack的介绍与使用请参考http://www.cnblogs.com/yuanermen/archive/2012/02/13/2348942.html这篇贴子,或者官网http://logback.qos.ch/,LogBack与Log4j是同一个作者开发,可以看作是LOG4J的升级版或者改良版。

3、使用SFL4J

需要的配置文件和组件包,下面三个 jar 文件和一个 properties 文件都是要放在项目的 ClassPath 上

A. slf4j-api-1.5.11.jar
B. slf4j-log4j12-1.5.11.jar
C. log4j-1.2.16.jar
D. log4j.properties(也可以是 log4j.xml,本例中用 log4j.propertes)

如果是Mavn工程,那么就在POM中引入。

<dependency>

<groupId>log4j</groupId>

<artifactId>log4j</artifactId>

<version>1.2.16</version>

</dependency>

<dependency>

<groupId>org.slf4j</groupId>

<artifactId>slf4j-log4j12</artifactId>

<version>1.6.1</version>

</dependency>

<dependency>

<groupId>org.slf4j</groupId>

<artifactId>slf4j-api</artifactId>

<version>1.6.1</version>

</dependency>

4、使用 SLF4J 的代码:

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

public class TestSlf4J {

private static final Logger logger = LoggerFactory.getLogger(TestSlf4j.class);

public static void main(String[] args) {

logger.info("Hello {}","SLF4J"); //log4j的API是不支持这种写法的。

}

}

执行它,控制台输出:

2013-11-07 15:34:45,245 [com.unmi.TestSlf4j]-[INFO] Hello
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  log4j SLF4J LogBack