2012-07-09 2 views
0

갑자기 야생 생각이 들릴 때 나는 프로그램을 작성하고 있었다 : 나의 프로그램에서 로그 시스템을 만드는 가장 좋은 방법은 무엇인가? 내 코드 (물론 헤더 파일 제외)의 어떤 위치에 로그를 저장할 수 있습니까? 당신은 이전에 난 그냥 열려있는 파일을 알고 내가 원하는 것을 저장,하지만 지금은 내가 좋아하는 프로 방법으로 그것을 할 것내 프로그램에서 로깅 시스템을 만드는 방법은 무엇입니까?

myLogs << "Ups, somthing failed :("; 

같은 뭔가 : DI 클래스에 대해 생각했다 다른 모든 클래스에 의해 상속되지만 그것은 문제가되는 종류입니다. 나는 또한 정적 함수에 대해 생각했지만 그것이 어떻게 작동하는지 잘 모르겠습니다.

+0

[이 질문에 대한 답변] (http://stackoverflow.com/questions/696321/best-logging-framework-for-native-c) –

답변

2

간단한 대답은 하나도 없습니다. 그것은 응용 프로그램에 따라 다릅니다. 난 많은 하위 프로젝트에 대한 로깅 을 다르게 구성 할 수있는 매우 큰 프로젝트에서 작업했습니다. 그러한 시스템은 작은 응용 프로그램 인 에서 과도 할 것입니다. 또한 응용 프로그램 이 장기간 동안 계속 있어야하는 경우에도 차이가 있습니다. 이 경우 응용 프로그램을 중지하지 않고 로그를 재구성하는 것이 좋습니다.

그러나 일반적으로 로그 구성 파일 의 로깅 수준을 지정하고 로그 메시지로 수행 할 작업이 필요합니다. 또한 로깅이 없을 때 최소한 의 작업을 수행해야합니다. 내가 사용한 한 가지 해결책은 사용 가능한 각 작업 (파일에 쓰기, 이메일 보내기, 또는 syslog로 보내기)마다 다양한 streambufs를 유지하는 것입니다. 그러면 ostream * 테이블에 로그 수준으로 색인이 생성됩니다. 해당 레벨에 대한 로깅이 있다면 필요한 모든 작업 streambufs로 전달하는 streambuf를 만들고 테이블에 사용하는 ostream의 주소를 으로 지정합니다. 이 특별한 streambuf에는 각 로깅 레코드를 시작하고 중지하는 기능도 있습니다. 레코드를 시작하는 레코드는 파일 이름과 라인 번호 으로 호출되며 레코드를 중지하는 레코드는 각 관리되는 스트림을 플러시합니다. 주어진 레벨에서 로깅이없는 경우 ostream 포인터는 null입니다.

기본 로거는 다음과 같습니다

class Logger 
{ 
    std::ostream* myDest; 
    int* myUseCount; 
public: 
    Logger(int level, char const* filename, int lineNumber) 
     : myDest(ourLogTable[level]) 
     , myUseCount(new int(1)) 
    { 
     if (myDest != NULL) { 
      myDest->rdbuf()->startLogRecord(filename, lineNumber); 
     } 
    } 

    Logger(Logger const& other) 
     : myDest(other.myDest) 
     , myUseCount(other.myUseCount) 
    { 
     ++ *myUseCount; 
    } 

    ~Logger() 
    { 
     -- *myUseCount; 
     if (*myUseCount == 0 && myDest != NULL) { 
      myDest->flush(); 
     } 
    } 

    template <typename T> 
    Logger& operator<<(T const& obj) 
    { 
     if (myDest != NULL) { 
      *myDest << obj; 
     } 
    } 
}; 

(.. C++ 11, 당신이 내 참조 계산보다는 이동의 의미를 사용해야 훨씬 더 간단) 마지막으로

, 당신은 로거를 호출 매크로를 통해 :

#define LOG(level) Logger(level, __FILE__, __LINE__) 

자동 파일 이름과 줄 번호를 삽입 할 경우 매크로의 사용이 필요하다.

1

클래스를 만들고 파일에 쓰기를 구현하려면 operator<<을 오버로드하십시오. 당신은 또한이 필요합니다 - 내가 정확히 질문을 이해하지만, 내가 무슨 짓을하는 (데이터를 커밋 한 다음 다른 사용자 정의 메시지)를 WM_SETTEXT 메시지를 사용하여 다른 응용 프로그램으로 로그 데이터를 전송하는 경우

#include <fstream> 
#include <iostream> 

using namespace std; 

class logger 
{ 
public: 
    void operator<<(const std::string & input); 
}MyLogger; 

void logger::operator <<(const string &input) 
{ 
    std::ofstream of("filename.txt"); 
    of << input; 
    of.close(); 
} 

int main() 
{ 
    MyLogger<<"sometext"; 
} 
+0

'MyLogger << "Error"<< XXX << "Out 치즈 오류. 다시 시작부터. "; –

0

확실하지 않음 데이터를 읽고 저장하는 기본 리스너 응용 프로그램을 작성하는 것이 좋습니다. 목록 상자와 같은 컨트롤에 배치하는 것이 좋습니다. 이것은 파일 시스템, 파이프, 소켓 등을 포함하지 않기 때문에 매우 빠르다. 헤더 파일 (#define/# ifdef 지시문에 의해 제어 됨)에서 조건부 컴파일을 사용하여 로깅을 켜거나 끌 수도있다.

관련 문제