Log4j实战

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的了解为零(其实他也懂一点,但是他命令我把他当做傻瓜来看,这让我很为难,但我必须服从命令^_^)

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

三.实现

#--------------------------------------------------------------------  
#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行 

log4j.rootLogger = OFF

为什么将根Log关闭了呢? 因为所有的logger都会自动继承RootLogger,客户要求除Struts和Hibernate外的其他第三方OpenSource输出的Log,一律不准输出。
项目中使用了大量的其他第三方的OpenSource,RootLogger设定为OFF,所有使用Log4j的OpenSource都会自动继承RootLogger,被设定OFF。

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

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

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

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

当然还有下面两个Log:

#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设置的关系

# 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的设置就可以改成这样了:

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

是不是简单多了!

好了,这篇文章就写到这里,希望能对童鞋们有所帮助。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
log4j.rootLogger=INFO,CONSOLE log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender INFO是日志记录的最低等级,必须写,它和比它高的等级会进入日志,如WARN、ERROR、FATAL、OFF。 关于8个日志等级,参考:https://blog.csdn.net/haoranhaoshi/article/details/89929470下半部分。 CONSOLE是appenderName,随便写,只要一致即可,换成A也行。 log4j推荐和slf4j一起用,关于log4j和slf4j, 参考:https://blog.csdn.net/haoranhaoshi/article/details/89929470上半部分。 log4j.appender.File.File=${user.dir}/logs/hmiservice.log ${user.dir}可以得到当前程序目录,关于${}里面可以使用的内容, 参考:https://blog.csdn.net/haoranhaoshi/article/details/93532273 写绝对路径也可以,但不推荐:log4j.appender.A.File=E:/Program/log/logs/info.log DailyRollingFileAppender支持按每月、周、日、时、分创建日志文件。 当前日志放在log4j.appender.File.File=${user.dir}/logs/hmiservice.log对应的命名文件中, 过了时间将原日志文件命名为原文件名后加上log4j.appender.File.DatePattern='.'yyyy-MM-dd-HH对应格式的日期, 注意不能用:和_。 关于DailyRollingFileAppender的使用,参考:https://www.cnblogs.com/zengdingxin/p/5135008.html log4j.appender.File=MyDailyRollingFileAppender MyDailyRollingFileAppender是自定义的类,需写包括包名的全路径,如果就在src-main-java下,写类名就行。 此类可以使log4j.appender.File.maxBackupIndex=12有效,DailyRollingFileAppender本身不支持创建日志文件的上限, 即不会清理过期日志文件。 log4j.appender.File.layout.ConversionPattern=%d{yyy MMM dd HH:mm:ss,SSS} %p %m%n 更多输出控制格式,参考:https://blog.csdn.net/reserved_person/article/details/52849505上半部分 log4j.appender.File.layout=org.apache.log4j.HTMLLayout 网页形式的日志文件,参考:https://blog.csdn.net/jQuerys/article/details/49909931 日志研发的方向: 日志内容 日志格式 多长时间、多大日志生成一个文件 多长时间、多大日志生成一个文件夹 多长时间、多大日志删除一个文件 多长时间、多大日志删除一个文件夹 日志等级是否分开存储 不同服务的日志是否分开存储 存储方式:后台打印、文件、数据库、邮件等,参考:https://blog.csdn.net/reserved_person/article/details/52849505下半部分 推荐的依赖组合: <dependency> <groupId>apache-log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>slf4j</groupId> <artifactId>api</artifactId> <version>1.6.6</version> </dependency> <dependency> <groupId>slf4j</groupId> <artifactId>log4j12</artifactId> <version>1.7.5</version> </dependency> 如果使用的是阿里的Maven仓库,最新的日志依赖可能没有,可以把这些依赖从官网下载后安装到本地。 本实战示例中在libs下有这些依赖。 执行以下命令,注意把Jar包路径改一下: mvn install:install-file -Dfile=C:\Users\hao\Desktop\log4j-1.2.17.jar -DgroupId=apache-log4j -DartifactId=log4j -Dversion=1.2.17 -Dpackaging=jar mvn install:install-file -Dfile=C:\Users\hao\Desktop\slf4j-api-1.6.6.jar -DgroupId=slf4j -DartifactId=api -Dversion=1.6.6 -Dpackaging=jar mvn install:install-file -Dfile=C:\Users\hao\Desktop\slf4j-log4j12-1.7.5.jar -DgroupId=slf4j -DartifactId=log4j12 -Dversion=1.7.5 -Dpackaging=jar
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值