您的位置:首页 > 编程语言 > Java开发

如何利用Log4j将不同级别,不同package中Log输出到不同的文件中

2012-10-11 14:50 721 查看
Log4j对我来说从来就是一笔糊涂账, 基本上就是从其他项目中, 或网上找一段下来依葫芦画瓢,反正都是无关痛痒的东西,从来没有仔细研究过。
最近做了个小项目,客户把Log看的比业务都重要,不得已又要提高自己了,仔细研究了一下,终于从稀里糊涂里走出来了。

本文不打算详细的介绍Log4j, 所以,诸如Log的 level(级别), Appender (输出目的地),Layout(输出格式)以及打印参数等等,
不再熬述, 因为这样的文章网上一搜一麻袋,各位如果想找这方面的资料, 那就Google吧。

本文要说明的重点有两个:

1.如何利用Log4j将不同级别,不同package中Log输出到不同的文件中

2.Log4j的设置和package划分的关系

本文将从实战的角度出发,讲述本项目对Log输出的要求, 以及如何实现这样的要求, 希望对各位童鞋有用。

一.项目简介

环境:Eclipse

语言:Java

业务:分为Web系 和 Batch系两个模块

Package:

├─x

│ └─y

│ └─z

│ └─e

│ └─w

// 以下为Web系

│ ├─action

│ │ └─interceptor

│ ├─dto

│ ├─entity

│ ├─exception

│ ├─hibernate

│ ├─listener

│ ├─service

│ └─util

// 以下为Batch系

│ ├─batch

│ │ ├─bean

│ │ ├─conf

│ │ ├─exception

│ │ ├─query

│ │ └─util

// 其他

└─template

└─simple

PS:

从上面的目录结构图不难看出, Web系和Batch系没有明确的分开,Batch系的Source全部在【bacth】package下面了, 但是Web系的Source却没有定义一个独立的package,而是散落在【w】package下面。

这是一个垃圾的设计,由于我一时的疏忽,没有考虑周全造成的。这会给Log4j的配置带来不必要的麻烦。在稍后会讲解它的弊端以及如何改善这个问题。

二.对Log输出的要求

1. 只输出DEBUG,INFO,ERROR三种级别的LOG

2. Web系的LOG分别输出到 web_debug.log, web_info.log, web_error.log
文件中

3. Batch系的LOG分别输出到
batch_debug.log, batch_info.log, batch_error.log 文件中

PS:注意Web系和Batch系是分开的,也就是说在Batch系的Log中不能出现Web系的Log,Web系的Log也不能出现在Batch系的Log中。

4. 每个Class,Method的预定动作,都会输出设计书规定的Log。

考虑到Framework采用Struts2 + Hibernate, 所以,Struts和Hibernate输出的Log,在项目发布时,预定关闭。

但是,要让客户能够轻而易举的将这两个OpenSource的Log打开。

但是,除此之外的其他第三方的OpenSource输出的Log,一律不准出现在Log文件中。

PS:客户对Log4j的了解为零(其实他也懂一点,但是他命令我把他当做傻瓜来看,这让我很为难,但我必须服从命令^_^)

// 其他打印格式等信息,此处省略,这不是本文讲述的重点

三.实现

[plain] view
plaincopy

#--------------------------------------------------------------------

#log4j.properties

#--------------------------------------------------------------------

# log4j.rootLogger = arg1, arg2, arg3,....

# arg1 = ( DEBUG | INFO | WARN | ERROR | ALL | OFF | FATAL )

# arg2,... is appender.

#log4j.rootLogger = ERROR, C0, A0, A1, A2

#In order to facilitate all levels of the log output can be flexible,

#root logger is closed

log4j.rootLogger = OFF

#------------------------

#Web Log

#Level :

# Followed from low to high is : ( DEBUG | INFO | WARN | ERROR | ALL | OFF | FATAL )

# Higher than the current level log only will be output.

#appender :

# A0 : web debug log appender

# A1 : web info log appender

# A2 : web error log appender

# C0 : web console log appender, currently is not being used.

# if you want to use it, add it at log appender.

# for example : log4j.logger.x.y.z.e.w.action = DEBUG, C0, A0, A1, A2

# after used it, log information will be output to the console.

#

#------------------------

# system log

log4j.logger.x.y.z.e.w.action = DEBUG, A0, A1, A2

log4j.logger.x.y.z.e.w.action.interceptor = DEBUG, A0, A1, A2

log4j.logger.x.y.z.e.w.bean = DEBUG, A0, A1, A2

log4j.logger.x.y.z.e.w.dto = DEBUG, A0, A1, A2

log4j.logger.x.y.z.e.w.entity = DEBUG, A0, A1, A2

log4j.logger.x.y.z.e.w.exception = DEBUG, A0, A1, A2

log4j.logger.x.y.z.e.w.hibernate = DEBUG, A0, A1, A2

