有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

JUL日志处理程序中的java日志记录

我为JUL创建了一个新的日志处理程序,它扩展了java。util。登录中。处理程序

是否有任何标准化的方法来应对日志记录处理过程中出现的错误(如log4j中的LogLog)

仅使用JUL记录器会导致另一个日志记录,该记录必须由同一个处理程序处理

所以,我基本上是在寻找一种(标准的)方法来记录消息,而不创建无休止的循环。目前,我正在比较sourceClassName以防止这种循环


共 (2) 个答案

  1. # 1 楼答案

    处理程序内部发生的异常应使用Handler.reportError(String, Exception, int)报告。这会向安装的ErrorManager报告故障,ErrorManager可以自定义。使用它应该可以处理大多数无休止的循环

    然而,如果发布行为依赖于也生成日志记录的lib,那么您必须求助于检测循环。使用java.lang.ThreadLocal和某种枚举来跟踪状态更改

    public class HandlerReentrance extends Handler {
    
        private static final Level PUBLISH = Level.ALL;
        private static final Level REPORT = Level.OFF;
    
        private static final ThreadLocal<Level> LOCAL = new ThreadLocal<>();
    
        @Override
        public void publish(LogRecord record) {
            if (LOCAL.get() == null) {
                LOCAL.set(PUBLISH);
                try {
                    doPublish(record);
                } finally {
                    LOCAL.remove();
                }
            } else {
                final Level last = LOCAL.get();
                if (PUBLISH.equals(last)) {
                    LOCAL.set(REPORT);
                    try {
                        reportLoop(record);
                    } finally {
                        LOCAL.set(last);
                    }
                }
            }
        }
    
        private void doPublish(LogRecord record) {
            if (isLoggable(record)) {
               //Insert code.
            }
        }
    
        private void reportLoop(LogRecord record) {
            //Insert code.
        }
    
        @Override
        public void flush() {
        }
    
        @Override
        public void close() {
        }
    }
    
  2. # 2 楼答案

    目前,我将采用以下解决方案:

    public class MyHandler extends Handler {
      private final static String className = MyHandler.class.getName();
      private final static Logger logLogger = Logger.getLogger(className);
      ...
    
      @Override
      public void publish(LogRecord record) {
        if (!super.isLoggable(record)) {
          return;
        }
    
        String loggerName = record.getLoggerName(); //EDIT: Was getSourceClassName before
        if (loggerName != null && loggerName.equals(className)) {
          // This is our own log line; returning immediately to prevent endless loops
          return;
        }
    
        try {
          // ... do actual handling...
        } catch(Exception e) {
          logLogger.logp(level.SEVERE, className, "publish", "something went wrong", e);
        }
      }
    }