Java日志管理方法(转载)
原文地址:http://www.cnblogs.com/leocook/p/log_java.html
java开发中常见的几种日志管理方案有以下4种:
1. Commons-logging + log4j
2. log4j
3. slf4j + log4j + commmons-logging
4. slf4j + log4j
原文地址:http://www.cnblogs.com/leocook/p/log_java.html
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 MMM 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)
日志级别设置:
log4j.rootLogger = [ level ] , appenderName, appenderName
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
下边是一个完整的配置配置文件,仅供参考:

#定义输出端
log4j.rootCategory=INFO,A1,A2,A3 #定义A1输出到控制器
log4j.appender.A1=org.apache.log4j.ConsoleAppender
#定义A1的布局模式为PaternLayout
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
# 定义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.driver=com.mysql.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.getLogger(Log4JTest.class);
if(logger.isDebugEnabled()){
logger.debug(new Exception("testLog4j debug demo.").getMessage());
}
if(logger.isInfoEnabled()){
logger.info(new Exception("testLog4j info demo.").getMessage());
}
logger.error(new Exception("testLog4j error demo.").getMessage());
logger.fatal(new Exception("testLog4j fatal demo.").getMessage());

2、Commons logging
- 概述
Apache针对不同的开发语言做了一系列的日志工具包,在Java、.net、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的兼容
log4j不依赖任何项目,这里点可以在log4j的官网查阅:http://logging.apache.org/log4j/2.x/dependencies.html 。
Commons-logging的在编译依赖、测试依赖等依赖项上都依赖有相关的依赖,所以,在这里可以找到Commons-logging和哪个版本的Log4j兼容性最好(很显然是编译依赖的版本)。具体的依赖关系可见:http://commons.apache.org/proper/commons-logging/dependencies.html。
编译依赖:用源码进行编译时需要的依赖,例如:拿到了Commons-logging的源码,想要编译得到Commons-logging.jar,那么就需要提供依赖中需要的那些jar包。
Commons-logging和log4j结合使用时,Java测试代码如下(Commons-logging + log4j):

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
Log log = LogFactory.getLog(Log4JTest.class);
if (log.isDebugEnabled()) {
log.debug(new Exception("Log4JCommonslogging debug demo.").getMessage());
}
if (log.isErrorEnabled()) {
log.error(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开发中,为保持插件间的独立性,插件只能使用自己的ClassLoader,这就使得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 = LoggerFactory.getLogger(SLF4JTest.class);
logger.debug("some thing :{}",new Exception("testLog4JSLF4J debug demo.").getMessage());
logger.error(new Exception("testLog4JSLF4J error demo.").getMessage());
logger.info(new Exception("testLog4JSLF4J info demo.").getMessage());

以上四种Java处理日志的方法,参考文献见:
http://www.importnew.com/7450.html
http://singleant.iteye.com/blog/934593
原文地址:http://www.cnblogs.com/leocook/p/log_java.html
Java日志管理方法(转载)的更多相关文章
- 4种Java日志管理方法
java开发中常见的几种日志管理方案有以下4种: 1. Commons-logging + log4j 2. log4j 3. slf4j + log4j + commmons-logging 4. ...
- Java日志管理
首页 资讯 精华 论坛 问答 博客 专栏 群组 更多 ▼ 您还未登录 ! 登录 注册 JavaCrazyer的ItEye(codewu.com)技术博客 博客 微博 相册 收藏 留言 关于我 ...
- Java日志管理:Logger.getLogger()和LogFactory.getLog()的区别(详解Log4j)
Java日志管理:Logger.getLogger()和LogFactory.getLog()的区别(详解Log4j) 博客分类: Java综合 第一.Logger.getLogger()和Log ...
- Java 日志管理最佳实践
转:http://blog.jobbole.com/51155/ 日志记录是应用程序运行中必不可少的一部分.具有良好格式和完备信息的日志记录可以在程序出现问题时帮助开发人员迅速地定位错误的根源.对于开 ...
- 使用Common.Logging+log4net规范日志管理【转载】
使用Common.Logging+log4net规范日志管理 Common.Logging+(log4net/NLog/) common logging是一个通用日志接口,log4net是一个强大 ...
- JAVA 日志管理
http://www.360doc.com/content/10/0704/05/2017726_36768082.shtml http://javacrazyer.iteye.com/blog/11 ...
- 如何在Eclipse下查看JDK源代码以及java源代码阅读方法(转载)
不会看JDK源代码,相当于没学过Java. 网上不容易找到一篇帮助我解决了如何在Eclipse下查看JDK源代码 的文章. 核心提示:在Eclipse中查看JDK类库的源代码!!! 设置: 1.点 w ...
- Java日志打印方法
一.使用log4j打印日志 1. 下载log4j.jar和commons-logging.jar. log4j.jar下载地址:http://logging.apache.org/log4j/ ...
- 分析java中clone()方法 (转载+修改)
Java中的clone() 方法 java所有的类都是从java.lang.Object类继承而来的,而Object类提供下面的方法对对象进行复制. protected native Object c ...
随机推荐
- 搭建C语言开发环境
大学的时候有数据结构这门课,但...终究还是得学.电脑是win8的,根据网上的教程倒是能安装成功vc6.0并且能够打开新建工程,但是一编译运行就提示兼容性问题. 首先安装C语言编译器.下载MinGw ...
- linux shell工具集合
1)判断进程是否存在,如果不存在再执行启动命令,可以避免一个脚本同时启动多份 if [ $(ps -ef |grep bastion_account.sh|grep -v grep|wc -l) - ...
- WCF两种方式
http://www.ilanever.com/article/sitedetail.html?id=164 1. 显示添加服务行为,为服务自动提供基于HTTP-GET的元数据.2. 采用元数据交换终 ...
- hiveserver2以及beeline客户端的使用
一:开启服务 1.启动前端的hiveserver2 按住ctrl+c就可以结束这个服务. 2.怎么知道已经开启的服务 如果进程在后台,可以查出来,kill这些进程. 3.后端开启服务 二:beelin ...
- QT多线程及通过事件进行通信(通过自定义事件,然后QApplication::postEvent给主界面,我之前用的是信号槽)
可以通过QThread实现跨平台的多线程开发,Qt库负责在特定平台上的特定多线程实现.要采用QThread进行多线程开发,首先需要包含头文件: #include <QThread> 然后需 ...
- .NET 可空值类型
Microsoft在CLR中引入了可空值类型(nullable value type)的概念. FCL中定义System.Nullable<T>类如下: [Serializable,Str ...
- 1012 最小公倍数LCM
1012 最小公倍数LCM 基准时间限制:1 秒 空间限制:131072 KB 输入2个正整数A,B,求A与B的最小公倍数. Input 2个数A,B,中间用空格隔开.(1<= A,B < ...
- [LeetCode] Combination Sum (bfs)
Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C wher ...
- ArcGIS三大文件格式解析
原文:ArcGIS三大文件格式解析 Shape数据 Shapefile是ArcView GIS 3.x的原生数据格式,属于简单要素类,用点.线.多边形存储要素的形状,却不能存储拓扑关系,具有简单.快速 ...
- C++经典编程题#2:大象喝水
总时间限制: 1000ms 内存限制: 65536kB 描述 一只大象口渴了,要喝20升水才能解渴,但现在只有一个深h厘米,底面半径为r厘米的小圆桶(h和r都是整数).问大象至少要喝多少桶水才会解 ...