首页 > 解决方案 > boost.log - 在单个接收器上进行多线程写入的一个很好的例子

问题描述

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

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

我已经channel为每个线程尝试了多个 s 并崩溃了。

#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++multithreadingboost-logboost-logging

解决方案


推荐阅读