2013-09-20 2 views
6

Я работаю с каркасом Vaadin, и он плохо поддерживает перехват событий, и я не могу знать, когда активируется сеанс или пользовательский интерфейс, поэтому я не могу поместить их идентификаторы в MDC.Logback MDC put() измененный объект

Обычно я бы:

public void onSessionBegin(){ 
    MDC.put("session", VaadinSession.getCurrent().toString()); //<-- String is immutable 
} 
public void onSessionEnd(){ 
    MDC.remove("session"); 
} 

Но у меня нет таких событий, поэтому я хотел бы, чтобы:

// in the servlet init or wherever 
MDC.put("session", new Object(){ 
     public String toString() { 
      VaadinSession.getCurrent().toString() 
     }; 
    }); //<-- This is mutable and will be evaluated each time 

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

Возможно ли это? Как заменить логическую реализацию MDC на обычную? Должен ли я редактировать источники slf4j и logback?

ответ

3

Вы не хотите извлекать текущий сеанс из локальной переменной потока для каждой строки ведения журнала (что и делает VaadinSession.getCurrent()). API использует статический тип String, поскольку он является самым быстрым.

У Vaadin на самом деле есть SessionInitListener и SessionDestroyListener, но это также не то, что вы хотите: MDC - это поток локальный, но не все запросы в пределах одного сеанса обрабатываются в пределах одного потока. Таким образом, вы должны установить значение в MDC по каждому запросу в реализации RequestHandler. Я не думаю, что у Vaadin есть интерфейс обратного вызова для завершения запроса, поэтому, похоже, нет хорошего места для очистки значения.

UPDATE: после этого ответ поступил, я узнал, что есть на самом деле лучший способ установить и очистить значение, так что если сервер перерабатывает потоки для различных сессий, он не содержит ложную информацию. Что вы должны сделать, это подкласс VaadinServlet или VaadinPortlet и переопределить createServletService(), чтобы вернуть пользовательский подкласс VaadinServletService или VaadinPortletService, который, в свою очередь, переопределяет как requestStart(), так и requestEnd() соответственно для установки и удаления значений в MDC.

Смежные вопросы