使用Log4j为项目配置日志输出应用详细总结及示例演示.

Log4j组件构成

Log4j由三个重要的组件构成:

1.日志信息的优先级(Logger)

2.日志信息的输出目的地(Appender)

3.日志信息的输出格式(Layout)。

概要:

日志信息的优先级从高到低有ERROR、WARN、INFO、DEBUG,分别用来指定这条日志信息的重要程度;

日志信息的输出目的地指定了日志将打印到控制台还是文件中;

而输出格式则控制了日志信息的显示内容。

Log4j介绍

  Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件、甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式,通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。log4j--log for java (java的日志) .

Log4j下载地址: http://logging.apache.org/log4j/2.x/download.html

Log4j配置文件的格式

Log4j支持两种配置文件格式:

1. XML格式的文件

2. properties格式的文件

也可以完全不使用配置文件,而是在代码中配置Log4j环境。但是,使用配置文件将使您的应用程序更加灵活。

Log4j定义配置文件

1.配置根Logger

其语法为:

log4j.rootLogger = [ level ] , appenderName, appenderName, …

参数说明:  

level是日志记录的优先级,分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者您定义的级别。

Off:最高等级,用于关闭所有日志记录

Fatal:指出每个严重的错误事件将会导致应用程序的退出。

Error:指出虽然发生错误事件,但仍然不影响系统的继续运行。

Warn:表明会出现潜在的错误情形

Info:一般用在粗粒度级别上,强调应用程序的运行全程

Debug:一般和在粗粒度级别上,强调应用程序的运行全程。

All:最低等级,用于打开所有日志记录。

Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。

appenderName就是指日志信息输出到哪个地方,可以同时指定多个输出目的地。

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(将日志信息以流格式发送到任意指定的地方)

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输出代码中指定的消息  

%p输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL   

%r输出自应用启动到输出该log信息耗费的毫秒数   

%c输出所属的类目,通常就是所在类的全名   

%t输出产生该日志事件的线程名   

%n输出一个回车换行符,Windows平台为“rn”,Unix平台为“n”   

%d输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyyMMMddHH:mm:ss,SSS},输出类似:2002年10月18日22:10:28,921   

%l输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10)

%x:输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像javaservlets这样的多客户多线程的应用中。

%%:输出一个”%”字符 %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字符,就从左边交远销出的字符截掉。

log4j.xml的配置方式

View Code
复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"><log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"><appender name="appender1"class="org.apache.log4j.RollingFileAppender"><param name="File" value="logfile08.html" /><param name="MaxFileSize" value="1MB" /><param name="MaxBackupIndex" value="5" /><layout class="org.apache.log4j.HTMLLayout"></layout></appender><root><level value="debug" /><appender-ref ref="appender1" /></root>
</log4j:configuration>
复制代码

代码中使用Log4j

  在程序中使用Log4j之前,首先要将commons-logging.jar和logging-log4j-1.2.9.jar导入到classpath中,并将log4j.properties放于src根目录中。 在类中使用log4j,首先声明一个静态变量Loggerlogger=Logger.getLog("classname").现在就可以使用了。

用法如下:logger.debug("debugmessage")或者logger.info("infomessage").

1.得到记录器

  使用Log4j,第一步就是获取日志记录器,这个记录器将负责控制日志信息。

其语法为:

  publicstaticLoggergetLogger(Stringname)

  通过指定的名字获得记录器,如果必要的话,则为这个名字创建一个新的记录器。Name一般取本类的名字,比如:

  staticLoggerlogger=Logger.getLogger(ServerWithLog4j.class.getName())

2.读取配置文件

  当获得了日志记录器之后,第二步将配置Log4j环境,其语法为:

  BasicConfigurator.configure():自动快速地使用缺省Log4j环境。

  PropertyConfigurator.configure(StringconfigFilename):读取使用Java的特性文件编写的配置文件。

  DOMConfigurator.configure(Stringfilename):读取XML形式的配置文件。

3.插入记录信息(格式化日志信息)

  当上两个必要步骤执行完毕,您就可以轻松地使用不同优先级别的日志记录语句插入到您想记录日志的任何地方,语法如下:

   Logger.debug(Objectmessage);

   Logger.info(Objectmessage);

   Logger.warn(Objectmessage);

   Logger.error(Objectmessage);

