2012-04-04 17 views
6

Tengo un sistema pequeño y deseo ofrecer un producto que pueda analizar errores/excepciones y sugerir una posible solución.Lectura y análisis de excepciones de Java

Así que quiero una forma de analizar una Excepción de Java (ya que los tengo solo en los registros [No quiero afectar el sistema real]).

Después de analizarlo, quiero guardarlo en un DB y compararlo con excepciones guardadas previamente (en algún formato), para poder encontrar la excepción de coincidencia más cercana.

Pensé en la siguiente idea: "XException en A en B en C en D" se guardará como [XException, A, B, C, D] y de alguna manera buscaré en mi base de datos: [XException ,?,?,?] que es lo más cercano. Por ejemplo: [XException, A, G, C, D] es bastante bueno.

¿Qué piensas de estas ideas?

Cualquier forma eficiente de analizar Excepciones?

¿Maneras eficientes o mejores de definir la distancia entre dos excepciones?

Conozca cualquier fuente abierta que pueda hacer esto - Creo que no he encontrado ninguno.

Gracias.

+0

Si ha diseñado el sistema de cuidado, que habría cogido de excepciones en lugares apropiados y se habría mostrado mensajes legibles por humanos apropiados. Si desea escribir una aplicación que analiza el error de la aplicación de otra persona.Creo que la aplicación puede ser vaga. Solo mis pensamientos. – Nishant

Respuesta

4

Es un trabajo bastante difícil, pero aquí hay una demostración del análisis de algunas excepciones de la vida real generadas sobre la marcha.

  • El método se llama generate_ $ para tratar de cubrir métodos con nombres extraños. Sin embargo, estoy seguro de que no he cubierto todos los casos.
  • reconstruirlos de nuevo en una lista de java.lang.StackTraceElement ya que parece el tipo correcto para el trabajo.

Código:

private static List<String> generate_$() { 
    List<String> returnValue = new LinkedList<String>(); 
    Exception[] exceptions = { new ClassCastException(), 
      new NullPointerException(), new IOException("foo") }; 
    for (Exception exception : exceptions) { 
     try { 
      throw exception; 
     } catch (Exception e) { 
      StringWriter writer = new StringWriter(); 
      e.printStackTrace(new PrintWriter(writer)); 
      returnValue.add(writer.getBuffer().toString()); 
     } 
    } 
    return returnValue; 
} 

public static void main(String[] args) { 
    List<String> examples = generate_$(); 
    for (String trace : examples) { 
     Pattern headLinePattern = Pattern.compile("([\\w\\.]+)(:.*)?"); 
     Matcher headLineMatcher = headLinePattern.matcher(trace); 
     if (headLineMatcher.find()) { 
      System.out.println("Headline: " + headLineMatcher.group(1)); 
      if (headLineMatcher.group(2) != null) { 
       System.out.println("Optional message " 
         + headLineMatcher.group(2)); 
      } 
     } 
     // "at package.class.method(source.java:123)" 
     Pattern tracePattern = Pattern 
       .compile("\\s*at\\s+([\\w\\.$_]+)\\.([\\w$_]+)(\\(.*java)?:(\\d+)\\)(\\n|\\r\\n)"); 
     Matcher traceMatcher = tracePattern.matcher(trace); 
     List<StackTraceElement> stackTrace = new ArrayList<StackTraceElement>(); 
     while (traceMatcher.find()) { 
      String className = traceMatcher.group(1); 
      String methodName = traceMatcher.group(2); 
      String sourceFile = traceMatcher.group(3); 
      int lineNum = Integer.parseInt(traceMatcher.group(4)); 
      stackTrace.add(new StackTraceElement(className, methodName, 
        sourceFile, lineNum)); 
     } 
     System.out.println("Stack: " + stackTrace); 

    } 
} 

Salida:

Headline: java.lang.ClassCastException 
Stack: [com.adamish.ExceptionParse.generate_$((ExceptionParse.java:16), com.adamish.ExceptionParse.main((ExceptionParse.java:31)] 

Headline: java.lang.NullPointerException 
Stack: [com.adamish.ExceptionParse.generate_$((ExceptionParse.java:17), com.adamish.ExceptionParse.main((ExceptionParse.java:31)] 

Headline: java.io.IOException 
Optional message : foo 
Stack: [com.adamish.ExceptionParse.generate_$((ExceptionParse.java:17), com.adamish.ExceptionParse.main((ExceptionParse.java:31)] 
+0

Gracias, buen trabajo. Sin embargo, hay un ligero error en la expresión regular: hay un '(' adicional en el nombre de archivo resultante. Cambiar ... (\\\ (. * Java) ... a ... \\\ ((. * java) ... – roesslerj

+0

Además, esta expresión regular no analiza correctamente "\ tat sun.nio.ch.WindowsSelectorImpl $ 1.access $ 400 (fuente desconocida) \ n" o "\ tat sun.nio.ch.WindowsSelectorImpl $ SubSelector.poll0 (Método nativo) \ n ". – roesslerj

2

Supongo que esta pregunta se cerrará por ser demasiado abierta. SO está destinado a preguntas a las que se pueden dar respuestas claras y definitivas.

Aún así, antes de que eso suceda, me gustaría decir que parece una buena idea y espero que pueda hacer que funcione. Lo mejor sería centrarse en las partes del trazado de la pila que identifican claramente la información inmutable, como los nombres de paquetes, clases y métodos. En cuanto a la detección de coincidencias parciales o completas, sugiero que busque algoritmos de indexación e identificación conocidos. Se pueden aplicar algunos algoritmos bien conocidos para las búsquedas de texto, pero las unidades "atómicas" son nombres de métodos o nombres de clases calificados por el paquete en vez de letras sueltas o palabras.

¡Buena suerte!

EDIT: solo he pensado en otra cosa. Es posible que desee centrarse en hacer que su implementación sea lo más genérica posible para los rastros de pila de muchos lenguajes de programación, marcos de trabajo, etc. Esto haría que el software sea más a prueba de futuro y ampliamente aplicable.

Cuestiones relacionadas