it-swarm.com.de

So erhalten Sie den Java Call Stack einer laufenden Anwendung

Ich arbeite an einer sehr großen webbasierten Java-Anwendung. Da es während der Entwicklung keine ordnungsgemäße Protokollierung gibt, ist es für mich sehr schwierig, einen Haltepunkt zu setzen und die App zu debuggen, da ich die Ausführungsreihenfolge nicht kenne. Gibt es irgendeinen Mechanismus, um einen vollständigen Aufrufstapel der laufenden Java-Anwendung zu erhalten, nachdem ich einige Aktionen ausgeführt habe?.

Ich habe lange im Netz gesucht, kann aber keine konkrete Lösung finden. Bitte schlagen Sie mir vor, ob etwas dafür vorhanden ist. Vielen Dank

14
sns

Methode 1: Verwenden Sie das Dienstprogramm jstack über die Befehlszeile (Teil der JDK-Distribution).

Methode 2: Senden Sie das Signal 3 an den Java-Prozess. Es gibt Stack-Traces auf stdout aus.

Methode 3: Rufen Sie Thread.getAllStackTraces () in der Anwendung auf:

public class StackTraceDumper
{
    public static dumpAllStackTraces ()
    {
        for (Map.Entry <Thread, StackTraceElement []> entry: 
            Thread.getAllStackTraces().entrySet ())
        {
            System.out.println (entry.getKey ().getName () + ":");
            for (StackTraceElement element: entry.getValue ())
                System.out.println ("\t" + element);
        }
    }
}

Verwenden Sie dann StackTraceDumper.dumpAllStackTraces(), wenn Sie Stack-Traces sichern möchten.

18

Thread.dumpStack() Druckt eine Stapelablaufverfolgung des aktuellen Threads in den Standardfehlerstrom. Thread.getAllStackTraces() Gibt eine Karte mit Stack-Traces für alle Live-Threads zurück. Thread.getStackTrace() Gibt ein Array von Stack-Trace-Elementen zurück, die den Stack-Dump dieses Threads darstellen.

6
Dewfy

Schauen Sie sich Throwable.getStackTrace() an. Erstellen Sie einfach einen neuen Throwablename__; Sie müssen es nicht unbedingt throwname__.

5
Graham Borland

Sie können einen Stapelspeicherauszug auslösen, indem Sie Strg + Pause drücken oder ein Signal 3 senden (auf Unix-basierten Systemen). Beachten Sie, dass Sie eine Stapelablaufverfolgung pro Thread erhalten. Dies geht zu Standardfehler , stellen Sie also sicher, dass Ihre Protokollierung dies erfasst.

Sie können dies programmgesteuert über tun

Map<Thread, StackTraceElement[]> m = Thread.getAllStackTraces();

Hier ist weitere Informationen zum Abrufen und Analysieren von Stack-Traces.

Wie Sie bereits bemerkt haben, ist BTrace eine weitere Möglichkeit. Hier ist eine SO Antwort zur Verwendung.

3
Brian Agnew

Es gibt einige Möglichkeiten:

  • Führen Sie es in einem Debugger aus und halten Sie alle Threads an. Anschließend können Sie sie überprüfen
  • Verwenden Sie VisualVM, um eine Verbindung zu den laufenden Prozessen herzustellen und einen Thread-Dump auszulösen. Es kommt mit dem JDK.
  • Verwenden Sie jstack in der Befehlszeile, um Threads zu sichern.

Fügen Sie Ihrem Code einige grundlegende Protokollierungen hinzu:

new RuntimeException().printStackTrace();

Dadurch wird eine statische Spur zu stderr erstellt

0
David Roussel

Warum verwenden Sie kein AOP-Tool wie AspectJ, um diese Werte zu erfassen und zu protokollieren? Sie können execution () point cut zusammen mit after () advice verwenden. Bei Nichtproduktionsbereitstellungen können Sie alle Methodenaufrufe zusammen mit den übergebenen Werten und dem zurückgegebenen Wert protokollieren. Dies ist zu viel Aufwand für die Produktionsumgebung. Dazu können Sie die übergebenen Werte (Object args [] wie in AspectJ advice angegeben) in einer lokalen Variablen speichern und nur im Ausnahmefall protokollieren. Aber selbst in diesem Fall wird es einige Performance-Einbußen geben, da primitive Werte als Object [] an Ihren Rat übergeben werden.

0
Amol U