【问题标题】:Boost BOOST_LOG_SEV with custom attributes使用自定义属性提升 BOOST_LOG_SEV
【发布时间】:2019-05-13 15:54:38
【问题描述】:

我需要一个 Boost 记录器,它记录到控制台(然后记录到文件),具有以下参数: “[%TimeStamp%] [%Severity%] [%File%(%Line%)] %Message%”。 我已阅读 Boost.Log v2 文档并从其他地方获得了一些“灵感”,但我无法真正让它发挥作用。

// cswlogger.h
#pragma once
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/attributes/mutable_constant.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/sources/global_logger_storage.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/utility/manipulators/add_value.hpp>


BOOST_LOG_GLOBAL_LOGGER(sysLogger,
boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level>);


class CswLogger 
{
public:
    /// Init with default info level logging
    static void init(boost::log::trivial::severity_level level = boost::log::trivial::info);

    /// Disable logging
    static void disable();
};

#define LOG_LOG_LOCATION(LOGGER, LEVEL, ARG)            \
  BOOST_LOG_SEV(LOGGER, boost::log::trivial::LEVEL)     \
    << boost::log::add_value("Line", __LINE__)          \
    << boost::log::add_value("File", __FILE__) << ARG


/// System Log macros.
/// TRACE < DEBUG < INFO < WARN < ERROR < FATAL
#define LOG_TRACE(ARG) LOG_LOG_LOCATION(sysLogger::get(), trace, ARG);
#define LOG_DEBUG(ARG) LOG_LOG_LOCATION(sysLogger::get(), debug, ARG);
#define LOG_INFO(ARG)  LOG_LOG_LOCATION(sysLogger::get(), info, ARG);
#define LOG_WARN(ARG)  LOG_LOG_LOCATION(sysLogger::get(), warning, ARG);
#define LOG_ERROR(ARG) LOG_LOG_LOCATION(sysLogger::get(), error, ARG);
#define LOG_FATAL(ARG) LOG_LOG_LOCATION(sysLogger::get(), fatal, ARG);

还有源文件:

//  cswlogger.cpp

#include "cswlogger.h"

#include <boost/log/core.hpp>
#include <boost/log/common.hpp>
#include <boost/log/attributes.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/utility/setup/settings.hpp>
#include <boost/log/sinks/sync_frontend.hpp>

BOOST_LOG_GLOBAL_LOGGER_DEFAULT(sysLogger,
    boost::log::sources::severity_channel_logger_mt<boost::log::trivial::severity_level>);


void CswLogger::init(boost::log::trivial::severity_level level) 
{
    boost::log::add_console_log
    (
        std::clog,
        boost::log::keywords::format = "[%TimeStamp%] [%Severity%] [%File%(%Line%)] %Message%"
    );

    boost::log::core::get()->set_filter
    (
        boost::log::trivial::severity >= level
    );

    // Indicate start of logging
    LOG_INFO("Log Start");
}

void CswLogger::disable() 
{
    boost::log::core::get()->set_logging_enabled(false);
}

main.cpp

#include "cswlogger.h"
CswLogger::init();
LOG_INFO("This is a info trace");

它的输出将是:“[ ] [ ] main.cpp(3) 这是一个信息跟踪”

缺少时间戳和严重性参数。 是否可以使用“BOOST_LOG_SEV”日志宏并添加自定义日志参数,还是我需要使用其他方法?

【问题讨论】:

    标签: boost


    【解决方案1】:

    首先,输出中缺少TimeStamp 属性,因为您尚未将其添加到日志记录核心。你可以按照here的描述添加:

    boost::log::core::get()->add_global_attribute(
        "TimeStamp",
        boost::log::attributes::local_clock());
    

    或者您可以通过调用add_common_attributes将其添加为常用属性之一。

    接下来,Severity 属性出现了,它由记录器提供。但是,从字符串解析的过滤器和格式化程序默认不支持该属性的值类型(boost::log::trivial::severity_level)。您可以通过两种方式解决此问题。

    首先,您可以切换到日志接收器的手动设置,这将允许您将接收器的过滤器和格式化程序设置为 lambda 表达式。这样,您将能够向格式化程序提供属性类型。例如:

    BOOST_LOG_ATTRIBUTE_KEYWORD(a_timestamp, "TimeStamp", boost::log::attributes::local_clock::value_type)
    BOOST_LOG_ATTRIBUTE_KEYWORD(a_severity, "Severity", boost::log::trivial::severity_level)
    BOOST_LOG_ATTRIBUTE_KEYWORD(a_file, "File", std::string)
    BOOST_LOG_ATTRIBUTE_KEYWORD(a_line, "Line", int)
    
    typedef boost::log::sinks::synchronous_sink< boost::log::sinks::text_ostream_backend > sink_t;
    auto sink = boost::make_shared< sink_t >();
    sink->set_formatter(boost::log::expressions::ostream
        << "[" << a_timestamp << "] "
        << "[" << a_severity << "] "
        << "[" << a_file << "(" << a_line << ")] "
        << boost::log::expressions::message);
    
    boost::log::core::get()->add_sink(sink);
    

    或者,您可以为Severity 属性注册格式化程序和过滤器工厂,以便格式化程序和过滤器解析器能够将该属性与boost::log::trivial::severity_level 类型相关联。这在here 中有详细描述。在您的情况下,您可以在解析任何格式化程序之前添加此调用(即在 add_console_log 调用之前):

    boost::log::register_simple_formatter_factory<
        boost::log::trivial::severity_level, char >("Severity");
    

    【讨论】:

    • 感谢 Andrey 的详细解释,感谢您使用这个库!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-05
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多