boost.log - 在单个接收器上进行多线程写入的一个很好的示例

问题描述 投票:0回答:1

假设只有一个接收器(例如一个文件),并且有几个线程正在其上写入日志。

我搜索了很多,但不幸的是找不到一个好的例子。

我已经尝试了每个线程多个

channel
并崩溃了。

#include <iostream>
#include <boost/log/expressions.hpp>
#include <boost/log/sources/severity_channel_logger.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/sinks.hpp>
#include <thread>

namespace logging = boost::log;
namespace src = boost::log::sources;
namespace expr = boost::log::expressions;
namespace keywords = boost::log::keywords;
namespace sinks = boost::log::sinks;

// We define our own severity levels
enum severity_level
{
    normal,
    notification,
    warning,
    error,
    critical
};

// Define the attribute keywords
BOOST_LOG_ATTRIBUTE_KEYWORD(line_id, "LineID", unsigned int)
BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", severity_level)
BOOST_LOG_ATTRIBUTE_KEYWORD(channel, "Channel", std::string)

std::ostream& operator<< (std::ostream& strm, severity_level level)
{
    static const char* strings[] =
            {
                    "normal",
                    "notification",
                    "warning",
                    "error",
                    "critical"
            };

    if (static_cast< std::size_t >(level) < sizeof(strings) / sizeof(*strings))
        strm << strings[level];
    else
        strm << static_cast< int >(level);

    return strm;
}

void init()
{
    // Create a minimal severity table filter
    typedef expr::channel_severity_filter_actor< std::string, severity_level > min_severity_filter;
    min_severity_filter min_severity = expr::channel_severity_filter(channel, severity);

    // Set up the minimum severity levels for different channels
    min_severity["general"] = notification;
    min_severity["network"] = warning;
    min_severity["gui"] = error;

    logging::add_file_log
            (
                    keywords::file_name = "sample_%N.log",
                    keywords::rotation_size = 1000 * 1024 * 1024,
                    keywords::time_based_rotation = sinks::file::rotation_at_time_point(0, 0, 0),
                    keywords::filter = min_severity || severity >= critical,
                    keywords::format =
                            (
                                    expr::stream
                                            << line_id
                                            << ": <" << severity
                                            << "> [" << channel << "] "
                                            << expr::smessage
                            )
            );


    logging::add_console_log
            (
                    std::clog,
                    keywords::filter = min_severity || severity >= critical,
                    keywords::format =
                            (
                                    expr::stream
                                            << line_id
                                            << ": <" << severity
                                            << "> [" << channel << "] "
                                            << expr::smessage
                            )
            );

// Define our logger type
typedef src::severity_channel_logger< severity_level, std::string > logger_type;

void test_logging(logger_type lg, std::string const channel_name)
{
    for(int i=0; i<1000; i++) {
        BOOST_LOG_CHANNEL_SEV(lg, channel_name, normal) << "A normal severity level message";
        BOOST_LOG_CHANNEL_SEV(lg, channel_name, notification) << "A notification severity level message";
        BOOST_LOG_CHANNEL_SEV(lg, channel_name, warning) << "A warning severity level message";
        BOOST_LOG_CHANNEL_SEV(lg, channel_name, error) << "An error severity level message";
        BOOST_LOG_CHANNEL_SEV(lg, channel_name, critical) << "A critical severity level message";
    }
}


int main(int, char*[])
{
    init();
    logging::add_common_attributes();

    logger_type lg;

    std::thread t1(test_logging, lg, "general");
    std::thread t2(test_logging, lg, "network");
    std::thread t3(test_logging, lg, "gui");
    std::thread t4(test_logging, lg, "filesystem");

    getchar();

    return 0;
}
c++ multithreading boost-log boost-logging
1个回答
0
投票

我测试了上面的代码,在 init 方法的末尾添加了缺少的“}”后,我得到了“在没有活动异常的情况下终止调用”。 我认为这与 C++ 在没有活动异常的情况下终止调用具有相同的根本原因。 解决方案:在工作线程上调用 join;

int main(int, char*[]) .... std::thread t4(test_logging, lg, "filesystem"); t1.join(); t2.join(); t3.join(); t4.join(); getchar(); return 0; }
    
© www.soinside.com 2019 - 2024. All rights reserved.