10

私は小さなシステムを持っていますが、エラー/例外を分析して可能な解決策を提案できる製品を提供したいと思います。

したがって、Java例外を解析する方法が必要です(ログにのみ存在するため[実際のシステムに影響を与えたくない])。

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

次のアイデアについて考えました。「XExceptionatAat B at C at D」は[XException、A、B、C、D]として保存され、どういうわけかDBを検索します:[XException、?、?、 ?]これが最も近いです。例:[XException、A、G、C、D]は非常に優れています。

これらのアイデアについてどう思いますか?

例外を解析するための効率的な方法はありますか?

2つの例外間の距離を定義するための効率的またはより良い方法は?

これを行うことができるオープンソースを知っている-私は確かに何も見つけていません。

ありがとうございました。

4

2 に答える 2

7

これは非常に大変な作業ですが、ここでは、その場で生成された実際の例外を解析するデモを示します。

  • このメソッドは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)]
于 2012-04-04T15:46:51.390 に答える
3

この質問は、制限が多すぎるために閉じられると思います。SOは、明確で明確な答えを与えることができる質問を対象としています。

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

幸運を!

編集:何か他のことを考えただけです。多くの異なるプログラミング言語、フレームワークなどのスタックトレースに対して、実装を可能な限り一般的にすることに集中することをお勧めします。これにより、ソフトウェアはより将来性があり、広く適用できるようになります。

于 2012-04-04T15:02:25.777 に答える