2009-06-25 18 views
40

Ho bisogno di scrivere una piccola applicazione di log analyzer per elaborare alcuni file di log generati da una libreria di terze parti chiusa (con logger personalizzato all'interno) utilizzata nel mio progetto.Stampa stack di chiamate completo su printStackTrace()?

In caso di una voce eccezione nel registro ho bisogno di raccogliere informazioni aggregate sui metodi coinvolti lungo la traccia dello stack dall'alto verso il luogo effettivo della deroga.

Sfortunatamente, per impostazione predefinita, Java printStackTrace() non stampa tutti i metodi nello stack di chiamate ma fino a un determinato numero e il resto viene semplicemente referenziato come 16 more....

Se potessi intercettare l'eccezione mi sarebbe usare il getStackTrace() e stamparlo me stesso, ma la causa principale non è mai incluso in salvo questa libreria getta.

C'è un modo per chiedere a Java per stampare l'intero stack di chiamate nel stacktrace?

A parte la mia situazione, i quadri di registrazione comuni hanno un'opzione per questo?

Modifica: Il programma viene eseguito su JVM di Sun con JDK 1.5.0_09. Nessuna opzione per cambiarlo.

+1

Eventuali duplicati di [Come faccio a smettere stacktraces truncating nei registri] (http://stackoverflow.com/questions/437756/how-do-i-stop-stacktraces-truncating-in-logs) –

risposta

28

here is an explanation del 'causata da' e '... n piu' linee nella traccia stampata. vedere anche lo JavaDoc for printStackTrace. potresti non avere alcun lavoro da fare.

Nota la presenza di righe contenenti i caratteri "...". Queste righe indicano che il resto dell'analisi dello stack per questa eccezione corrisponde al numero indicato di frame dal fondo della traccia dello stack dell'eccezione causata da questa eccezione (l'eccezione "che include"). Questa stenografia può ridurre notevolmente la lunghezza dell'output nel caso comune in cui un'eccezione avvolta viene generata dallo stesso metodo in cui viene rilevata l'eccezione causativa.

+0

Buon punto. Potrei aver frainteso il ... concetto come una semplice forma di separazione quando lo stack delle chiamate è troppo grande. Immagino che quando c'è un'eccezione senza root case gettato annidato 100 fotogrammi in profondità otterrei 100 righe nella stampa? – akarnokd

+0

lo spero, ma c'è un avviso nel JavaDoc per Throwable's getStackTrace(): "Alcune macchine virtuali possono, in alcune circostanze, omettere uno o più frame dello stack dallo stack trace." al centro di getOurStackTrace() ci sono due metodi nativi che controllano questo comportamento: getStackTraceDepth() e getStackTraceElement (int index) – akf

+0

Grazie. Potresti anche riflettere sulla seconda domanda? Potrebbe essere necessario analizzare il mio output log4j un giorno. Sarebbe molto più semplice avere una stampa completa e non preoccuparti di saltare avanti e indietro tra le cause e l'eccezione principale. – akarnokd

6

Non puoi fare qualcosa con Thread.currentThread().getStackTrace()?

Ecco una vera semplice esempio che chiama un metodo ricorsivo 20 volte e poi discariche fuori stack del thread corrente.

public class Test { 
    public static void main(String[] args) { 
     method(); 
    } 

    static int x = 0; 
    private static void method() { 
     if(x>20) { 
      StackTraceElement[] elements = Thread.currentThread().getStackTrace(); 

      for(int i=0; i<elements.length; i++) { 
       System.out.println(elements[i]); 
      } 
     } 
     else { 
      x++; 
      method(); 
     } 
    } 
} 
+4

Citazione: "Se potessi prendere l'eccezione io stesso userei getStackTrace() e stamparlo da solo" – akarnokd

+0

Quindi non sei in alcun modo in controllo del codice in ogni caso? Stai semplicemente guardando i file di registro? Rileggo di nuovo la tua domanda, immagino di no. Scuse! Lascerò il codice sorgente pubblicato anche se qualcuno lo trova utile. –

+0

È una libreria di terze parti per alcune operazioni legacy. Non posso nemmeno JAD senza errori. Sulla base della risposta di akf, potrei aver semplicemente interpretato erroneamente il formato di stampa dello stacktrace. Raramente ho il compito di analizzare uno stacktrace a livello di codice. – akarnokd

0

Può essere che si può provare a iterare la matrice restituita da:

Thread.currentThread().getStackTrace(); 
+6

Citazione: "Se potessi rilevare l'eccezione io stesso userei getStackTrace() e stamperò me stesso" – akarnokd

+0

Il metodo getStackTrace() sull'oggetto Thread dovrebbe restituire il traccia dello stack completa del thread corrente, non è vero? Se l'eccezione di root è stata generata nello stesso thread, dovrebbe funzionare? Potrebbe essere mi manca qualcosa ..? –

+1

Si verifica un'eccezione all'interno della libreria. Registra questa traccia dello stack di eccezioni nel suo file di registro, quindi crea un'istanza della propria eccezione (chiamala LibException) contenente il messaggio della causa principale (LibException: FileNotFoundException ...) ma non assegna la causa principale. Molto probabilmente la libreria è scritta per Java 1.2 dove non esisteva un costruttore con il parametro root cause e il metodo initCause() è attivo da 1.4. – akarnokd

Problemi correlati