2012-04-04 18 views
6

私は小さなシステムを持っており、エラー/例外を分析して解決策を提案できる製品を提供したいと考えています。Java例外の読み込みと解析

私はJavaの例外を解析する方法を望んでいます(実際のシステムに影響を与えたくありません)。

これを解析した後、DBに保存して、以前に保存した例外(何らかの形式)と比較して、最も近い一致例外を見つけることができます。

私は次の考えを考えました: "XのAとBのCとD"は[XException、A、B、C、D]として保存され、私は何とか私のDBで検索します:[XException 、?、?、?]である。例えば:[XException、A、G、C、D]はかなり良いです。

これらのアイデアはどう思いますか?

例外を解析する効果的な方法はありますか?

2つの例外間の距離を効率的に定義する方法はありますか?

これを行うオープンソースを知っています - わかりませんが見つかりませんでした。

ありがとうございます。

+0

あなたは慎重にシステムを設計した場合、あなたは適切な場所で例外をキャッチしているだろうし、適切な人間が読めるメッセージを表示しています。他の人のアプリケーションエラーを分析するアプリを作成したい場合私はアプリがあいまいになるかもしれないと思う。ちょうど私の考え。 – 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(Unknown Source)\ n"または "\ tat sun.nio.ch.WindowsSelectorImpl $ SubSelector.poll0"を正しく解析しません(ネイティブメソッド)\ n " – roesslerj

2

私はこの質問があまりにもオープンエンドであるとは思わないと思います。 SOは、明確かつ決定的な回答が得られる質問を対象としています。

でも、これが起こる前に、これはかなり良いアイデアのように思えます。私はあなたがそれを機能させることができればと願っています。パッケージ、クラス、メソッド名などの不変の情報を明確に識別するスタックトレースの部分に焦点を当てるのが最善です。部分一致または完全一致の検出に関しては、既知の索引付けアルゴリズムと一致アルゴリズムを調べることをお勧めします。テキスト検索のためのいくつかのよく知られたアルゴリズムを適用することができますが、 "原子"単位はメソッド名またはパッケージ修飾されたクラス名であり、代わりに単一の文字または単語です。

幸運を祈る!

EDIT:ちょっと考えました。多くの異なるプログラミング言語、フレームワークなどのスタックトレースのために、実装を可能な限り一般的なものにすることに焦点を当てたいと思うかもしれません。これは、ソフトウェアをより将来的に証明し、広く適用できるようにします。

関連する問題