2016-04-02 12 views
1

Ich möchte die Thread-ID als Teil meiner Protokollnachricht mit log4j2 Async-Protokollierung protokollieren.Die beste Methode zum Übergeben von threadId in log4j2 AsyncLogger

Mit log4j2 2.4.1 war dies über eine benutzerdefinierte AsyncLogger möglich, die die logMessage-Methode überschreibt.

public class ThreadIdAsyncLogger extends AsyncLogger { 
    private static final long serialVersionUID = 1L; 

    private static final ThreadLocal<Boolean> THREAD_CONTEXT_SETUP = new ThreadLocal<Boolean>() { 
     @Override 
     protected Boolean initialValue() { 
      return false; 
     } 
    }; 

    public ThreadIdAsyncLogger(final LoggerContext context, final String name, final MessageFactory messageFactory) { 
     super(context, name, messageFactory); 
    } 

    @Override 
    public void logMessage(final String fqcn, 
          final Level level, 
          final Marker marker, 
          final Message message, 
          final Throwable thrown) { 
     if (!THREAD_CONTEXT_SETUP.get()) { 
      // it is enough to set it once per thread 
      ThreadContext.put(Constants.ContextMapKeys.THREAD_ID, String.valueOf(Thread.currentThread().getId())); 
      THREAD_CONTEXT_SETUP.set(true); 
     } 

     super.logMessage(fqcn, level, marker, message, thrown); 
    } 
} 

Ich habe gerade versucht 2.5.0 auf die Version zu aktualisieren und ich nicht jetzt meinen eigenen AsyncLogger mehr schaffen scheinen zu können, weil das AsyncLoggerDisruptor Paket privat ist. Ich weiß, ich könnte Reflexion verwenden, aber ich denke, es gibt einen besseren Weg dafür.

Was wäre die beste Praxis (Design und Leistung) für die gleiche Funktionalität?

Antwort

2

Es wird daran gearbeitet, für diese: https://issues.apache.org/jira/browse/LOG4J2-1270

Inzwischen können Sie die Thread Karte oder Stapel Methoden verwenden, um dies zu erreichen. Leistungsmäßig ist der ThreadLocal-Stack etwas günstiger als die Map, denke ich.

+0

an welcher Stelle im Code sollte ich die threadId auf dem Stapel schieben? Ich möchte das an einmal im Logger machen und nicht vor jedem Logger-Aufruf im App-Code. Was schlägst du hier vor? Soll ich warten (bleiben Sie bei 2.4.1), bis das Ticket, das Sie erwähnten, resoviert wird? – leozilla

+0

Normalerweise gibt es einen einzigen Einstiegspunkt, an dem Ihre Anwendung einen Rückruf vom Framework erhält, das das Threading-Modell bereitstellt. Wenn Ihre Anwendung einige Aufgaben in einem Thread-Pool ist, wäre dies die run() -Methode der Runnable oder die call() -Methode der Callable. Für Servlets ist es eine der Methoden service() oder doXxx(). Andere Frameworks haben andere Callbacks, aber im Allgemeinen sind diese Einstiegspunkte der ideale Kandidat, um die Thread-ID zu pushen (und nach dem Code zu öffnen). –

+0

ok ich verstehe. Leider kann ich das nur für den Code, den ich kontrolliere, und nicht für einige "Middleware" -Threads. Wenn ich mir den log4j async logger code anschaue, sehe ich, dass du bereits die threadid erhalten musst, vielleicht wäre es möglich, sie mit dem LogEvent weiterzugeben, wenn du es sowieso hast. Ich werde über eine Lösung nachdenken .. – leozilla

Verwandte Themen