log4j 扩展多配置文件共存

本文介绍了一种在Java应用中使用Log4j进行多配置文件日志记录的方法。通过扩展LoggerRepository并创建BizLog4jManager和服务类,实现了不同业务模块使用独立的日志配置。文章还提供了测试代码及配置示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天突然要用到记录运营平台的操作日志记录,以前也没有好好考虑过,一般都是系统级的直接修改jboss容器的log4j配置文件。业务级的都是自己手写类记录到数据库。这次特殊情况,综合考虑决定以log文件把业务日志记录到硬盘上。这个以前还没有用过。想自己写一个类记录,还是觉得现成的拿来用比较好,就还是用log4j记录吧。搭了环境,做了测试,性能和并发应该都不是问题。可以忽然发现,自己如果用log4j配置业务日志,就会和jboss系统自己配的起冲突,具体的没有测,不是你覆盖我的就是我覆盖你的。考虑到想以后对不同业务组用不同的配置文件配置,所以必须得解决多配置文件共存的问题。就开始上网查,有的是扩展LoggerFactory,扩展Logger,有的是手动setProperties.都试了一试,还真没有符合我要求的。
最后准备用simple log或者alj,还是把log4j1.2.16源码download读了一下,没有看结构图。听说很复杂,就没有细致研究。我主要关心初始化和配置文件存储方面。发现主要用到了Logger,LogManager,LoggerRepository,Hierarchy。logManger做了一个RepositorySelector提供扩展,说明上说
For example, when tomcat starts it will be able to install its
own repository selector. However, if and when Tomcat is embedded
within JBoss, then JBoss will install its own repository selector
and Tomcat will use the repository selector set by its container,
JBoss.
大意就是tomcat用自己的respostitory,jboss用自己的respository。没有读过tomcat源码,感觉使用RepositorySelector挺复杂的,因为Hierarchy是Repository的一个实现,所以中心思想就是每个业务模块就是一个Hierarchy.

代码最核心的地方就是
Logger rootLogger = new RootLogger(Level.ALL);
LoggerRepository loggerRepository = new Hierarchy(rootLogger);
PropertyConfigurator().doConfigure(path, loggerRepository); //path是你配置文件的路径

getLogger的时候就 return loggerRepository.getLogger(name);
我为了用的方便扩展了两个类 BizLog4jManager,Bizlog4jService,一个测试类TestBizLog4j

BizLog4jManager


package org.targtime.log;

import java.net.URL;
import java.util.Hashtable;

import org.apache.log4j.Logger;
import org.apache.log4j.spi.LoggerRepository;


/**
* @comment 有点类似于log4j的LogManager,本来想改改LogManger的,觉得没有必要,够用就好。
* 简化了LoggerRepositorySelect和适配,多出来两个hashtable为了缓存service。
* 这个类很简单,不多说。
* @author Neil
*
*/
public class BizLog4jManager {
static Hashtable<String,Bizlog4jService> htStr = new Hashtable<String,Bizlog4jService>();
static Hashtable<URL,Bizlog4jService> htURL = new Hashtable<URL,Bizlog4jService>();
static LoggerRepository lr;


private static Bizlog4jService getService(String path){
if(!htStr.containsKey(path)){
htStr.put(path, new Bizlog4jService(path));
}
return (Bizlog4jService)htStr.get(path);

}

private static Bizlog4jService getService(URL pathU){
if(!htURL.containsKey(pathU)){
htURL.put(pathU, new Bizlog4jService(pathU));
}
return (Bizlog4jService)htURL.get(pathU);

}

public static Logger getLogger(String path,String name){
return getService(path).getLogger(name);
}
public static Logger getLogger(URL pathU,String name){
return getService(pathU).getLogger(name);
}

}


Bizlog4jService


package org.targtime.log;

import java.net.URL;

import org.apache.log4j.Hierarchy;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.spi.LoggerRepository;
import org.apache.log4j.spi.RootLogger;
/**
* @comment 这个类的关键就是初始化的时候那几个方法实现了和公用的PropertyCongifurator的隔离
* @author Neil
*
*/
public class Bizlog4jService {
static Logger rootLogger;
static LoggerRepository loggerRepository;

public Bizlog4jService(String path) {
initEvn();
new PropertyConfigurator().doConfigure(path, loggerRepository);
}

public Bizlog4jService(URL pathU) {
initEvn();
new PropertyConfigurator().doConfigure(pathU, loggerRepository);
}

/**
* 初始化这个service自己的RootLogger和一个Hierarchy.
*/
private void initEvn() {
rootLogger = new RootLogger(Level.ALL);
loggerRepository = new Hierarchy(rootLogger);

}

public Logger getLogger(String name) {
return loggerRepository.getLogger(name);
}

}


TestBizLog4j


import java.net.URL;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.targtime.log.BizLog4jManager;

public class TestBizLog4j {
public static void main(String[] args) {

//定义3个logger
Logger log1; //通用 log4j logger1
Logger log2; //业务 log4j logger2
Logger log3; //业务 log4j logger2


//取得3个logger配置文件路径
URL pathU1 = BizLog4jManager.class.getResource("Log4j.properties");
URL pathU2 = BizLog4jManager.class.getResource("T2Log4j.properties");
URL pathU3 = BizLog4jManager.class.getResource("T3Log4j.properties");

//配置logger1,像所有log4j教程那样
PropertyConfigurator.configure(pathU1);
log1 = Logger.getLogger("org.tt.neil1");
log1.error("I'm common logger1 test ");

//得到第二个业务需要用的logger2,注意每次获得比普通log4j多了一个path|pathU,为了使用多个业务模块不同配置情况
//然后debug输出,输出到哪了,看T2Log4j.properties文件.
log2 = BizLog4jManager.getLogger(pathU2, "org.tt.neil2");
log2.debug("I'm biz logger2 test ");

//不废话
log3 = BizLog4jManager.getLogger(pathU3, "org.tt.neil3");
log3.debug("I'm biz logger3 test ");


//做完3组logger 打印,再做一组logger1的写入,为了证明logger2,logger3初始化并没有影响和覆盖log1的通用配置
for (int i = 0; i < 20000; i++) {
log1.info("common logger1 test after biz logger2,3");
log1.error("common logger1 test after biz logger2,3");
}

}
}



Log4j.properties


log4j.category.org.zblog=INFO,A3
log4j.appender.A3=org.apache.log4j.RollingFileAppender
log4j.appender.A3.File=C:/my.log
log4j.appender.A3.MaxFileSize=20MB
log4j.appender.A3.MaxBackupIndex=100
log4j.appender.A3.layout=org.apache.log4j.PatternLayout
log4j.appender.A3.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n


T2Log4j.properties

log4j.rootCategory=DEBUG,A3
log4j.appender.A3=org.apache.log4j.RollingFileAppender
log4j.appender.A3.File=C:/my2.log
log4j.appender.A3.MaxFileSize=20MB
log4j.appender.A3.MaxBackupIndex=100
log4j.appender.A3.layout=org.apache.log4j.PatternLayout
log4j.appender.A3.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n

T3Log4j.properties


log4j.rootCategory=DEBUG,A3
log4j.appender.A3=org.apache.log4j.RollingFileAppender
log4j.appender.A3.File=C:/my3.log
log4j.appender.A3.MaxFileSize=20MB
log4j.appender.A3.MaxBackupIndex=100
log4j.appender.A3.layout=org.apache.log4j.PatternLayout
log4j.appender.A3.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n


就这么多内容,没有写很详细,就是随笔,也没有测试性能,有问题自己可以改改
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值