2015-11-05 2 views
1

Я хочу добавить пользовательский обработчик для каждого регистратора для каждого класса моего проекта. У меня есть logging.properties файл, который читается в самом начале использования:add Handler to every Logger

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 
    } 
} 

файл регистрации читается без проблем, так как больше нет INFO или предупреждающие сообщения, не выводятся на консоль, только ТЯЖЕЛАЯ. Но мой пользовательский обработчик никогда не вызывается, поскольку окна с предупреждением никогда не открываются. Я также попытался добавить обработчик к глобальному регистратору, в надежде на любой другой регистратор унаследует его обработчики, но он не работает либо:

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

Добавление обработчика для конкретного регистратора работает как задумано: если ошибка бросается в любом месте класса, окно предупреждения открывается с помощью stacktrace.

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. Выберите нормальные значения по умолчанию, если не определены значения уровня, форматирования или фильтра.
  3. Сделка с JavaFX Application Threads Создание и отображение диалогового окна с помощью Platform.runLater.
  4. Звонок isLoggable в вашем методе публикации, чтобы определить, должен ли ваш обработчик публиковать или нет.
  5. Исключайте исключения во время выполнения внутри вашего метода публикации и отслеживайте их по телефону Handler.reportError.

Сделайте жизнь легкой и создайте модульные тесты, чтобы убедиться, что ваш обработчик действительно работает, прежде чем пытаться использовать его в дикой природе.

+0

Ну, когда я добавляю его вручную для определенного регистратора, он работает, скажем: Logger.getLogger («mySecondClass»). AddHandler (новый AlertHandler()); ... Если исключения исключены из этого класса, открывается окно предупреждения, поэтому я уверен, что обработчик работает! – user2336377

+0

Вы уверены, что обработчик работает, но javac говорит, что этот пример не компилируется.'ошибка: не удается найти символ a = new Alert (Alert.AlertType.ERROR); символ: переменная a. Мое мнение, похоже, не влияет на javac. Тестирование модулей действительно поможет вам. – jmehrens

+0

Ах, извините, что это была копия и вставка ошибки -.-. Сначала у меня было Alert как поле класса, а не локальная переменная ^^ Исправлено это в вопросе! – user2336377