设置自定义收集器时 boost::log 不遵守 keywords::max_size 吗?

Doesn't boost::log respect keywords::max_size when custom collector is set?

我正在使用 Boost 1.61,我最终想要的是:

  1. 如果当前日志文件的大小达到 FILE_ROTATION_SIZE
  2. ,则旋转当前日志文件
  3. 使用自定义收集器处理旋转文件以进一步压缩(这是压缩旋转文件的正确方法吗?)
  4. 如果文件总大小达到 FILES_MAX_SIZE
  5. ,则删除一些最旧的(最好压缩)文件

现在,在没有任何收集器的情况下,我只需使用以下代码片段就可以实现第 1 点和第 3 点

sink = logging::add_file_log(
      keywords::file_name = fileName,
      keywords::rotation_size = FILE_ROTATION_SIZE,
      keywords::scan_method = sinks::file::scan_method::scan_matching,
      keywords::target = logDir.native(),
      keywords::max_size = FILES_MAX_SIZE,
      keywords::format =
      (
         expr::stream
            << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d %H:%M:%S.%f")
            << " " << expr::attr< boost::log::attributes::current_thread_id::value_type >("ThreadID") << " "
            << "<" << expr::attr< Logger::SeverityLevel >("Severity") << "> "
            << expr::message
            << expr::attr< std::wstring >("Suffix")
      ),
      keywords::auto_flush = true

   );

但是,当设置一个收集器 sink->locked_backend()->set_file_collector(_fileCollector); 继承自

boost::log::sinks::file::collector 目前基本上什么都不做 文件仍在继续轮换,但旧文件不会被删除。

这是收集器的样子:

class FileCollector : public boost::log::sinks::file::collector
{
   virtual void store_file(boost::filesystem::path const& src_path) override;

   virtual uintmax_t scan_for_files(boost::log::sinks::file::scan_method method,
                                       boost::filesystem::path const& pattern = boost::filesystem::path(),
                                       unsigned int* counter = 0) override;
};

void FileCollector::store_file(boost::filesystem::path const& src_path)
{
   LOG << "src_path: " << src_path;
}

uintmax_t FileCollector::scan_for_files(boost::log::sinks::file::scan_method method,
                                                boost::filesystem::path const& pattern,
                                                unsigned int* counter)
{
   return 1;
}

scan_for_files() 根本没有被调用。

,我可以看到作者说 max_size 是一个收集器参数,所以我假设我的 FileCollector [=52] 中应该有某种设置它的方法=].调用 sinks::file::make_collector() 而不是继承自定义收集器似乎不是一个选项,因为它没有提供所需 store_file() 回调的方法,我打算将压缩逻辑放在那里。

这是否意味着我应该继续跟踪总大小并在需要时自行处理删除?

谢谢!

is this the right way for compressing rotated files?

是的,如果您必须在您的应用程序中执行此操作。请注意,除非您使用异步日志记录,否则日志文件轮换是同步完成的。这意味着在压缩日志文件时,应用程序中的一些随机日志语句将需要相当长的时间才能完成。

更好的解决方案可能是使用单独的服务,例如 logrotate,它可以在不影响应用程序性能的情况下处理日志轮换和压缩。

Does this mean that I should keep tracking the total size and handle the deletion when needed by myself?

是的,文件收集器全权负责管理轮换的文件。每当调用 store_file 时,您的文件收集器都必须执行必要的步骤来压缩文件并将其存储在目标存储中,并可能删除任何旧文件。

targetmax_size 等参数由 Boost.Log 中实现的文件收集器解释,该文件收集器由 sinks::file::make_collector 创建。如果您实现自己的收集器,则必须以您自己的方式对其进行初始化——可能是通过将这些参数传递给收集器构造函数。