log4j.logger.x.y.z.e.w.listener = DEBUG, A0, A1, A2

log4j.logger.x.y.z.e.w.service = DEBUG, A0, A1, A2

log4j.logger.x.y.z.e.w.util = DEBUG, A0, A1, A2

#hibernate log

#hibernate log is closed, if you want to open it, use the following format .

#log4j.logger.org.hibernate = arg1, arg2

#arg1 : (DEBUG | INFO | WARN | ERROR | ALL | OFF | FATAL )

#arg2 : A0, A1, A2

log4j.logger.org.hibernate = OFF

#struts2 log

#struts log is closed, if you want to open it, use the following format .

#log4j.logger.org.apache.struts2 = arg1, arg2

#arg1 : (DEBUG | INFO | WARN | ERROR | ALL | OFF | FATAL )

#arg2 : A0, A1, A2

log4j.logger.org.apache.struts2 = OFF

#------------------------

# batch log

# B0 : batch debug log appender

# B1 : batch info log appender

# B2 : batch error log appender

#------------------------

#system batch log

log4j.logger.x.y.z.e.w.batch = DEBUG, B0, B1, B2

#---------------------------------------------------------------------

# Console

# console appender is currently not being used, if you use it,

# log information will be output to the console.

# How to use it? -> in the corresponding log appender add it.

# for example : log4j.logger.x.y.z.e.w.action = DEBUG, C0, A0, A1, A2

log4j.appender.C0 = org.apache.log4j.ConsoleAppender

log4j.appender.C0.Threshold = ALL

log4j.appender.C0.layout = org.apache.log4j.PatternLayout

