2009-06-25 23 views
40

Necesito escribir una pequeña aplicación analizadora de registros para procesar algunos archivos de registro generados por una biblioteca de fuente cerrada de terceros (que tiene un registro interno personalizado) utilizado en mi proyecto.Imprimir pila de llamadas completa en printStackTrace()?

En el caso de una entrada de excepción en el registro, necesito recopilar información agregada sobre los métodos implicados a lo largo de la traza de la pila desde la parte superior hasta el lugar real de la excepción.

Desafortunadamente, de forma predeterminada Java printStackTrace() no imprime todos los métodos en la pila de llamadas pero hasta cierto número y el resto simplemente se hace referencia como 16 more....

Si pudiera detectar la excepción, usaría getStackTrace() e imprimiría yo mismo, pero la causa raíz nunca se incluye en la excepción que arroja esta biblioteca.

¿Hay alguna manera de pedirle a Java que imprima toda la pila de llamadas en stacktrace?

Aparte de mi situación, ¿los marcos de registro comunes tienen opción para esto?

Editar: El programa se ejecuta en la JVM de Sun con JDK 1.5.0_09. No hay opción para cambiar eso.

+1

duplicado posible de [¿Cómo paro stacktraces truncar en los registros] (http://stackoverflow.com/questions/437756/how-do-i-stop-stacktraces-truncating-in-logs) –

Respuesta

28

here is an explanation de la 'causado por' y '... n más' líneas en la huella impresa. ver también el JavaDoc for printStackTrace. es posible que no tengas trabajo que hacer.

Tenga en cuenta la presencia de líneas que contienen los caracteres "...". Estas líneas indican que el resto del seguimiento de la pila para esta excepción coincide con el número indicado de fotogramas de la parte inferior del seguimiento de la pila de la excepción causada por esta excepción (la excepción "adjuntando"). Esta taquigrafía puede reducir en gran medida la longitud de la salida en el caso común donde se arroja una excepción envuelta desde el mismo método que la "excepción causativa".

+0

Buen punto. Podría haber malinterpretado la ... noción como una forma de soleridad simple cuando la cantidad de llamadas es demasiado grande. Supongo que cuando hay una excepción sin rootcase lanzado a 100 cuadros de profundidad, ¿obtendría esas 100 líneas en la impresión? – akarnokd

+0

, espero que sí, pero hay una advertencia en el JavaDoc para el getStackTrace() de Throwable: "Algunas máquinas virtuales pueden, en algunas circunstancias, omitir uno o más marcos de pila del rastro de la pila". en el corazón de getOurStackTrace() hay dos métodos nativos que controlan este comportamiento: getStackTraceDepth() y getStackTraceElement (índice int) – akf

+0

Gracias. ¿Podrías también reflexionar sobre la segunda pregunta? Puede que necesite analizar mi propia salida log4j algún día. Sería mucho más simple tener una impresión completa y no preocuparse por ir y venir entre las causas y la excepción principal. – akarnokd

6

¿No puedes hacer algo con Thread.currentThread().getStackTrace()?

Aquí hay un ejemplo realmente simple que llama a un método recursivamente 20 veces y luego volca la pila del hilo actual.

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

Cita: "Si pudiera detectar la excepción yo mismo, usaría getStackTrace() e imprimiría yo mismo" – akarnokd

+0

¿De todos modos no tiene el control del código? ¿Simplemente está mirando archivos de registro? Vuelve a leer tu pregunta, supongo que no. Disculpas! Aunque dejaré el código fuente publicado, en caso de que alguien lo encuentre útil. –

+0

Es una biblioteca de terceros para algunas operaciones heredadas. Ni siquiera puedo JAD sin errores. Basado en la respuesta de akf, podría haber malinterpretado el formato de impresión de la pila. Raramente tengo la tarea de analizar un stacktrace mediante programación. – akarnokd

0

Puede ser que usted puede tratar de iterar sobre la matriz devuelta por:

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

Cita: "Si pudiera detectar la excepción, usaría getStackTrace() e imprimiría yo mismo" – akarnokd

+0

El método getStackTrace() en el objeto Thread debería devolver el completar el seguimiento de la pila del hilo actual, ¿no? Si la excepción de raíz se lanzó en el mismo subproceso debería funcionar? ¿Puede ser que me esté perdiendo algo ...? –

+1

Existe una excepción dentro de la biblioteca. Registra esta traza de la pila de excepción en su archivo de registro y luego ejemplifica su propia excepción (llámalo LibException) que contiene el mensaje de la causa raíz (LibException: FileNotFoundException ...) pero no asigna la causa raíz. Lo más probable es que la biblioteca esté escrita para Java 1.2 donde no haya ningún constructor con parámetro de causa raíz y el método initCause() sea desde 1.4. – akarnokd

Cuestiones relacionadas