2010-04-20 1 views
3

우리는 거대한 Java 코드베이스 [~ 1 M Lines]를 가지고 있습니다.Large Java 프로그램에서 System.out으로 오류 출력 찾기

코드베이스에 묻혀있는 (어딘가에) 우리가 제거하려는 System.out에 대한 일부 오래된 디버그 출력입니다 (어수선한 것들).

문제는 아웃 코드베이스가 너무 커서 출력이 어디에서 왔는지 쉽게 찾을 수 없다는 것입니다. 우리가 원하는 것은 System.out.println이 호출되는 곳 (예 : 예외 또는 일부 스택 추적)을 확인하는 방법입니다.

그것의 디버깅에 적합하지 - 잘못된 출력이 곳 등

다운이 잘못된 출력의 소스를 추적하는 방법에 대한 아이디어를 몇 가지 잘못된 스레드에서오고있다?

추 신 : System.out에 대한 99.99 %의 호출은 합법적이며 우리는 수천 개가 있습니다. 따라서 System.out 호출에 대한 코드 기반을 간단하게 검색하는 것은 해결책이 아닙니다!

+0

@SvrGuy : 모든 * System.out.println *을 적절한 로깅 호출로 바꿀 수 있습니다. 그런 다음 호출 된 곳을 알 수 있습니다. * System.out * 호출을 대체 할 수도 있습니다.이 호출은 * System.out.println * 호출에서 오는 클래스 이름을 추가하여 호출 할 수 있습니다. 둘 다 일부 스크립팅 언어를 사용하여 쉽게 수행 할 수 있습니다 (일부 스크립팅 기술은 모든 프로그래머에게 필수이지만 필자는 생략 함). 그곳에 가셔서, 모든 System.out.println을 100 KLOC 자바 코드베이스의 Un * x Bash 쉘 스크립트에 의해 자동으로 적절한 로깅으로 대체했습니다. – SyntaxT3rr0r

+0

@SvrGuy : 쉘 스크립트를 사용하고 * find *, * sed * 및 * awk *와 같은 도구를 결합하는 것은 약간의 해킹이지만 아무 것도 잘못되지 않도록 제어 할 수 있습니다. 기본적으로 필자는 모든 * .java * 파일을 찾기 위해 * find *를 사용하고 각 파일 안에는 * System.out.println (* with * System.out.println (" .java_file_name "+"* 혹시 멋진 DVCS를 사용하고 있다면, 1M 초의 코드베이스를 초 단위로 복제하고 포크에서 최악의 범죄자를 찾아 "진짜"코드베이스에서 최악의 범죄자를 삭제하고, – SyntaxT3rr0r

답변

6

System.setOut() 방법이 있습니다. 정말로 필사적이라면, 이것을 진짜 stdout의 래퍼로 설정하고 래퍼에서 무엇이든 할 수 있습니다. 예 : 쓰여진 문자열을 무언가와 비교하고 그 결과가 잘못된 경우 던져 버리십시오.

+0

나는 이것이 정확하게 맞는 것 같아. 자신의 스트림을 만들고, 기분을 상하게하는 메시지가 왔을 때.그냥 스택 추적을 인쇄하십시오 : 새로운 RuntimeException(). printStackTrace(); –

+0

좋은 답변입니다! 그것은 필사적으로 절실히 필요하지 않습니다 - 저는 그것이 몇 분 안에 완료 될 수 있다고 생각합니다. –

2

AspectJ를 사용하면 System.out을 호출하는 클래스의 서명을 쉽게 인쇄 할 수 있습니다.

TraceAspect에서 제공하는 간단한 예제는 다음과 같습니다. 중요한 부분은 클래스가 데모 패키지에 있고 System.out을 호출한다는 것입니다. aspect는 데모 패키지 깊이의 하위 패키지에있는 모든 클래스에서 System.out에 대한 모든 호출을 조언합니다.

@Aspect 
public class TraceAspect { 

    @Pointcut("call(* java.io.PrintStream.*(..))") 
    public void sysoutPointcut() { 
    } 

    @Pointcut("within(demo..*)") 
    public void packagePointcut() { 
    } 

    @Before("sysoutPointcut() && packagePointcut()") 
public void beforeSysoutCallInsideDemoPackage(JoinPoint joinPoint) { 
    System.out.print(joinPoint.getThis().getClass().getName() + ":" 
      + joinPoint.getSourceLocation().getLine() + " - "); 
} 
} 

DemoClass의 주요 방법을 실행의 출력은 다음과 같습니다하여 System.out을 호출하기 전에

package demo; 

public class DemoClass { 

    public void demo() { 
     System.out.println("inside demo method.."); 
    } 

    public static void main(String[] args) { 
     new DemoClass().demo(); 
    } 
} 

는이 같은 화면을 추가 할 수 있습니다, 패키지 및 클래스 이름을 인쇄하려면 : -의 AspectJ 프로젝트로 변환>

이클립스와 AspectJ를 플러그인으로
demo.DemoClass:6 - inside demo method.. 

, 당신은 당신의 프로젝트를 마우스 오른쪽 단추로 클릭하고 구성을 클릭 할 수 있습니다. 위의 코드가 작동합니다.

@AspectJ 스타일 here으로 AspectJ에 대해 더 자세히 작성했습니다.