4种Java⽇志管理⽅法
java开发中常见的⼏种⽇志管理⽅案有以下4种:
1. Commons-logging + log4j
2. log4j
3. slf4j + log4j + commmons-logging
4. slf4j + log4j
详细说明如下。
1、log4j
概述
log4j是Apache的⼀个开源项⽬,主要是⽤来做Java开发中的⽇志管理⼯作。主要是由三个重要组件构成的。可管理⽇志的优先级、输出⽬的地以及输出格式等。它的配置⽂件主要有XML和properties两种,当然,也可以在程序⾥配置,但实际开发中⼀般使⽤properties⽂件。
log4j的组件
1.1、⽇志信息的优先级(Level)
有7个⽇志级别:OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL,级别从做到有⼀次降低。
Off:关闭所有的⽇志记录
Fatal:记录严重的错误,并且会导致应⽤程序退出
Error:记录严重的错误,但不会影响程序的继续运⾏
Warn:记录警告
Info:记录程序中⽐较有意义的信息
Debug:记录程序中的细节信息
All:记录所有的⽇志
1.2、⽇志信息的输出⽬的地(Appender)
log4j可以把⽇志传送到控制台、⽂件、GUI组件、甚⾄是套接⼝服务器、NT的事件记录器、UNIX Syslog守护进程等。
常⽤的有以下⼏种:
org.apache.log4j.ConsoleAppender(控制台)
org.apache.log4j.FileAppender(⽂件)
org.apache.log4j.DailyRollingFileAppender(每天产⽣⼀个⽇志⽂件)
org.apache.log4j.RollingFileAppender(⽂件⼤⼩到达指定尺⼨的时候产⽣新⽂件)
org.apache.log4j.WriterAppender(将⽇志信息以流格式发送到任意指定的地⽅)
org.apache.log4j.jdbc.JDBCAppender(将⽇志信息写到数据库⾥)
1.3、⽇志信息的输出格式(Layout)
输出格式主要有下边⼏种:
org.apache.log4j.HTMLLayout(HTML表格形式)
org.apache.log4j.PatternLayout(通过表达式指定格式)
org.apache.log4j.SimpleLayout(仅仅包含⽇志信息的级别和信息的简单字符串)
org.apache.log4j.TTCCLayout(包含⽇志产⽣的时间、线程、类别等等信息)
在使⽤表达式指定格式的时候,表达式和C的风格还是很相近的,参数如下:
%m 输出代码中指定的消息
%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
%r 输出⾃应⽤启动到输出该log信息耗费的毫秒数
%c 输出所属的类⽬,通常就是所在类的全名
%t 输出产⽣该⽇志事件的线程名
%n 输出⼀个回车换⾏符,Windows平台为“rn”,Unix平台为“n”
%d 输出⽇志时间点的⽇期或时间,默认格式为ISO8601,也可以在其后指定格式,⽐如:%d{yyy MM
M dd HH:mm:ss,SSS},输出类似:2002年10⽉18⽇22:10:28,921 %l 输出⽇志事件的发⽣位置,包括类⽬名、发⽣的线程,以及在代码中的⾏数。举例:Testlog4.main(TestLog4.java:10)
%x: 输出和当前线程相关联的NDC(嵌套诊断环境),尤其⽤到像java servlets这样的多客户多线程的应⽤中。
%%: 输出⼀个”%”字符 %F: 输出⽇志消息产⽣时所在的⽂件名称
%L: 输出代码中的⾏号
%m: 输出代码中指定的消息,产⽣的⽇志具体信息
%n: 输出⼀个回车换⾏符,Windows平台为”\r\n”,Unix平台为”\n”输出⽇志信息换⾏可以在%与模式字符之间加上修饰符来控制其最⼩宽度、最⼤宽度、和⽂本的对齐⽅式。如:
1)%20c:指定输出category的名称,最⼩的宽度是20,如果category的名称⼩于20的话,默认的情况下右对齐。
2)%-20c:指定输出category的名称,最⼩的宽度是20,如果category的名称⼩于20的话,”-”号指定左对齐。
3)%.30c:指定输出category的名称,最⼤的宽度是30,如果category的名称⼤于30的话,就会将左边多出的字符截掉,但⼩于30的话也不会有空格。
4)%20.30c:如果category的名称⼩于20就补空格,并且右对齐,如果其名称长于30字符,就从左边交远销出的字符截掉。
1.4、配置⽂件格式(properties)
⽇志级别设置:
level:OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL
输出的⽬的地:
#定义appenderName输出到控制器
log4j.appender.appenderName=org.apache.log4j.ConsoleAppender
#定义appenderName的布局模式为PaternLayout
log4j.appender.appenderName.layout=org.apache.log4j.PatternLayout
这⾥的appenderName和上边⽇志级别⾥的appenderName是⼀样的,也就是输出的⽬的地名字,可以任意取。
输出格式配置:
# 定义appenderName的输出格式
log4j.appender.appenderName.layout.ConversionPattern=%4p [%t] (%F:%L) - %m%n
下边是⼀个完整的配置配置⽂件,仅供参考:
#定义输出端
#定义A1输出到控制器
log4j.appender.A1=org.apache.log4j.ConsoleAppender
#定义A1的布局模式为PaternLayout
log4j.appender.A1.layout=org.apache.log4j.PatternLayoutlog4j2不打印日志
# 定义A1的输出格式
log4j.appender.A1.layout.ConversionPattern=%4p [%t] (%F:%L) - %m%n
#定义A2输出到⽂件
log4j.appender.A2=org.apache.log4j.DailyRollingFileAppender
#定义A2输出到哪个⽂件
log4j.appender.A2.File=D:\\log\\sysLog.log
#定义A2输出⽂件的最⼤长度
#log4j.appender.A2.MaxFileSize = 1KB
#定义A2的备份⽂件数
#log4j.appender.A2.MaxBackupIndex = 3
#定义A2的布局模式为PatternLayout
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
#定义A2的输出模式
log4j.appender.A2.layout.ConversionPattern=%d{yyyy-MM-dd hh:mm:ss}:%p %t %c - %m%n
#定义A3输出到数据库
log4j.appender.A3=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.A3.URL=jdbc:mysql://localhost:3306/db_log4j
log4j.appender.A3.sql.jdbc.Driver
log4j.appender.A3.user=root
log4j.appender.A3.password=root
#定义A3的布局和执⾏的SQL语句
log4j.appender.A3.layout=org.apache.log4j.PatternLayout
log4j.appender.A3.layout.ConversionPattern=INSERT INTO tb_log(createDate,thread,level,class,message) values('%d','%t','%-5p','%c','%m')
下边是⼀段Java的测试代码(log4j):
import org.apache.log4j.Logger;
Logger logger = Logger(Log4JTest.class);
if(logger.isDebugEnabled()){
logger.debug(new Exception("testLog4j debug demo.").getMessage());
}
if(logger.isInfoEnabled()){
logger.info(new Exception("testLog4j info demo.").getMessage());
}
<(new Exception("testLog4j error demo.").getMessage());
logger.fatal(new Exception("testLog4j fatal demo.").getMessage());
2、Commons logging
概述
Apache针对不同的开发语⾔做了⼀系列的⽇志⼯具包,在Java、、php、c++上都可以⽤,并且为这些⽇志制定了风格⼀致的操作⽅式,这⾥就实现了Commons-logging(JCL),Commons-logging主要是为哪些需要在不同环境下使⽤不同⽇志结构做开发的程序员⽽编写的,其中包括Apache Log4j和Java log。使⽤Commons-loogging的Log接⼝,并且在运⾏时决定使⽤哪种⽇志架构。现在使⽤Commons-logging和Log4J已经成为了Java⽇志的标准解决⽅案。
已经可以使⽤Log4j了,可为什么还要使⽤Commons-logging呢?在这⾥,Commons-logging相当于⼀个统⼀的⽇志接⼝集,当然他也有已经实现的SimpleLog,但功能很弱。在运⾏时来选择使⽤哪套⽇志的实现(例如Log4J),使得后期更改⽇志框架很⽅便,只需要更改JAR包就可以。另外,Commons-logging的⽇志管理操作更丰富、简单。
Commons-logging和log4j的兼容
编译依赖:⽤源码进⾏编译时需要的依赖,例如:拿到了Commons-logging的源码,想要编译得到Commons-logging.jar,那么就需要提供依赖中需要的那些jar包。
Commons-logging和log4j结合使⽤时,Java测试代码如下(Commons-logging + log4j):
 import org.apachemons.logging.Log;
 import org.apachemons.logging.LogFactory;
