2010-07-13 6 views
1

별도의 스레드에서 실제 로깅을 수행하는 로깅 API를 작성해야합니다.호출 스택을 캡처하여 다른 스레드에서 실행하도록하십시오.

즉 일부 정보를 기록하려는 응용 프로그램이 있습니다. 그것은 내 API를 호출하고 api는 모든 인수 등을 캡처 한 다음 기록 할 별도의 스레드로 전달합니다.

로거 API는 가변 인수를 허용하므로 전체 초기 호출은 전체 호출 스택을 캡처하고 어떻게 든 로깅을 수행 할 스레드에 넘겨 줘야합니다.

전화 스택을 캡처 할 수있어서 기쁩니다. 그러나 나는이 호출 스택을 다른 메소드에 전달하는 방법을 확신하지 못한다.

저는 Linux에서 g ++를 사용하고 있으며 solaris에서 Sun의 CC v12와 함께 작동해야 할 수도 있습니다.

아이디어가 없습니다.

답변

2

호출 스택에서 고정 된 크기의 바이트를 캡처 할 수 있지만 필요하지 않은 경우에도 해당 메모리를 모두 복사하여 대기열에 저장하여 로깅 스레드로 전달해야합니다. 일하기에 많은 노력이 필요하고, 비효율적입니다.

로깅 API를보다 효율적으로 만들기 위해 별도의 로깅 스레드를 사용한다고 가정합니다. 이 경우 로깅 API에서 가변 매개 변수를 추출하고 간단한 표현 (예 : 기록 할 문자열)으로 변환 한 다음 대기열에 넣는 것이 더 효율적일 수 있습니다.

좋은 로깅 API는 차단해서는 안되기 때문에 로깅 API와 로깅 스레드 사이에 잠금이없는 대기열을 권장합니다.

+0

Thanks Frederik. 그것은 실제로 스레드 로거 뒤에있는 이론적 근거입니다. 나는 디스크 io의 느린 작업을 다른 스레드에 맡기고 싶습니다. 스택을 복사하려고 시도했지만 물론 여전히 기록되는 모든 객체가 기록 될만큼 길어야한다는 의미입니다. 나는 당신이 호출 지점에서 로깅 문자열을 생성하고 로거에 전달하는 것이 더 나은 접근 방법이라고 생각한다. – ScaryAardvark

0

다른 스레드로 전달하는 방법을 모르는 것이 가장 간단한 방법은 뮤텍스를 보호하는 호출 스택 대기열 (std :: deque, 아마도)을 사용하는 것입니다. 응용 프로그램에서 콜 스택을 생성하면 뮤텍스를 잠그고 콜 스택을 켠 다음 뮤텍스를 잠금 해제합니다. 로깅 스레드는 주기적으로 뮤텍스를 잠그고 대기열의 크기를 확인하며 비어 있지 않으면 호출 스택을 꺼내 처리합니다.

효율성을 향상시킬 수있는 방법이 있습니다 (예 : 조건 변수, 별도의 카운터를 사용하여 크기를 확인하기 전에 잠글 필요가 없으며 비 잠금 데이터 구조를 사용할 수도 있습니다).하지만 걱정할 필요가 없습니다. 그들이 프로파일 링에 나타날 때까지 말입니다.

0

다른 방법은 다음과 같습니다

  1. 함수 이름과 표준 미리 정의 된 매크로를 사용하여 파일 이름, 줄 번호 등과 같은 몇 가지 추가 정보를 인쇄하는 매크로를 정의합니다. 그렇지 않으면 printf를 사용하게 될 추가 로그 정보를 전달할 수도 있습니다. 그러면 다른 스레드로 데이터를 보내는 함수가 호출됩니다. 이 스레드는 소켓/파이프에서 대기 할 수 있습니다. 데이터를 기록한 다음 시스템 호출 (쓰기/읽기/파이프)을 사용하여 데이터를 읽을 수 있습니다.
  2. 이제 모든 함수/API의 시작 부분에이 매크로를 삽입하십시오. 호출 흐름 (호출 스택)을 얻을 수 있습니다.
  3. 로깅 스레드는이 매크로의 정보를 사용하여 파일에 쓰거나 콘솔에 표시 할 수 있습니다.

    PRINT_LOG (X) function_to_pass_data_to_thread (X, FILE, LINE)를 정의;

    API1() 
    { 
        PRINT_LOG("Entered API1"); 
        //Your API here 
    

    }

PS : 겉만 번지르르 한 편집 대해 죄송합니다. 나는 오늘 편집장이 무슨 문제인지 이해하는 것 같다. 내 생각에 SO 버그를 기록해야합니다.;)

관련 문제