2012-04-04 4 views
6

У меня небольшая система, и я хочу предложить продукт, который может анализировать ошибки/исключения и предлагать возможное решение.Чтение и разбор исключений Java

Так что я хочу, чтобы разобрать исключение Java (поскольку у меня есть они только в журналах [я не хочу влиять на реальную систему]).

После разбора его я хочу сохранить его в БД и сравнить его с ранее сохраненными исключениями (в некотором формате), чтобы я мог найти ближайшее сопоставимое исключение.

Я подумал о следующей идее: «XException at A at B at C at D» будет сохранено как [XException, A, B, C, D], и я буду как-то искать в своей БД: [XException ,?,?,?], который является самым близким. Например: [XException, A, G, C, D] неплохо.

Что вы думаете об этих идеях?

Любой эффективный способ анализа Исключения?

Эффективные или лучшие способы определения расстояния между двумя исключениями?

Знайте какие-либо открытые источники, которые могут это сделать - я уверен, что не нашел.

спасибо.

+0

Если вы тщательно разработали систему, вы уловили Exception в соответствующих местах и ​​будут отобразили соответствующие считываемые сообщения человека. Если вы хотите написать приложение, которое анализирует чужую ошибку приложения.Я думаю, что приложение может оказаться неопределенным. Просто мои мысли. – Nishant

ответ

4

Это довольно тяжелая работа, но вот демонстрация синтаксического анализа некоторых реальных исключений, сгенерированных на лету.

  • метод называется generate_ $, чтобы попытаться покрыть странно названные методы. Я уверен, что я не рассматривал все случаи.
  • восстановить их обратно в список java.lang.StackTraceElement, так как он кажется правильным типом для задания.

Код:

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); 

    } 
} 

Выход:

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

Спасибо, отличная работа. Однако в регулярном выражении есть небольшая ошибка: в результирующем имени файла есть еще один (...). ... (\\\ (. * Java) ... to ... \\\ ((. * java) ... – roesslerj

+0

Кроме того, это регулярное выражение неправильно обрабатывает «\ tat sun.nio.ch.WindowsSelectorImpl $ 1.access $ 400 (Неизвестный источник) \ n" или "\ tat sun.nio.ch.WindowsSelectorImpl $ SubSelector.poll0 (Native Method) \ n ". – roesslerj

2

Я думаю, этот вопрос будет закрыт как слишком открытый. SO предназначен для вопросов, которым могут быть даны четкие и окончательные ответы.

Несмотря на это, прежде чем это произойдет, я хотел бы сказать, что это кажется довольно хорошей идеей, и я надеюсь, что вы сможете заставить ее работать. Было бы лучше сосредоточиться на тех частях трассировки стека, которые четко идентифицируют неизменяемую информацию, такую ​​как имена пакетов, классов и методов. Что касается обнаружения частичных или полных совпадений, я предлагаю вам ознакомиться с известными алгоритмами индексирования и сопоставления. Могут быть применены некоторые известные алгоритмы для текстовых поисков, но с «атомарными» единицами - это имена методов или имена классов класса, а не отдельные буквы или слова.

Удачи вам!

EDIT: просто подумал о чем-то другом. Вы можете сосредоточиться на том, чтобы сделать вашу реализацию максимально универсальной для стековых следов многих разных языков программирования, фреймворков и т. Д. Это сделало бы программное обеспечение более перспективным и широко применимым.

Смежные вопросы