如何使用Boost日志设置每个日志源的严重性级别?

时间:2017-08-24 09:13:00

标签: c++ logging boost boost-log

我是Boost Log的新手,并且在做一些非常简单的事情时遇到了麻烦。 我尝试创建一个记录器并为其分配一个级别(例如警告,信息,跟踪等),并过滤掉(出于性能原因)发送到此记录器的任何日志,其分配的级别较低到记录器,在Logging核心级别,而不是在接收器级别。 例如(伪代码):

logger lg;
lg.setLevel(Warn);
BOOST_LOG_TRIVIAL(trace) << "A trace severity message"; // Will be filtered
BOOST_LOG_TRIVIAL(warn) << "A warning severity message"; // Won't be filtered

我很确定这可以通过Boost Log实现,但由于某种原因我无法做到这一点。

谢谢,

奥马尔。

2 个答案:

答案 0 :(得分:2)

Boost.Log中的记录器(源)级别没有过滤器。您可以全局(在日志记录核心中)或每个接收器设置过滤器,并且将统一处理来自所有源的日志记录。

您可以使用channels实现所需的行为,方法是为每个记录器分配一个频道并根据频道和严重性级别进行过滤。

BOOST_LOG_ATTRIBUTE_KEYWORD(a_severity, "Severity", LogSeverity)
BOOST_LOG_ATTRIBUTE_KEYWORD(a_channel, "Channel", std::string)

typedef sources::severity_channel_logger< LogSeverity, std::string > logger_type;

logger_type lg_a(keywords::channel = "A");
logger_type lg_b(keywords::channel = "B");

core::get()->set_filter
(
    (a_channel == "A" && a_severity >= LogSeverity::info) ||
    (a_channel == "B" && a_severity >= LogSeverity::warning)
);

该库还提供a specialized filter,可用于简化此操作。

auto min_severity = expressions::channel_severity_filter(a_channel, a_severity);
min_severity["A"] = LogSeverity::info;
min_severity["B"] = LogSeverity::warning;

core::get()->set_filter(min_severity);

请注意,您实际上不限于每个频道只有一个记录器 - 您可以创建多个记录器,并且每个记录器的记录将以相同的方式处理。

答案 1 :(得分:1)

我建议您使用this link作为参考...

下面是我的代码的一小部分内容。在这个小片段中,我使用了同步后端,但您可以自由使用异步后端。

log.hpp

#pragma once

#include <boost/log/common.hpp>
#include <boost/log/sources/severity_logger.hpp>

enum class LogSeverity {
    trace, debug, info, warning, error, fatal
};

extern boost::log::sources::severity_logger<LogSeverity> g_logger;

void log_set_filter(LogSeverity level);
void init_logger();

#define LOG_TRACE   BOOST_LOG_SEV(g_logger, LogSeverity::trace)
#define LOG_DEBUG   BOOST_LOG_SEV(g_logger, LogSeverity::debug)
#define LOG_INFO    BOOST_LOG_SEV(g_logger, LogSeverity::info)
#define LOG_WARNING BOOST_LOG_SEV(g_logger, LogSeverity::warning)
#define LOG_ERROR   BOOST_LOG_SEV(g_logger, LogSeverity::error)
#define LOG_FATAL   BOOST_LOG_SEV(g_logger, LogSeverity::fatal)

log.cpp

#include "bumper-common/log.hpp"
#include <boost/log/common.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/sinks/sync_frontend.hpp>
#include <boost/log/sinks/text_ostream_backend.hpp>
#include <boost/log/core.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/attributes.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/support/date_time.hpp>
#include <boost/core/null_deleter.hpp>
#include <iomanip>
#include <iostream>

using namespace boost::log;

using LogTextSink = sinks::synchronous_sink<sinks::text_ostream_backend>;

LogSeverity g_logLevel = LogSeverity::info;
sources::severity_logger<LogSeverity> g_logger;

BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", LogSeverity)
BOOST_LOG_ATTRIBUTE_KEYWORD(timestamp, "TimeStamp", boost::posix_time::ptime)
BOOST_LOG_ATTRIBUTE_KEYWORD(log_thread_id, "ThreadID", attributes::current_thread_id::value_type)

std::ostream& operator<< (std::ostream& strm, LogSeverity level)
{
    static const std::array<std::string, 6> strings
    {
        std::string{"trace"},
        std::string{"debug"},
        std::string{"info"},
        std::string{"warn"},
        std::string{"error"},
        std::string{"fatal"}
    };

    strm << strings[static_cast< std::size_t >(level)];

    return strm;
}

void init_logger()
{
    boost::shared_ptr<std::ostream> stream{&std::cout,
        boost::null_deleter{}};

    auto loggerSink = boost::make_shared<LogTextSink>();

    add_common_attributes();

    loggerSink->locked_backend()->add_stream(stream);
    loggerSink->locked_backend()->auto_flush(true);

    loggerSink->set_filter(severity >= g_logLevel);

    loggerSink->set_formatter( expressions::stream
        << "[" << expressions::format_date_time(timestamp, "%H:%M:%S.%f") << "] ["
        << std::setw(5) << std::left << severity << "] ["
        << log_thread_id << "] "
        << expressions::smessage
    );

    boost::log::core::get()->add_sink(loggerSink);
}

void log_set_filter(LogSeverity level)
{
    g_logLevel = level;
}

希望这可以帮到你。我对这个库感到很困扰。所以我强烈建议您阅读我之前发布的文档。