我在使用时使用glog进行日志记录:
LOG(INFO) << "something";
它按预期工作但是当我使用如下的多个日志时,它将不会记录,直到程序停止。当程序停止时,它将按预期记录所有内容。
LOG(INFO) <<"111111111111111";
LOG(INFO) <<"222222222222222";
LOG(INFO) <<"333333333333333";
LOG(INFO) <<"444444444444444";
但令人困惑的是,当我多次使用LOG(警告)时,它可以完美地工作,即,即使程序运行,它也会记录所有内容,而不像之前的情况,当程序停止时记录所有内容。
LOG(WARNING) <<"111111111111111";
LOG(WARNING) <<"222222222222222";
LOG(WARNING) <<"333333333333333";
LOG(WARNING) <<"444444444444444";
**非常感谢任何有关此行为的帮助**
答案 0 :(得分:4)
这是由于默认情况下glog
缓冲INFO
日志。缓冲由标志FLAG_logbuflevel
控制,标志的默认值为0,即所有严重性<=该值都将被缓冲。
accepted answer可以工作,因为google::FlushLogFiles(min_severity)
会强制刷新所有> = min_severity的日志,但是在生产代码库中定义我们的自定义宏可能不可行。因此,防止缓存INFO
日志的最简单解决方案是将FLAG_logbuflevel
设置为-1
other answer提出了一个有趣的想法,即LogMessage::~LogMessage()
调用了Flush()
,因此不需要接受的答案中建议的显式刷新。这是不正确的,因为在dtor中对Flush()
的调用是有条件的。这是调用堆栈-
LogMessage::~LogMessage()
|__LogMessage::Flush()
|__(LogMessage::*send_method_)() == LogMessage::SendToLog()
|__LogDestination::LogToAllLogfiles()
|__LogDestination::MaybeLogToLogfile()
|__Logger::Write(should_flush = log_severity > FLAGS_logbuflevel )
如您在调用堆栈的最后一帧中所见,日志目标(文件)的实际Write
接受布尔值should_flush
,该布尔值取决于标志FLAGS_logbuflevel
我刚才说过。
因此,默认情况下,即使Flush
的dtor中有一个LogMessage
调用,也不会实际将数据刷新到磁盘上
答案 1 :(得分:1)
问题相当简单。默认情况下,glog对每个严重性使用一个日志文件,以防止两个流打开同一个文件。如果您通过不同的流在c++
中打开相同的文件,其中一个(打开文件的第一个)会优先写入文件。另一个只能在第一个流关闭时开始写入该文件。
您必须为每个严重性声明不同的日志文件,或者将所有日志消息放在一个文件中,您只需编写自己的小日志库即可。
似乎特别需要使用google::FlushLogFiles(google::INFO)
刷新INFO流。要在每个要记录的信息之后执行此操作,我将自己定义一个宏来调用flush函数,如下所示:
#define log(severity, msg) LOG(severity) << msg; google::FlushLogFiles(google::severity);
这可确保刷新流并且所有消息都将显示在日志文件中
答案 2 :(得分:0)
尽管以上答案已被接受并且可能有助于解决问题,但我不确定这是否是解决问题的正确方法,甚至是正确的解释。
如果您查看glog的代码,则会发现:
'''
'''
因此在原始问题中,LOG(INFO)将被定义为类似 '''
'''
这将创建一个临时流对象,并将日志记录内容写入该流对象。之后,将调用LogMessage LogMessage ::〜LogMessage()的析构函数。在该析构函数中,实际上将调用Flush()来将日志记录内容刷新到I / O设备。
也就是说,对于每个LOG(INFO)语句,将创建并销毁一个临时流对象,并在销毁它之前调用Flush()。因此,恕我直言,不需要额外调用google :: LogMessage :: Flush()甚至google :: FlushLogFiles(google :: INFO)。