Log log = Log(Log4JTest.class);
if (log.isDebugEnabled()) {
log.debug(new Exception("Log4JCommonslogging debug demo.").getMessage());
}
if (log.isErrorEnabled()) {
<(new Exception("Log4JCommonslogging error demo.").getMessage());
}
if (log.isInfoEnabled()) {
log.info(new Exception("Log4JCommonslogging info demo.").getMessage());
}
if (log.isFatalEnabled()) {
log.fatal(new Exception("Log4JCommonslogging fatal demo.").getMessage());
}
3、 SLF4J
与Apache Commons-logging类似,但是它是在编译时静态绑定Log库的,⽽Commons-logging是动态查的机制,是在程序运⾏时才出真正使⽤的⽇志库。
slf4j的必要性
commons-logging是动态查机制,程序运⾏时出真正的⽇志库,是使⽤ClassLoader来寻、加载⽇志库的。但是这样会有个弊端,例如OSGI开发中,为保持插件间的独⽴性,插件只能使⽤⾃⼰的Cla
ssLoader,这就使得Apache Commons-logging⽆法⼯作。
slf4j的优势
⽇志记录⽅式更优雅
如果只使⽤log4j,每次记录⽇志的时候需要判断当前的⽇志级别,例如:
if(logger.isDebugEnabled()){
logger.debug(new Exception("testLog4j debug demo.").getMessage());
}
但是在使⽤slf4j时只需要如下:
logger.debug("Hello world:{}",new Exception("testLog4JSLF4J debug demo.").getMessage());
slf4j底层会识别⽇志界别,从⽽不⽤⾃⼰去判断,⼤⼤的简化了书写。
另外,提供了占位符"{}",使书写布局更加灵活。
降低⽇志系统的对内存消耗
slf4j是延迟字符串的加载,上边这段代码的环境中如果⽇志级别⾼于debug的话,那么new Exception("testLog4JSLF4J debug demo.").getMessage()这段内容将不会被加载。
另外,占位符减少了⽇志信息中字符串的拼接,减少了内存和cpu的性能消耗。
log4j + slf4j + commons-logging
这样的结构体系中,还是使⽤了commons-logging的接⼝,slf4j来决定底层的实现是⽤的哪种⽇志实现的。
需要的jar包:
log4j-1.2.17.jar  log4j实现库
slf4j-api-1.7.7.jar  slf4j库
slf4j-log4j12-1.7.7.jar  log4j的适配器和静态绑定log4j底层的实现
jcl-over-slf4j-1.7.7.jar  提供Commons-logging接⼝,实现底层是由slf4j来决定使⽤哪种实现
测试代码和Commons-logging和log4j结合的代码样例中的代码⼀样(slf4j + log4j + commmons-logging),更改⽇志框架等不⽤修改代码,是不是很⽅便。关于包之间的兼容性,可下载slf4j包,解压后查看⾥边的pom⽂件。
log4j + slf4j
这样的结构体系中,还是使⽤了SLF4J的接⼝,使⽤什么样的⽇志库,由编译时classpath下的⽇志库决定。个⼈推荐这种⽅法。
需要的jar包:
log4j-1.2.17.jar  log4j实现库
slf4j-api-1.7.7.jar  slf4j库
slf4j-log4j12-1.7.7.jar  log4j的适配器和静态绑定log4j底层的实现
测试代码如下(slf4j + log4j):
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Logger logger = Logger(SLF4JTest.class);
logger.debug("some thing :{}",new Exception("testLog4JSLF4J debug demo.").getMessage());
<(new Exception("testLog4JSLF4J error demo.").getMessage());
logger.info(new Exception("testLog4JSLF4J info demo.").getMessage());
以上四种Java处理⽇志的⽅法,参考⽂献见:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。