log4j.appender.C0.layout.ConversionPattern=[%d{HH:mm:ss,SSS}][%-5p] (%F#%M:%L) - %m%n

#---------------------------------------------------------------------

# WEB DEBUG LOG

log4j.appender.A0 = a.b.c.log4j.DailyRollingFileAppenderEx

log4j.appender.A0.File = /var/log/web_debug.log

log4j.appender.A0.Threshold = DEBUG

log4j.appender.A0.append=true

log4j.appender.A0.layout = org.apache.log4j.PatternLayout

log4j.appender.A0.layout.ConversionPattern=[%d{HH:mm:ss,SSS}][%-5p] (%F#%M:%L) - %m%n

#---------------------------------------------------------------------

# WEB INFO LOG

log4j.appender.A1 = a.b.c.log4j.DailyRollingFileAppenderEx

log4j.appender.A1.File = /var/log/web_info.log

log4j.appender.A1.Threshold = INFO

log4j.appender.A1.append=true

log4j.appender.A1.layout = org.apache.log4j.PatternLayout

log4j.appender.A1.layout.ConversionPattern=[%d{HH:mm:ss,SSS}][%-5p] (%F#%M:%L) - %m%n

#---------------------------------------------------------------------

# WEB ERROR LOG

log4j.appender.A2 = a.b.c.log4j.DailyRollingFileAppenderEx

log4j.appender.A2.File = /var/log/web_error.log

log4j.appender.A2.Threshold = ERROR

log4j.appender.A2.append=true

log4j.appender.A2.layout = org.apache.log4j.PatternLayout

log4j.appender.A2.layout.ConversionPattern=[%d{HH:mm:ss,SSS}][%-5p] (%F#%M:%L) - %m%n

#---------------------------------------------------------------------

# BATCH DEBUG LOG

log4j.appender.B0 = a.b.c.log4j.DailyRollingFileAppenderEx

log4j.appender.B0.File = /var/log/batch_debug.log

log4j.appender.B0.Threshold = DEBUG

log4j.appender.B0.append=true

log4j.appender.B0.layout = org.apache.log4j.PatternLayout

log4j.appender.B0.layout.ConversionPattern=[%d{HH:mm:ss,SSS}][%-5p] (%F#%M:%L) - %m%n

#---------------------------------------------------------------------

# BATCH INFO LOG

log4j.appender.B1 = a.b.c.log4j.DailyRollingFileAppenderEx

log4j.appender.B1.File = /var/log/batch_info.log

log4j.appender.B1.Threshold = INFO

log4j.appender.B1.append=true

log4j.appender.B1.layout = org.apache.log4j.PatternLayout

log4j.appender.B1.layout.ConversionPattern=[%d{HH:mm:ss,SSS}][%-5p] (%F#%M:%L) - %m%n

#---------------------------------------------------------------------

# BATCH ERROR LOG

log4j.appender.B2 = a.b.c.log4j.DailyRollingFileAppenderEx

log4j.appender.B2.File = /var/log/batch_error.log

log4j.appender.B2.Threshold = ERROR

log4j.appender.B2.append=true

log4j.appender.B2.layout = org.apache.log4j.PatternLayout

log4j.appender.B2.layout.ConversionPattern=[%d{HH:mm:ss,SSS}][%-5p] (%F#%M:%L) - %m%n

这里对Log4j的设置做一下讲解:

讲解一. 第12行

[plain] view
plaincopy

log4j.rootLogger = OFF

为什么将根Log关闭了呢? 因为所有的logger都会自动继承RootLogger,客户要求除Struts和Hibernate外的其他第三方OpenSource输出的Log,一律不准输出。

项目中使用了大量的其他第三方的OpenSource,RootLogger设定为OFF,所有使用Log4j的OpenSource都会自动继承RootLogger,被设定OFF。

除非再次显式的为它指定logger,否则,所有使用Log4j输出的Log都将不会输出,本项目中,在关闭RootLogger以后,就再次显式的指定了以下logger。

[plain] view
plaincopy

log4j.logger.x.y.z.e.w.action = DEBUG, A0, A1, A2

log4j.logger.x.y.z.e.w.action.interceptor = DEBUG, A0, A1, A2

log4j.logger.x.y.z.e.w.bean = DEBUG, A0, A1, A2

log4j.logger.x.y.z.e.w.dto = DEBUG, A0, A1, A2

log4j.logger.x.y.z.e.w.entity = DEBUG, A0, A1, A2

log4j.logger.x.y.z.e.w.exception = DEBUG, A0, A1, A2

log4j.logger.x.y.z.e.w.hibernate = DEBUG, A0, A1, A2

log4j.logger.x.y.z.e.w.listener = DEBUG, A0, A1, A2

log4j.logger.x.y.z.e.w.service = DEBUG, A0, A1, A2

log4j.logger.x.y.z.e.w.util = DEBUG, A0, A1, A2

[plain] view
plaincopy

log4j.logger.x.y.z.e.w.batch = DEBUG, B0, B1, B2

这样一来,除上面明确指出的logger以外,其他所有的log都不会输出了。

当然还有下面两个Log:

[plain] view
plaincopy

#hibernate log

#hibernate log is closed, if you want to open it, use the following format .

#log4j.logger.org.hibernate = arg1, arg2

#arg1 : (DEBUG | INFO | WARN | ERROR | ALL | OFF | FATAL )

#arg2 : A0, A1, A2

log4j.logger.org.hibernate = OFF

#struts2 log

#struts log is closed, if you want to open it, use the following format .

#log4j.logger.org.apache.struts2 = arg1, arg2

#arg1 : (DEBUG | INFO | WARN | ERROR | ALL | OFF | FATAL )

#arg2 : A0, A1, A2

log4j.logger.org.apache.struts2 = OFF

这两个不写,也不会输出Log,因为他们会继承自RootLogger的OFF设定。

上面说了,客户要求预定将这两个Log关闭,必要的时候可以打开。看到上面蹩脚的英文说明没有,那是本人一级英语的杰作。尽管看上去都是废话,没办法,客户命令我把他当做傻瓜来看待。

讲解二.package 的划分与Log4j设置的关系

[plain] view
plaincopy

# system log

log4j.logger.x.y.z.e.w.action = DEBUG, A0, A1, A2

log4j.logger.x.y.z.e.w.action.interceptor = DEBUG, A0, A1, A2

log4j.logger.x.y.z.e.w.bean = DEBUG, A0, A1, A2

log4j.logger.x.y.z.e.w.dto = DEBUG, A0, A1, A2

log4j.logger.x.y.z.e.w.entity = DEBUG, A0, A1, A2

log4j.logger.x.y.z.e.w.exception = DEBUG, A0, A1, A2

log4j.logger.x.y.z.e.w.hibernate = DEBUG, A0, A1, A2

log4j.logger.x.y.z.e.w.listener = DEBUG, A0, A1, A2

log4j.logger.x.y.z.e.w.service = DEBUG, A0, A1, A2

log4j.logger.x.y.z.e.w.util = DEBUG, A0, A1, A2

这一堆都是对Web系Log输出的控制,精确到了每一个package,没办法,我前面说过了,这个项目中对Web系package的划分是个垃圾的设计,因为他没有将Web系和Batch系的Source完全的分离开来, Web系的Source散落在package【w】下面,而RootLogger又被设定OFF,所以只能这样一个一个的设置了。

那么Web系的package改如何划分才对呢?很简单,只要在package【x.y.z.e.w】的下面再加入一层package,变为【x.y.z.e.w.web】就行了。

这样一来,Web系的package就全部在【x.y.z.e.w.web】的下面了,而Batch系的package已经在【x.y.z.e.w.batch】中了,上面那一堆对Web系Log的设置就可以改成这样了:

[plain] view
plaincopy

# system log

log4j.logger.x.y.z.e.w.web = DEBUG, A0, A1, A2

是不是简单多了!

好了,这篇文章就写到这里,希望能对童鞋们有所帮助。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息