前言
随着项目规模的越来越大,会不断的引入新的模块,不同的模块都会打印自己的日志,最后就造成日志根本没法查看,比如我自己的项目中,就存在以下这些日志:
接收外界消息的日志、对外发送消息的日志;
后台常驻线程的处理日志;
外部接口访问的参数、返回结果等接口日志;
Service访问数据库产生的SQL日志;
这其中,消息日志和后台线程的日志数据量非常庞大,如果所有日志打印在一个文件中,使用tail -f log.log文件,会发现日志在快速的滚动,根本无法查看甚至定位某一个具体的SQL或者Service访问日志。
解决方法就是可以将不同的日志加以分类输出,这样相互的日志不影响,尤其重要的接口访问日志,能够很方便的定位和排查问题。
步骤1:在log4j.properties中配置
先贴一下我自己所有的log4j.properties配置:
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为例):
1、log4j.logger.net.czt.crazyant.service=DEBUG, service
这句中的”net.czt.crazyant.service”,表示该普通logger日志配置生效的package的完全路径
其中色service,表示该普通logger的名字
2、log4j.additivity.net.czt.crazyant.service=false
其中的”net.czt.crazyant.service”,和上面的相同,表示该配置项针对的package
该句配置的意思,是不要将该package的日志输出到rootLogger日志中,只输出到自己配置的日志就行了;
3、log4j.appender.service=org.apache.log4j.RollingFileAppender,以及该配置段下面的配置项
这里的”service”字符串,和上面的第一个配置项的”service”相同,表示对该普通Logger的配置;
下方的配置项和rootLogger相同,表示每天输出文件、编码UTF8、分片规则、每行的输出模式等等
我自己遇到的问题,是上面的log4j.properties配置好以后,发现各个日志文件创建了,但是里面都没有内容,这是为啥呢?来看下面第二个注意的地方;
步骤2、输出日志时需要设定日志对象对应的具体Class
什么意思呢?上面的配置项中,有一个”net.czt.crazyant.service”的package字符串,那么我们自己想一下,log4j是怎样将不同package中的logger日志输出到不同文件呢,想一下会有两种方法:
1、采用intercepter或者aop的方式,log4j自己检测日志输出,检测到日志产生于哪个package,就将其输出到对应文件中;
2、由用户传一个Class参数,log4j获取该Class对应的Package,以此为准,来定位不同的日志文件;
看一下代码,显然log4j用的是后一种简单直接的方式:
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的日志输出到不同文件的方法相关文章请关注PHP中文网!

本文分析了2025年的前四个JavaScript框架(React,Angular,Vue,Susve),比较了它们的性能,可伸缩性和未来前景。 尽管由于强大的社区和生态系统,所有这些都保持占主导地位,但它们的相对人口

本文讨论了使用咖啡因和Guava缓存在Java中实施多层缓存以提高应用程序性能。它涵盖设置,集成和绩效优势,以及配置和驱逐政策管理最佳PRA

Node.js 20通过V8发动机改进可显着提高性能,特别是更快的垃圾收集和I/O。 新功能包括更好的WebSembly支持和精制的调试工具,提高开发人员的生产率和应用速度。

Java的类上载涉及使用带有引导,扩展程序和应用程序类负载器的分层系统加载,链接和初始化类。父代授权模型确保首先加载核心类别,从而影响自定义类LOA

本文介绍了SnakeyAml中的CVE-2022-1471漏洞,这是一个允许远程代码执行的关键缺陷。 它详细介绍了如何升级春季启动应用程序到Snakeyaml 1.33或更高版本的降低风险,强调了依赖性更新

本文讨论了使用JPA进行对象相关映射,并具有高级功能,例如缓存和懒惰加载。它涵盖了设置,实体映射和优化性能的最佳实践,同时突出潜在的陷阱。[159个字符]

本文使用lambda表达式,流API,方法参考和可选探索将功能编程集成到Java中。 它突出显示了通过简洁性和不变性改善代码可读性和可维护性等好处


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

禅工作室 13.0.1
功能强大的PHP集成开发环境

SublimeText3汉化版
中文版,非常好用

SublimeText3 Linux新版
SublimeText3 Linux最新版

记事本++7.3.1
好用且免费的代码编辑器

Dreamweaver CS6
视觉化网页开发工具