【问题标题】:How to write lines into a logfile from within multiple distributed processes in parallel如何将行从多个分布式进程中并行写入日志文件
【发布时间】:2021-08-19 19:21:50
【问题描述】:

我尝试了 boost::log,但我在文件中根本没有得到任何东西。事实上,该文件甚至没有被创建。

再次重申:重点是让许多客户端进程分布在网络上,将消息写入同一个文件。

而且我对所有这些属性、接收器、源和过滤器毫无用处——我什至不知道它们的用途。事实上,我更喜欢简单的构造函数和流式操作符。

这是当前的代码,根本不产生任何输出:

#include <boost/log/core.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/sinks/text_file_backend.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/sources/record_ostream.hpp>


static int initFileLogging(void)
{       namespace logging = boost::log;
        namespace src = boost::log::sources;
        namespace sinks = boost::log::sinks;
        namespace keywords = boost::log::keywords;
        logging::add_file_log("~/smc.log");
        logging::core::get()->set_filter(logging::trivial::severity >= logging::trivial::info);
        logging::add_common_attributes();
        return 0;
}
int main(int, char**)
{
        initFileLogging();

        namespace logging = boost::log;
        namespace src = boost::log::sources;
        using namespace logging::trivial;
        src::severity_logger< severity_level > lg;
        BOOST_LOG_SEV(lg, debug) << "test" << std::endl;
}

【问题讨论】:

  • 那些进程是同一个应用程序的不同实例(不同的PID)?在您的问题主体中,您似乎非常关注boost::log,您是否尝试过其他解决方案?

标签: c++ linux boost boost-log


【解决方案1】:

我尝试了 boost::log,但我在文件中根本没有得到任何东西。事实上,该文件甚至没有被创建。

在示例代码片段中,您设置了一个全局过滤器,它只通过严重级别为trivial::info 或更高级别的日志记录,但您发出的日志记录级别为trivial::debug,级别较低。日志记录被丢弃,并且由于没有日志记录到达文件接收器后端,因此不会创建文件。

而且我对所有这些属性、接收器、源和过滤器都没有用处

显然,您这样做了,因为您使用的是严重性级别,这是一个属性、一个过滤器和一个文件接收器。您可能还会在最终解决方案中使用不同的接收器类型。

您真的应该阅读库文档中的Design section,以更好地了解库的工作原理,以便有效地使用它。

如何将行从多个分布式进程中并行写入日志文件

关键是让许多客户端进程分布在网络上,将消息写入同一个文件。

如果您确实在网络中的不同机器上有多个进程,那么 Boost.Log 中没有内置解决方案。如果您正在使用类似 UNIX 的系统,您很可能可以访问 syslog 服务,并且 Boost.Log 可以生成带有 syslog sink backend 的 syslog 消息。您可以在所有机器上配置 syslog 服务,以将消息传输到一个公共服务器,该服务器会将它们写入一个公共日志文件。在这里,syslog服务实现了网络通信和文件写入部分。

或者,您可以使用 Boost.ASIO 创建一个 TCP iostream,并将其与 Boost.Log 中的 ostream sink backend 一起使用。 TCP iostream 必须连接到将接收格式化日志记录并将它们写入文件的公共服务器。不过,您必须自己编写服务器。

如果您的多个进程要在同一台机器上运行(即不分布在网络上),那么您可以使用IPC message queue backend 将日志记录传递给将写入日志文件的通用进程。这个后端使用IPC message queue,它是使用共享内存实现的,可能比套接字更有效。在这种情况下,您也必须自己实现服务器进程,有一个 example in the docs

如果这些都不起作用,您总是可以实现your own sink backend

无论如何,您都可以在所有建议中看到一个共同的主题。您需要有一个将写入日志文件的公共进程,以及将其日志记录传递到该公共服务器的客户端进程。问题只是要使用哪种传输方式以及如何实现它。

您可能很想避免使用消息传递设计,而是使用文件锁定来同步多个进程的并发访问到一个公共文件(大概会安装在每台客户端计算机上的共享文件夹中)。首先,我应该注意到 Boost.Log 没有实现文件锁定,因此在像这样的普通文件上使用开箱即用的文件接收器将无法正常工作。接下来,我建议不要使用这种方法,因为 (a) 文件锁定可能无法通过网络共享可靠地工作,并且 (b) 文件锁定会在所有客户端进程中创建一个争用点,这将影响可伸缩性。

【讨论】:

    猜你喜欢
    • 2014-07-02
    • 1970-01-01
    • 2012-09-22
    • 2019-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-26
    相关资源
    最近更新 更多