程序演示

1.使用程序进行日志信息输出

复制代码
 1 package org.demo.log4j.dennisit;
 2 
 3 import java.io.IOException;
 4 
 5 import org.apache.commons.logging.impl.Log4JLogger;
 6 import org.apache.log4j.BasicConfigurator;
 7 import org.apache.log4j.FileAppender;
 8 import org.apache.log4j.Layout;
 9 import org.apache.log4j.Level;
10 import org.apache.log4j.Logger;
11 import org.apache.log4j.SimpleLayout;
12 
13 /**
14  *
15  *  @version : 1.1
16  *  
17  *  @author  : 苏若年    <a href="mailto:DennisIT@163.com">发送邮件</a>
18  *    
19  *  @since      : 1.0        创建时间:    2013-1-1        下午03:19:42
20  *     
21  *  @function: 通过代码将日志输出
22  *
23  */
24 
25 public class Log4jPrintByCode {
26 
27     private static Logger logger = Logger.getLogger(Log4jPrintByCode.class);
28     
29     private Layout layout = new SimpleLayout();
30     private FileAppender fileAppender;
31     
32 
33     //使用构造依赖,创建对象时初始化
34     public Log4jPrintByCode(Layout layout, Level level,String distDir){
35         
36         BasicConfigurator.configure();        //使用默认的配置信息,不需要写log4j.properties
37         
38         try {
39             init(layout,level, distDir);
40         } catch (Exception e) {
41             e.printStackTrace();
42         }
43         
44     }
45     
46     
47     public void init(Layout layout, Level level,String distDir) throws Exception{
48         
49         logger.setLevel(level);                //设置日志输出级别
50         fileAppender = new FileAppender(layout,distDir,false);
51         logger.addAppender(fileAppender);    //添加输出端
52         
53     }
54     
55     
56     public static void main(String[] args) {
57         
58         SimpleLayout layout = new SimpleLayout();
59         String logDir = "log4jcode.Log";
60         Log4jPrintByCode log4jCode = new Log4jPrintByCode(layout,Level.INFO,logDir);
61         
62         
63         //下面信息将被输出
64         log4jCode.logger.info("log info print by log4j");
65         log4jCode.logger.warn("log warn print by log4j");
66         log4jCode.logger.error("log error print by log4j");
67         
68     }
69 
70 
71     public Layout getLayout() {
72         return layout;
73     }
74 
75     public void setLayout(Layout layout) {
76         this.layout = layout;
77     }
78 
79     public FileAppender getFileAppender() {
80         return fileAppender;
81     }
82 
83     public void setFileAppender(FileAppender fileAppender) {
84         this.fileAppender = fileAppender;
85     }
86     
87     
88     
89 }
复制代码

为了提高效率,我们可以在写日志前增加判断:

复制代码
// 记录debug级别的信息
if (logger.isDebugEnabled()) {logger.debug("This is debug message from Dao.");
}// 记录info级别的信息
if (logger.isInfoEnabled()) {logger.info("This is info message from Dao.");
}
复制代码

如果这个类作为基类,如J2EE中的BaseDao、BaseAction、BaseService等等,则我们可以将各层的日志信息分类输出到各个文件。

2.Log4J将同一个日志信息输出到多个目的地

应用实例将日志信息同时输出到控制台,文件和数据库中.

创建数据库与 表

复制代码
/* 创建数据库 */ 
create database db_log4j;/* 切换数据库 */
use  db_log4j;/* 日志信息表 */
create table tb_log(logId int not null auto_increment comment '流水号' ,createDate varchar(45) default null comment '日志生成时间' ,thread varchar(45) default null comment '当前线程',level varchar(45) default null comment '当前日志级别' ,class varchar(45) default null comment '生成日志的类',message varchar(245) default null comment '日志具体信息',primary key(logId)
);
复制代码

配置文件log4j.properties

复制代码
#定义3个输出端
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.RollingFileAppender
#定义A2输出到哪个文件
log4j.appender.A2.File=./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测试代码

