java.util.logging无法在两个类之间共享记录器

时间:2016-07-18 16:34:37

标签: java java.util.logging

我试图将日志从两个类(在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。

1 个答案:

答案 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");