Log4j将不同Package的日志输出到不同的文件
转自:http://www.crazyant.net/1931.html
随着项目规模的越来越大,会不断的引入新的模块,不同的模块都会打印自己的日志,最后就造成日志根本没法查看,比如我自己的项目中,就存在以下这些日志:
- 接收外界消息的日志、对外发送消息的日志;
- 后台常驻线程的处理日志;
- 外部接口访问的参数、返回结果等接口日志;
- Service访问数据库产生的SQL日志;
这其中,消息日志和后台线程的日志数据量非常庞大,如果所有日志打印在一个文件中,使用tail -f log.log文件,会发现日志在快速的滚动,根本无法查看甚至定位某一个具体的SQL或者Service访问日志。
解决方法就是可以将不同的日志加以分类输出,这样相互的日志不影响,尤其重要的接口访问日志,能够很方便的定位和排查问题。
步骤1:在log4j.properties中配置
先贴一下我自己所有的log4j.properties配置:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
log4j.rootLogger=INFO, console, file
log4j.appender.console=net.czt.log.AsyncConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d [%t] %-5p crazyant-web %-17c{2} (%13F:%L) %X{USER_ID}|%X{USER_IP}|%X{SERVER_ADDRESS}|%X{SERVER_NAME}|%X{REQUEST_URI}|%X{SESSION_ID} - %m%n
log4j.appender.console.bufferSize=10000
log4j.appender.console.encoding=UTF-8
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.file=/home/work/apache-tomcat-6.0.39/logs/crazyant.log
log4j.appender.file.MaxBackupIndex=5
log4j.appender.file.MaxFileSize=1GB
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%-5p] crazyant-web %d{yyyy-MM-dd HH:mm:ss,SSS} %X{USER_ID}|%X{USER_IP}|%X{SERVER_ADDRESS}|%X{SERVER_NAME}|%X{REQUEST_URI}|%X{SESSION_ID} method:%l%n%m%n
log4j.appender.file.bufferSize=10000
log4j.appender.file.encoding=UTF-8
log4j.logger.net.czt.crazyant.msg=DEBUG, message
log4j.additivity.net.czt.crazyant.msg=false
log4j.appender.message=org.apache.log4j.RollingFileAppender
log4j.appender.message.File=/home/work/apache-tomcat-6.0.39/logs/crazyant_message.log
log4j.appender.message.Append=true
log4j.appender.message.MaxFileSize=1GB
log4j.appender.message.MaxBackupIndex=5
log4j.appender.message.layout=org.apache.log4j.PatternLayout
log4j.appender.message.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%-5p][%c{1}] [%t] - %m%n
log4j.appender.message.encoding=UTF-8
log4j.logger.net.czt.crazyant.async.service=DEBUG, async
log4j.additivity.net.czt.crazyant.async.service=false
log4j.appender.async=org.apache.log4j.RollingFileAppender
log4j.appender.async.File=/home/work/apache-tomcat-6.0.39/logs/crazyant_async.log
log4j.appender.async.Append=true
log4j.appender.async.MaxFileSize=1GB
log4j.appender.async.MaxBackupIndex=5
log4j.appender.async.layout=org.apache.log4j.PatternLayout
log4j.appender.async.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%-5p][%c{1}] [%t] - %m%n
log4j.appender.async.encoding=UTF-8
log4j.logger.net.czt.orm.mybatis.SqlMonitorManager=DEBUG, showsql
log4j.additivity.net.czt.orm.mybatis.SqlMonitorManager=false
log4j.logger.net.czt.transaction.interceptor.SmartTransactionInterceptor=DEBUG, showsql
log4j.additivity.net.czt.transaction.interceptor.SmartTransactionInterceptor=false
log4j.appender.showsql=org.apache.log4j.RollingFileAppender
log4j.appender.showsql.File=/home/work/apache-tomcat-6.0.39/logs/crazyant_sql.log
log4j.appender.showsql.Append=true
log4j.appender.showsql.MaxFileSize=1GB
log4j.appender.showsql.MaxBackupIndex=5
log4j.appender.showsql.layout=org.apache.log4j.PatternLayout
log4j.appender.showsql.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%-5p][%c{1}] [%t] - %m%n
log4j.appender.showsql.encoding=UTF-8
log4j.logger.net.czt.crazyant.service=DEBUG, service
log4j.additivity.net.czt.crazyant.service=false
log4j.appender.service=org.apache.log4j.RollingFileAppender
log4j.appender.service.File=/home/work/apache-tomcat-6.0.39/logs/crazyant_service.log
log4j.appender.service.Append=true
log4j.appender.service.MaxFileSize=1GB
log4j.appender.service.MaxBackupIndex=5
log4j.appender.service.layout=org.apache.log4j.PatternLayout
log4j.appender.service.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%-5p][%c{1}] [%t] - %m%n
log4j.appender.service.encoding=UTF-8
|
在配置文件的下方,可以方便的看到,我将message(消息)、async(后端线程)、showsql(数据库日志)、service(接口调用)分别输出到了不同的日志文件。
其中的一些解释:
log4j.rootLogger=INFO, console, file
log4j有一个rootLogger和普通Logger的概念,默认情况下我们只需要一个rootLogger,就是所有的日志只会输出到这一个日志文件中。
看一下普通Logger的配置(以接口日志service为例):
- log4j.logger.net.czt.crazyant.service=DEBUG, service
- 这句中的”net.czt.crazyant.service”,表示该普通logger日志配置生效的package的完全路径
- 其中色service,表示该普通logger的名字
- log4j.additivity.net.czt.crazyant.service=false
- 其中的”net.czt.crazyant.service”,和上面的相同,表示该配置项针对的package
- 该句配置的意思,是不要将该package的日志输出到rootLogger日志中,只输出到自己配置的日志就行了;
- log4j.appender.service=org.apache.log4j.RollingFileAppender,以及该配置段下面的配置项
- 这里的”service”字符串,和上面的第一个配置项的”service”相同,表示对该普通Logger的配置;
- 下方的配置项和rootLogger相同,表示每天输出文件、编码UTF8、分片规则、每行的输出模式等等
我自己遇到的问题,是上面的log4j.properties配置好以后,发现各个日志文件创建了,但是里面都没有内容,这是为啥呢?来看下面第二个注意的地方;
步骤2、输出日志时需要设定日志对象对应的具体Class
什么意思呢?上面的配置项中,有一个”net.czt.crazyant.service”的package字符串,那么我们自己想一下,log4j是怎样将不同package中的logger日志输出到不同文件呢,想一下会有两种方法:
- 采用intercepter或者aop的方式,log4j自己检测日志输出,检测到日志产生于哪个package,就将其输出到对应文件中;
- 由用户传一个Class参数,log4j获取该Class对应的Package,以此为准,来定位不同的日志文件;
看一下代码,显然log4j用的是后一种简单直接的方式:
Java
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class MyClassImpl implements MyClass {
/**
* loger
*/
private static final Log logger = LogFactory.getLog(MyClassImpl.class);
/**
* my func
*/
public void myfunc() {
logger.info("call method myfunc.");
}
}
|
在logger = LogFactory.getLog(MyClassImpl.class)中,传入了使用该logger的Class参数,而该Class被反射取到的package地址,就是log4j用来输出日志的package地址。
这种做法也有强大的地方,方便逻辑上的日志归类,比如很多代码不属于一个package,但是它们逻辑上属于一起的,举个例子,消息的处理不只是接口调用Service这个package,可能还会调用发送msg的操作,如果想把msg的package中一些日志也输出到Service,那么在这个msg的logger初始化的时候,传入一个Serivice的Class就行了。
或者对于某一类的所有日志来说,它们所有的logger对象,都来自封装好的单个对象实例即可,而这个单个对象实例传入的参数只有一个,用于标识这个逻辑归类即可。
总结
在Log4j.properties中,支持package或者具体class的日志单独输出,但是也需要代码中logger初始化的时候,能和日志配置中的package对应上。
Log4j将不同Package的日志输出到不同的文件的更多相关文章
- Log4j将不同Package的日志输出到不同的文件的方法
随着项目规模的越来越大,会不断的引入新的模块,不同的模块都会打印自己的日志,最后就造成日志根本没法查看,比如我自己的项目中,就存在以下这些日志: 接收外界消息的日志.对外发送消息的日志: 后台常驻线程 ...
- Shell 命令行 从日志文件中根据将符合内容的日志输出到另一个文件
Shell 命令行 从日志文件中根据将符合内容的日志输出到另一个文件 前面我写了一篇博文Shell 从日志文件中选择时间段内的日志输出到另一个文件,利用循环实现了我想要实现的内容. 但是用这个脚本的同 ...
- Shell 从日志文件中选择时间段内的日志输出到另一个文件
Shell 从日志文件中选择时间段内的日志输出到另一个文件 情况是这样的,某系统的日志全部写在一个日志文件内,所以这个文件非常大,非常长,每次查阅的时候非常的不方便.所以,相关人员希望能够查询某个时间 ...
- log4j学习(二)不同类的日志输出到不同的文件
目的:一个应用中有两个不同作用的后台服务,我们需要把他们的日志分开,存放到2个不同的日志文件中. 办法:需要在log4j.properties文件中配置两个不同的logger和对应的appender ...
- docker日志输出文件大小设置以及文件个数限制
问题描述: 今天有同事运行了一个docker容器,不多时就导致宿主机硬盘直接撑爆,消耗了120G,发生的很是突然. 问题排查: 后续查阅资料,发现是因为docker中的某个进程一直在持续输出,而这些输 ...
- Log4j官方文档翻译(五、日志输出的方法)
日志类提供了很多方法用于处理日志活动,它不允许我们自己实例化一个logger,但是提供给我们两种静态方法获得logger对象: public static Logger getRootLogger() ...
- log4j将日志输出到控制台,文件,邮件
#将日志写到文件 log4j.appender.file=org.apache.log4j.DailyRollingFileAppender log4j.appender.file.File=e\:\ ...
- log4j2配置按照日志级别将日志输出到不同的文件
背景 在项目中,可能会产生非常多的日志记录,为了方便日志分析,可以将日志按级别输出到指定文件. log4j2.xml配置文件 <!--将info级别的日志单独输出到info.log中--> ...
- log4j 配置INFO 和DEBUG 分布输出至两个文件
博客地址: http://blog.csdn.net/wangchsh2008/article/details/8812857
随机推荐
- Python 提取Twitter tweets中的元素(包括text, screen names, hashtags)
CODE: #!/usr/bin/python # -*- coding: utf-8 -*- ''' Created on 2014-7-1 @author: guaguastd @name: ex ...
- iOS 带IAP提交注意事项及无法submit for review的解决方案
原地址:http://blog.sina.com.cn/s/blog_71ce775e0101dl4a.html 最近项目接触到了苹果的程序内购(IAP),碰到不少问题,参考了很多帖子才得以解决.在此 ...
- Oculus rift development kit 2使用手记(2014年10月到货)
昨天上午拿到后就立即拆包体验. 首先说下配置流程,其实很简单: 第一步是下载runtime,在没插dk2的时候安装好runtime. 第二步看着说明书(有图解)把硬件连接完毕.这里要说明的是dk2默认 ...
- NSDate相差8小时
NSDate *date = [NSDate date]; NSTimeZone *zone = [NSTimeZone systemTimeZone]; NSInteger interval = ...
- Android应用TranslateAnimation移动之后,利用视图的setLayoutPara
Android中利用TranslateAnimation移动时,不设置mTranslateAnimation.setFillAfter(true);,而利用视图的setLayoutParams来重新定 ...
- caffe 中如何打乱训练数据
第一: 可以选择在将数据转换成lmdb格式时进行打乱: 设置参数--shuffle=1:(表示打乱训练数据) 默认为0,表示忽略,不打乱. 打乱的目的有两个:防止出现过分有规律的数据,导致过拟合或者不 ...
- Java多线程——不可变对象
不可变对象条件 对象需要满足一下三个条件才是不可变对象: 1.对象创建以后其状态就不能修改 2.对象所有域都是final类型 3.对象是正确创建的(对象在创建期间,this引用没有溢出) 简而言之就是 ...
- Android应用APP脱壳笔记
[TOC] 天下游 模拟定位技术点简析 通过代码分析初步猜测模拟定位用到的几处技术点: 获取了Root权限 通过反射获取 android.os.ServiceManager 对应的函数 getServ ...
- OSI与TCP/IP你了解多少?
刚开始接触计算机的时候,非常好奇数据是怎样传输的,通过后期的学习逐步了解了计算机的通信原理.相信很多人在学习计算机的时候,首先入门的第一门课就是计算机的通信原理,而通信原理又离不开两大参考模型:OSI ...
- PILE读书笔记_基础知识
程序的构成 Linux下二进制可执行程序的格式一般为ELF格式. 我们可以用readelf命令来读取二进制的信息. ELF文件的主要内容就是由各个section及symbol表组成的. 下面来分别介绍 ...