spdlog:无法刷新/写入文件

Posted

技术标签:

【中文标题】spdlog:无法刷新/写入文件【英文标题】:spdlog: failing to flush/write to file 【发布时间】:2018-11-23 12:21:32 【问题描述】:

问这个问题我觉得自己像个傻瓜,因为这是我能想到的微不足道的例子,但它让我受不了。

我已经实现了一个非常基本的控制台和文件记录器:

    auto logger = spdlog::basic_logger_mt("console and file logger", filepath);
#ifdef NDEBUG
    spdlog::set_level(spdlog::level::info); // Set global log level to info
#else
    spdlog::set_level(spdlog::level::trace); // Set global log level to everything
#endif
    spdlog::set_pattern("%^%l: %v%$");    // see https://github.com/gabime/spdlog/wiki/3.-Custom-formatting
    spdlog::flush_on(spdlog::level::info);

这会以完美的颜色写入控制台,但虽然它会创建日志文件,但它从不写入。

我想尝试手动刷新,但是没有 spdlog::flush。

我最初用两个接收器(一个控制台,一个文件)实现了这个,并且有一个类似的问题:除非在那种情况下它会写 first(和只有第一个)消息到日志文件,只要它是一个错误。

我很抱歉问了这样一个点头的问题......

------------------------------ 编辑 ---------------- ----------------------

尝试 1(来自多接收器示例):

    // Creating console logger --------------------
    auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();

    // Creating file logger -----------------------
    auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(filepath);

    // Creating multi-logger ----------------------
    spdlog::logger logger("console and file",  console_sink, file_sink );
    spdlog::flush_on(spdlog::level::info);

结果:创建了日志文件,控制台日志记录很好,但文件仍然是空的。

尝试 2(来自基本示例):

    // Creating the logger ------------------------
    auto logger = spdlog::basic_logger_mt("console and $ME file", filepath);
    spdlog::set_level(spdlog::level::trace); // Set global log level to everything
    spdlog::flush_on(spdlog::level::info);

结果:一样

唯一一次我似乎更进一步的是当我将日志级别设置为“错误”时,如果下一个日志是错误,它会出现在文件中。文件中没有其他消息。

我也找不到手动冲洗。我试过用这个例子:

spdlog::apply_all([&](std::shared_ptr<spdlog::logger> l) l->flush(); );

但这似乎没有任何作用......

【问题讨论】:

请提供一个完整的可复现的例子 尝试使用记录器方法而不是 spdlog 的方法。或者,使用 spdlog:register_logger(logger) 注册记录器。 @GabiMe - 然后我从 throw spdlog_ex("logger with name '" + logger_name + "' already exists") 中得到一个错误; 每个记录器的名称只需要调用一次 看来 spdlog::basic_logger_mt 已经自动注册了记录器(这很好),因此您不需要执行 register_logger 步骤。这符合其余的行为(因为它按预期记录到控制台)。 【参考方案1】:

好的,在逐行查看spdlog代码后,我找到了意外行为的根源。

我一直在使用

spdlog::error(message);

以及进行日志记录的相关函数,因为这些不需要创建任何单例或任何东西。

看代码,这些函数总是使用默认记录器,而方法spdlog:register_logger没有设置默认记录器(不知道是做什么的)。

如果您改用以下代码:

spdlog::set_default_logger(logger);

它似乎工作正常。

【讨论】:

谢谢 Mike ;) spdlog API 可以做一些简化。

以上是关于spdlog:无法刷新/写入文件的主要内容,如果未能解决你的问题,请参考以下文章

出现错误 29285。00000 -“文件写入错误” *原因:尝试 FFLUSH 时无法写入、刷新或关闭文件

SSD写入很慢是怎么回事

MPI 屏障不阻塞文件写入、刷新和 os.fsync

python 写文件刷新缓存

关于c++的glog和spdlog的性能对比

从 Windows CLI 刷新磁盘写入缓存