复制代码
package org.demo.log4j.dennisit;import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;/****  @version : 1.1*  *  @author  : 苏若年    <a href="mailto:DennisIT@163.com">发送邮件</a>*    *  @since      : 1.0        创建时间:    2013-1-1        下午04:13:59*     *  @function: 通过配置文件控制日志信息输出到多个目的端**/public class Log4jPrintByConfigure {private static Logger logger = Logger.getLogger(Log4jPrintByConfigure.class);public static void main(String[] args) throws Exception {//加载log配置文件log4j.propertiesPropertyConfigurator.configure("configure/log4j.properties");//文件存放在src同目录的configure文件夹下//如果放在src下的话,参数应为"bin/log4j.properties"或者"src/log4j.properties", 建议以bin为准//以下信息将被打印输出logger.debug("logger print DEBUG messgae");logger.info("logger print INFO message");logger.warn("logger print WARN message");logger.error("logger print ERROR message");logger.fatal("Here is FATAL message");}}
复制代码

转载请注明出处[http://www.cnblogs.com/dennisit/archive/2013/01/01/2841603.html]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/444411.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leetcode205. 同构字符串 一般人一次做不对的简单题

给定两个字符串 s 和 t&#xff0c;判断它们是否是同构的。 如果 s 中的字符可以被替换得到 t &#xff0c;那么这两个字符串是同构的。 所有出现的字符都必须用另一个字符替换&#xff0c;同时保留字符的顺序。两个字符不能映射到同一个字符上&#xff0c;但字符可以映射自己…

C++:32---IO库

一、IO库 I0库类型和头文件头文件类型iostreamistream,wistream从流读取数据ostream,wostream向流写入数据iostream,wiostream读写流fstreamifstream,wifstream从文件读取数据ofstream,wofstream向文件写入数据fstream,wfstream读写文件sstreamistringstream,wistringst

leetcode209. 长度最小的子数组 借这个题规范一下双指针写法

给定一个含有 n 个正整数的数组和一个正整数 s &#xff0c;找出该数组中满足其和 ≥ s 的长度最小的连续子数组。如果不存在符合条件的连续子数组&#xff0c;返回 0。 示例: 输入: s 7, nums [2,3,1,2,4,3] 输出: 2 解释: 子数组 [4,3] 是该条件下的长度最小的连续子数组…

C++(STL):02---tuple容器

一、tuple的历史概述 Tuple是TR1引入的东西,它扩展了pair的概念,拥有任意数量的元素。在C++11标准之前,tuple最多带有10个类型不同的元素C++11,tuple被重新定义,采用variadic template概念,被设计为可用于任意大小的异质集合二、tuple概述 tuple与pair类似,也是一个模板…

leetcode 231. 2的幂

给定一个整数&#xff0c;编写一个函数来判断它是否是 2 的幂次方。 示例 1: 输入: 1 输出: true 解释: 20 1 示例 2: 输入: 16 输出: true 解释: 24 16 示例 3: 输入: 218 输出: false 本题思路转载位运算的常用技巧&#xff1a;lowbit运算&#xff0c;包含lowbit公式、…

C++(STL):14--- forward_list比list更高效的容器

forward_list 是 C++ 11 新添加的一类容器,其底层实现和 list 容器一样,采用的也是链表结构,只不过 forward_list 使用的是单链表,而 list 使用的是双向链表(如图 1 所示)。 图 1 单链表( a) )和双向链表( b) ) 图 1 中,H 表示链表的表头。 通过图 1 不难看出,使用…

C++(STL):12--- list基本介绍

list 容器,又称双向链表容器,即该容器的底层是以双向链表的形式实现的。这意味着,list 容器中的元素可以分散存储在内存空间里,而不是必须存储在一整块连续的内存空间中。图 1 展示了 list 双向链表容器是如何存储元素的。 图 1 list 双向链表容器的存储结构示意图 可以看到…

Linux下MySQL忘记root密码及解决办法

第一步 修改MySQL的配置文件(默认为/etc/my.cnf),在配置文件的[mysqld]标签下加入一行“skip-grant-tables”,并保存文件sudo vim /etc/my.cnf.d/mysql-server.cnf 第二步 重启MySQL服务sudo service mysqld restart 第三步 输入“mysql -u root -p”命令进入数据库,…

C++(STL):21---deque之源码剖析

一、deque概述 deque的使用语法:总的来说:是一个双端队列特点:支持快速随机访问(支持索引取值)在头尾插入/删除速度很快deque是非常复杂的数据结构,由多个vector组成,迭代器使用时会在不同的区间跳转存取元素的时候,deque的内部结构会多出一个间接过程,相比vector操作…

C++(STL):22 ---序列式容器queue使用

queue是队列,特点是先进先出,后进后出,你可以理解为数据结构里的队列模型,他只允许你访问 queue<T> 容器适配器的第一个和最后一个元素。只能在容器的末尾添加新元素,只能从头部移除元素。许多程序都使用了 queue 容器。queue 容器可以用来表示超市的结账队列或服务…

C++(STL):23 ---序列式容器queue源码剖析

一、queue概述 queue是一种先进先出(First In First Out,FIFO)的数据结构。它有两个出口,形式如下图所示特点:queue允许新增元素、移除元素、从最底端加入元素、取得最顶端元素但除了最底端可以加入、最顶端可以取出外,没有任何其他方法可以存取queue的其他元素。换言之q…

C++(STL):25 ---序列式容器stack源码剖析

一、stack概述 stack是一种先进后出(First In Last Out,FILO)的数据结构。它只有一个出口, 形式如下图所示特点:stack允许新增元素、移除元素、取得最顶端元素。但除了最顶端外,没有任何其他方法可以存取stack的其他元素。换言之stack不允许有遍历行为将元素推入stack的动…

C++:42---类的内存大小

一、类内存的特点 类内无任何成员变量时,默认为1字节类内成员遵循内存的对齐补齐规则(与结构体的对齐补齐一样)函数不占内存(存在代码段)有继承关系时,父类的成员变量也属于类内寸的一部分,但是C++标准并没有明确规定派生类的对象在内存中如何分布(也就是说基类部分和派…

leetcode179. 最大数

给定一组非负整数&#xff0c;重新排列它们的顺序使之组成一个最大的整数。 示例 1: 输入: [10,2] 输出: 210 示例 2: 输入: [3,30,34,5,9] 输出: 9534330 说明: 输出结果可能非常大&#xff0c;所以你需要返回一个字符串而不是整数。 思路&#xff1a;贪心&#xff0c;对于…

C++:47---绝不重新定义继承而来的缺省参数值

一、静态类型、动态类型 静态类型:在被声明时所采用的的类型动态类型:目前所知对象的类型演示案例 下面是一个继承体系class Shape {public:enum ShapeColor { Red, Green, Blue };virtual void draw(ShapeColor color = Red)const = 0;};class Rectangle :public Shape {pub…

C++:53---菱形继承、虚继承

一、菱形继承 在介绍虚继承之前介绍一下菱形继承概念:A作为基类,B和C都继承与A。最后一个类D又继承于B和C,这样形式的继承称为菱形继承菱形继承的缺点:数据冗余:在D中会保存两份A的内容访问不明确(二义性):因为D不知道是以B为中介去访问A还是以C为中介去访问A,因此在访…

C++:52---多重继承

一、多重继承概念 多重继承是指:从多个直接基类而产生派生类的能力例如:class ZooAnimal {}; //动物class Endangered {}; //濒临灭绝的动物class Bear :public ZooAnimal {}; //熊 //多重继承 class Panda :public Bear, public Endangered {}; //熊猫二、多重继承的语法 继…

Redis:15---键迁移(move、dump、restore、migrate)

键迁移概述&#xff1a;键迁移就是把数据由一个Redis迁移到另一个Redis&#xff08;例如从生产环境迁移到测试环境&#xff09;&#xff0c;或者在数据库之间进行迁移键迁移有三种方式&#xff1a;move、dumprestore、migrate下面是三种方式的比较&#xff0c;建议使用migrate&…

Redis:17---常用功能之(事务)

为了保证多条命令组合的原子性&#xff0c;Redis提供了简单的事务功能以及集成Lua脚本来解决这个问题&#xff0c;本文介绍Redis事务&#xff0c;Lua在下一篇文章介绍一、事务概述简单地说&#xff0c;事务表示一组动作&#xff0c;要么全部执行&#xff0c;要么全部不执行。例…

Redis:12---有序集合对象

一、有序集合对象概述它保留了集合不能有重复成员的特性&#xff0c; 但不同的是&#xff0c;有序集合中的元素可以排序。但是它和列表使用索引下标作为排序依据不同的是&#xff0c;它给每个元素设置一个分数&#xff08;score&#xff09;作为排序的依据如下图所示&#xff0…