2017-02-15 10 views
1
#include <iostream> 

#define LOGFATAL(msg) log(0, msg) 

std::ofstream *logst = NULL; 

void log(int sev, char *msg) 
{ if (logst == NULL) { 
     logst = new std::ofstream(); 
     logst->open("filea.txt", std::ios::out | std::ios::app); 
     *logst << "Logger started." << std::endl; 
    } 

    std::ofstream &_log = *logst; 
    _log << msg << std::endl; 
    _log.flush(); 
} 

int main() 
{ LOGFATAL("Log msg1."); 
    LOGFATAL("Log msg2."); 
    LOGFATAL("Log msg3."); 

    logst->close(); 
    delete logst; 
} 

로그를 처음으로 기록하기위한 파일을 열어 프로그램이 끝날 때까지 계속 열어 둡니다.C++ forstream은 프로그램을 계속 실행하여 파일을 작성 및 작성하지 않습니다.

모든 로그 호출 후에 flush() 작업을 사용하기 때문에 메시지가 곧바로 인쇄 될 것으로 예상됩니다. 그러나 이것은 없었습니다. 왜?

현재, 나는 그것이 완료되기 전에 (왜 안 함) Ctrl 키 + C를 사용하여 내 프로그램을 죽인다. 이후에 프로그램을 실행하면 로그 파일이 생성되는 것을 볼 수 없으며 이미 존재하는 경우에도 추가되는 로그는 표시되지 않습니다. close()을 실행시키지 않으므로 파일 설명자가 유출되어 향후에 새 프로그램의 open()이 실패하지 않도록 하시겠습니까?

RHEL 7.2에서 실행 중이며 우연히 close()이 호출되지 않아도 요즘 대부분의 OS가 처리한다고 가정합니다. Ctrl + C은 내 프로그램을 현재 중지하는 유일한 방법입니다. 프로그램을 시작할 때마다 올바르게 기록하도록하려면 어떻게해야합니까?

로그 파일에 유출 된 파일 설명자가 있는지 시스템 셸에서 확인하는 방법이 있습니까?

+0

"가까운 시일 내에"당신의 메시지가 * 인쇄되지 않고 * 어떻게 확인되고 있습니까? 프로세스를 죽이는 것에 관해서는 일단 사라지면 열려있는 파일 스트림이므로 모두 "누출"해서는 안됩니다. 과정은 * 사라 * 있습니다. 즉, 당신이 당신의'open' 호출에 적절한 플래그를 사용하고 있는지 확실합니까? (http://en.cppreference.com/w/cpp/io/basic_ofstream/open)? – WhozCraig

+0

gdb에서 flush()를 실행 한 후에 로그 파일을 테일링하고 잠시 동안 로그를 보지 못합니다. 그러나 이것이 가장 걱정스러운 문제는 아닙니다. 후속 프로그램 실행시 전혀 열거 나 쓰지 않는 것이 더 큰 문제입니다. std :: ios :: out 및 std :: ios :: app 모드를 설정했습니다. 내가 다른 일을해야합니까? – siri

+0

또한 부울 로깅 기능은 더 나은 방법으로 흐름/활동을 캡처하기 위해 프로젝트에 인쇄 된 모든 로그에서 '파일 열기, 로그 및 닫기'기능을 제공해야합니다. – sameerkn

답변

1

삽입 std::endl 자체가 데이터를 플러시합니다. _log.flush();에 댓글이 달린 경우에도 작동합니다.

"내 메시지가 즉시 인쇄 될 것으로 예상됩니다". vim을 사용하는 경우 파일을 닫았다가 다시 열어야합니다. 따라서 tail -F filea.txt을 사용하여 데이터가 파일에 기록되면 즉시 출력을 확인하십시오.

+0

그러나 나는 프로그램의 후속 실행에서 전혀 인쇄 된 것을 보지 못했다. 나는 is_open() 체크를 넣었고 open()은 파일을 열지도 않는다는 것을 알았다. – siri

+0

@siri'fstream :: open()'은 아무 것도 반환하지 않으므로'fopen'을 사용하여 파일을'a +'모드로 열고'errno variable'을 통해 에러를 검사 할 것을 제안합니다 . – sameerkn

+0

@siri 킥을 위해서'std :: ios :: out | std :: ios :: app | std :: ios :: ate'를 오픈 플래그로 사용하십시오. RHEL을 사용하고 있다는 것을 알고 있지만 툴체인은 무엇입니까? – WhozCraig