我试图将日志从两个类(在com.project.callcontrol包中)重定向到同一个文件。 这就是我在两个类中启动记录器的方法 private static final Logger logger =
private static Logger log = Logger.getLogger(CCPurgeEvent.class.getName());
private static Logger log = Logger.getLogger(PurgeDeadCalls.class.getName());
这就是我尝试为这两个类共享同一个文件的方法,java.util.logging配置
com.project.callcontrol.PurgeDeadCalls.useParentHandlers = false
com.project.callcontrol.PurgeDeadCalls.handlers = com.project.logging.CcPurgeLogger
com.project.callcontrol.CCPurgeEvent.useParentHandlers = false
com.project.callcontrol.CCPurgeEvent.handlers = com.project.logging.CcPurgeLogger
com.project.logging.CcPurgeLogger.pattern=/var/log/voxcallcontrol-batches/cc_purge%u.log
com.project.logging.CcPurgeLogger.formatter = java.util.logging.SimpleFormatter
com.project.logging.CcPurgeLogger.level = FINEST
com.project.logging.CcPurgeLogger.limit=100000000
com.project.logging.CcPurgeLogger.count=10
请注意,CCPurgeLogger什么都不做,只是创建父类FileHandler的方法(甚至不知道它为什么存在) 我的问题是我无法从日志文件中的两个类中获取日志,我只能从一个类中获取日志,具体取决于配置文件中的配置顺序。 例如,如果我将CCPurgeEvent配置移到PurgeDeadCalls配置之上,它适用于CCPurgeEvent而不是PurgeDeadCalls,当我切换订单时会发生相反的情况。 我似乎无法理解我所缺少的东西,这方面的任何指示都会非常有用。
P.S:我无法更改我的日志框架,我知道log4j和其他框架提供了更多选项,但在当前工作范围内,我只需要使用java.util.logging。
答案 0 :(得分:1)
如果您希望共享两个记录器的一个日志文件,那么您已经在一个公共父记录器上安装了处理程序,并且您的代码必须获取并将该父记录器固定在内存中。第一个共同的父母是com.project.callcontrol
。
com.project.callcontrol.handlers = com.project.logging.CcPurgeLogger
com.project.callcontrol.PurgeDeadCalls.useParentHandlers = true
com.project.callcontrol.CCPurgeEvent.useParentHandlers = true
com.project.logging.CcPurgeLogger.pattern=/var/log/voxcallcontrol-batches/cc_purge%u.log
com.project.logging.CcPurgeLogger.formatter = java.util.logging.SimpleFormatter
com.project.logging.CcPurgeLogger.level = FINEST
com.project.logging.CcPurgeLogger.limit=100000000
com.project.logging.CcPurgeLogger.count=10
如果您想使用现有配置,则必须将com.project.logging.CcPurgeLogger
处理程序的实现更改为:
public class CcPurgeLogger extends Handler {
private static volatile Handler common;
private static long count;
private static void create() throws IOException {
synchronized (CcPurgeLogger.class) {
if (common == null) {
common = new FileHandler();
}
count++;
}
}
public CcPurgeLogger() throws IOException {
create();
}
@Override
public boolean isLoggable(LogRecord record) {
String name = record.getLoggerName();
return ("com.project.callcontrol.PurgeDeadCalls".equals(name)
|| "com.project.callcontrol.CCPurgeEvent".equals(name))
&& common.isLoggable(record);
}
@Override
public void publish(LogRecord record) {
common.publish(record);
}
@Override
public void flush() {
common.flush();
}
@Override
public void close() throws SecurityException {
synchronized (CcPurgeLogger.class) {
if (common != null) {
if (count == 1L) {
common.close();
common = null;
}
--count;
}
}
}
}
您是否也可以共享在配置文件中定义新子系统记录器的示例?
让我们根据它所做的事情(清除)来命名子系统,而不是命名它(某些类名)。
com.project.callcontrol.PURGE.handlers = com.project.logging.CcPurgeLogger
com.project.callcontrol.PURGE.useParentHandlers = true
com.project.logging.CcPurgeLogger.pattern=/var/log/voxcallcontrol-batches/cc_purge%u.log
com.project.logging.CcPurgeLogger.formatter = java.util.logging.SimpleFormatter
com.project.logging.CcPurgeLogger.level = FINEST
com.project.logging.CcPurgeLogger.limit=100000000
com.project.logging.CcPurgeLogger.count=10
然后在' PurgeDeadCalls'班级和CCPurgeEvent' class通过执行以下操作来获取子系统记录器。
private static Logger log = Logger.getLogger("com.project.callcontrol.PURGE");