嗯,如果记录器在事情进展顺利时只保留记录,那么它有什么用?
在扩展它之前我想测试一个非常简单的记录器:
// Logger.h
class Logger : boost::noncopyable
{
public:
static void write(std::string const& msg, int line, std::string const& file);
private:
Logger();
private:
static std::ofstream m_sOut;
};
#define LOG(msg) Logger::write(msg, __LINE__, __FILE__)
// Logger.cpp
std::ofstream Logger::m_sOut("Logfile");
void Logger::write(const std::string &msg, int line, const std::string &file, Level level /* = Info */)
{
m_sOut << file << ": " << line << ": " << msg << "\n";
}
我担心这太简单了。如果我正常退出程序,它会按预期输出到我的日志文件。但是,如果发生崩溃,则没有输出。
我需要做些什么来确保无论崩溃都输出到日志?
答案 0 :(得分:3)
取决于崩溃的时间,我会说。如果在日志输出期间,则所有投注均已关闭。
首先,我会确保在每次调用后都会刷新日志输出,因此我会在std::endl
中使用\n
而不是write()
。您还必须验证这确实是足够的,或者您是否必须采取其他步骤来确保您使用的流不会缓冲写入。
编辑:正如评论中所指出的,写入磁盘而不进行任何类型的缓存/缓冲是缓慢且昂贵的。这是一个权衡 - 如果你绝对必须要求你不能丢失任何日志信息,除非程序在日志语句期间崩溃,你可能必须这样做。我可能会稍微放松一下这个要求,只是依赖std::endl
的行为,这会导致流被刷新;这仍然会将缓冲区留在流下面,就像OS缓冲区一样,但是你很有可能不会丢失任何日志输出。
答案 1 :(得分:2)
我认为这需要您的日志记录子系统至少在一个单独管理的进程中,您应该通过高带宽协议进行通信 - 例如共享内存。
答案 2 :(得分:1)
在Windows上,您可以使用SetUnhandledExceptionFilter刷新日志文件。
答案 3 :(得分:1)
听起来你需要在写完后冲洗:
m_sOut.flush();