2012-04-04 3 views
6

시스템이 작기 때문에 오류/예외를 분석하고 가능한 해결책을 제시 할 수있는 제품을 제공하고 싶습니다.Java 예외 읽기 및 구문 분석

그래서 (실제로 시스템에 영향을 미치고 싶지 않은) 로그에만 있기 때문에 Java 예외를 구문 분석하는 방법을 원합니다.

구문 분석 후 DB에 저장하고 이전에 저장 한 예외 (일부 형식)와 비교하여 가장 가까운 일치 예외를 찾을 수 있습니다.

나는 다음과 같은 생각에 대해 생각 : 는 [XException, A, B, C, D]와 I로 저장됩니다 "D에서 C에서 B에서의에서 XException은"어떻게 든 내 DB에서 검색됩니다 [XException ,?,?,?] 가장 가까운 것입니다. 예를 들면 : [XException, A, G, C, D] 꽤 좋습니다.

이러한 아이디어에 대해 어떻게 생각하십니까?

예외를 구문 분석하는 효율적인 방법은 무엇입니까?

두 가지 예외 사이의 거리를 정의하는 더 효율적이고 효과적인 방법은 무엇입니까?

이 작업을 수행 할 수있는 공개 소스를 확인하십시오. 확실하지 않습니다.

감사합니다.

+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) ...) ... \\ ((* java) ... – roesslerj

+0

또한이 정규식은 "\ tat sun.nio.ch.WindowsSelectorImpl $ 1.access $ 400 (알 수없는 소스) \ n"또는 "\ tat sun.nio.ch.WindowsSelectorImpl $ SubSelector.poll0 (네이티브 메소드) \ n " – roesslerj

2

나는이 질문이 너무 개방적이어서는 안된다고 생각한다. 그래서 명확하고 확실한 답을 얻을 수있는 질문을하고자합니다.

그런데도 이런 일이 일어나기 전에 나는 이것이 꽤 좋은 생각처럼 보인다고 말하고 싶습니다. 패키지, 클래스 및 메서드 이름과 같이 변경 불가능한 정보를 명확하게 식별하는 스택 추적 부분에 초점을 맞추는 것이 가장 좋습니다. 부분 일치 또는 전체 일치를 탐지하는 방법에 대해서는 알려진 색인 및 일치 알고리즘을 살펴 보는 것이 좋습니다. 텍스트 검색을위한 몇 가지 잘 알려진 알고리즘을 적용 할 수 있지만 "원자"단위는 메소드 이름이거나 단일 문자 또는 단어 인 경우 패키지 규정 클래스 이름입니다.

행운을 빈다.

편집 : 방금 다른 생각이 들었습니다. 많은 다른 프로그래밍 언어, 프레임 워크 등의 스택 흔적에 대해 구현을 가능한 한 포괄적으로 만드는 데 집중할 수 있습니다. 그러면 소프트웨어가 미래 지향적이고 광범위하게 적용될 수 있습니다.