2015-11-05 63 views
1

我想为我的项目的每个类的每个记录器添加一个自定义处理程序。我有一个logging.properties文件,这是在一开始就使用阅读:添加处理程序到每个记录器

try (InputStream in = ReportingService.class.getResourceAsStream("logging.properties")) { 
    LogManager.getLogManager().readConfiguration(in); 
} catch (IOException ex) { 
    Logger.getLogger(myClass.class.getName()).log(Level.SEVERE, null, ex); 
} 

logging.properties文件,如下所示:

handlers=java.util.logging.ConsoleHandler,myPackage.AlertHandler 
.level=SEVERE 
java.util.logging.ConsoleHandler.level=SEVERE 
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter 
myPackage.AlertHandler.level=SEVERE 
myPackage.AlertHandler.formatter=java.util.logging.SimpleFormatter 

而且myPackage.AlertHandler.java看起来是这样的:

package myPackage; 
import java.util.logging.Handler; 
import java.util.logging.LogRecord; 
import javafx.scene.control.Alert; 
public class AlertHandler extends Handler { 
    @Override 
    public void publish(LogRecord lr) { 
     Alert a = new Alert(Alert.AlertType.ERROR); 
     a.setTitle("Exception!"); 
     a.setHeaderText("Exception was thrown, here is the StackTrace:"); 
     a.setContentText(getFormatter().formatMessage(lr)); 
     Platform.runLater(()->{a.showAndWait();}); 
    } 
    @Override 
    public void flush() { 
     //no real handler is open, nothing to flush 
    } 
    @Override 
    public void close() throws SecurityException { 
     //no real handler is open, nothing to close 
    } 
} 

测井文件被读取,而不问题,因为没有更多信息或警告消息被打印到控制台,只有严重。但我的自定义处理程序永远不会被调用,因为没有警报窗口打开。我也尝试添加了处理全球记录,在所有其他记录的希望继承它的处理程序,但它不工作,要么:

Logger.getGlobal().addHandler(new AlertHandler()); 
Logger.getLogger("").addHandler(new AlertHandler()); 

添加处理程序,以一个特定的记录按预期工作:如果有错误被扔在课堂的任何地方,随着堆栈跟踪打开一个警告窗口。

Logger.getLogger("mySecondClass").addHandler(new AlertHandler()); 

但我想把这个处理程序添加到任何类的每个记录器!

回答

3

But I want to add this handler to EVERY logger in any class!

如果你想让这个处理程序看到所有的记录器输出,那么你只需要在根记录器上安装一个实例。例如,Logger.getLogger("").addHandler(new AlertHander());

默认情况下,子记录器将发布日志记录到parent handers

主要问题是您的代码将始终生成NullPointerException,因为您从未分配过与处理程序一起使用的格式程序。所以对getFormatter的调用将返回null,然后失败。

public static void main(String[] args) { 
    Handler h = new Handler() { 

     @Override 
     public void publish(LogRecord record) { 
     } 

     @Override 
     public void flush() { 
     } 

     @Override 
     public void close() throws SecurityException { 
     } 
    }; 
    System.out.println(h.getFormatter()); 
} 

您还需要:

  1. 添加代码来解析水平,格式化,并通过日志管理器为您处理程序分配的过滤器。
  2. 如果未定义级别,格式化程序或过滤器值,请选择sane默认值。
  3. 处理非JavaFX Application Threads创建并使用Platform.runLater显示对话框。
  4. 在您的发布方法中调用isLoggable来确定您的处理程序是否应该发布。
  5. 在发布方法内捕获运行时异常并通过调用Handler.reportError来跟踪它们。

让生活变得轻松,创建单元测试以确保您的处理程序在您试图在野外使用它之前实际工作。

+0

那么当我手动添加它到某个记录器它的工作,说: Logger.getLogger(“mySecondClass”)。addHandler(new AlertHandler()); ...当这个类中的任何地方抛出异常时,会打开一个警告窗口,所以我非常肯定Handler的工作原理! – user2336377

+0

您确定处理程序正常工作,但javac说这个示例不能编译。'错误:找不到符号 a =新的警报(Alert.AlertType.ERROR); 符号:变量a'我的意见似乎并没有影响到javac。单元测试将真正帮助你。 – jmehrens

+0

对不起,这是一个复制和粘贴错误-.-。起初,我把Alert作为一个类字段,而不是一个局部变量^^修正了这个问题! – user2336377

相关问题