c++ - 如何从 boost log sink 组织线程安全读取?

标签 c++ c++11 boost boost-log

我正在寻找一种正确的方法来安全地从 boost::log::sinks::text_ostream_backend 获取文本数据。 我目前仅在所有内容都记录在接收器后端后才获取数据。我想在仍然可以生成数据的同时获取后端内部缓冲区 (m_ss) 的拷贝。

using Logger = boost::log::sources::severity_channel_logger_mt<boost::log::trivial::severity_level, std::string>;

class MyClass
{
  mutable std::mutex  m_mutex;
  mutable Logger      m_logger {boost::log::keywords::channel = "MyClass"};
  std::stringstream   m_ss;
  bool                m_completed {false};

public:
  void initLogging(const std::string& id)
  {
    using namespace boost::log;
    using Sink = sinks::synchronous_sink<sinks::text_ostream_backend>;

    auto backend = boost::make_shared<sinks::text_ostream_backend>();
    backend->add_stream(boost::shared_ptr<std::stringstream>(&m_ss, boost::null_deleter()));
    auto sink = boost::make_shared<Sink>(backend);
    sink->set_filter(expressions::has_attr<std::string>("ID") && expressions::attr<std::string>("ID") == id);

    core::get()->add_sink(sink);

    m_logger.add_attribute("ID", attributes::constant<std::string>(id));
  }

  void doSomething()
  {
    BOOST_LOG_SEV(logger, boost::log::trivial::severity_level::debug) << "TEST";
    BOOST_LOG_SEV(logger, boost::log::trivial::severity_level::error) << "TEST";

    // Stop write logs
    std::lock_guard<std::mutex> lock(m_mutex);
    m_completed = true;
  }

  void access()
  {
    std::lock_guard<std::mutex> lock(m_mutex);

    if (m_completed) {
      // Can read from stream
      useStreamData(m_ss.str());
    }
  }
};

最佳答案

如果流仅由接收器后端访问,那么同步访问的最简单方法是使用 locked_backend

auto locked_backend = sink->locked_backend();

这里,locked_backend 对象是一个智能指针,它锁定接收器前端,从而防止日志记录线程访问后端,从而防止访问 m_ss 流。当 locked_backend 存在时,您可以安全地使用 m_ss

还有其他方法可以实现这一点。例如,您可以实现 custom sink backend或者实现一个允许同步访问累积数据的流缓冲区。有许多关于编写自定义流缓冲区的文章和博客文章,here就是一个例子。

关于c++ - 如何从 boost log sink 组织线程安全读取?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51844561/

相关文章:

c# - C++ 在 Visual Studio 2010 中从二进制文件读取 void* 数据作为 utf8

c++ - 如何确定点是否在形状上和在形状上?

c++ - 使用指针打印函数地址

c++ - 在 Qt Creator 中使用 Boost Python

c++ - 如何在mingw中启用异常处理

c++ - 这段代码安全吗,是否可以从构造函数 C++ 生成线程?

c++ - 回归虚无?

c++ - 模板库的编译器内存消耗(boost + Eigen)

c++ - 闭源库包括 boost 分发

c++ - 可按参数类型更改 "return type template"