Boost Log Sink-时间戳属性和格式化程序问题

时间:2018-12-14 14:40:44

标签: c++ boost

我实现了一个接收器,它将记录记录到std :: vector并在调用flush函数时将所有日志刷新到控制台。我根据以下内容添加了四个属性:

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", std::string)

但是,当我使用set_formatter函数时,出现编译器错误(MSVC17),提示:

  

错误C2679二进制'<<':未找到使用右手的运算符   'const T'类型的操作数(或者没有可接受的值)   转换)ControllerSoftware c:\ local \ boost_1_68_0 \ boost \ log \ utility \ formatting_ostream.hpp 870

为了清楚起见,我将提供完整的代码:

// 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>
#include <boost/log/core.hpp>
#include <boost/log/sinks/basic_sink_backend.hpp>
#include <boost/log/sinks/sync_frontend.hpp>

#include <vector>
#include <string>


namespace sinks = boost::log::sinks;

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(bool useRamLog = false, boost::log::trivial::severity_level level = boost::log::trivial::info);

        /// Disable logging
        static void disable();

        // Flush log
        static void flushLogs();

        // Convert file path to only the filename
        static std::string path_to_filename(std::string path) 
        {
            return path.substr(path.find_last_of("/\\") + 1);
        }
    private:
        static void registerRamLog();
};

class RamLogSink :
    public sinks::basic_formatted_sink_backend<
    char, 
    sinks::combine_requirements<
    sinks::synchronized_feeding,
    sinks::flushing
    >::type
    >
{
    public:
        // The function consumes the log records that come from the frontend
        void consume(boost::log::record_view const& rec, string_type const& strType);
        // The function flushes the logs in vector
        void flush();
    private:
        std::vector<std::string> logEntries_;

};
// Complete sink type
typedef sinks::synchronous_sink< RamLogSink > sink_t;

#define LOG_LOG_LOCATION(LOGGER, LEVEL, ARG)            \
  BOOST_LOG_SEV(LOGGER, boost::log::trivial::LEVEL)     \
    << boost::log::add_value("Line", std::to_string(__LINE__))          \
    << boost::log::add_value("File", CswLogger::path_to_filename(__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>
#include <boost/log/expressions.hpp>
#include <boost/log/sources/record_ostream.hpp>

#include <string>
#include <iostream>



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


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", std::string)

void CswLogger::init(bool useRamLog, boost::log::trivial::severity_level level)
{
    boost::log::register_simple_formatter_factory<boost::log::trivial::severity_level, char>("Severity");

    if (useRamLog)
    {
        registerRamLog();
    }
    else
    {
        boost::log::add_console_log
        (
            std::clog,
            boost::log::keywords::format = "[%TimeStamp%] [%Severity%] %File%(%Line%): %Message%"
        );
    }   

    boost::log::add_common_attributes();
    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);
}

void CswLogger::flushLogs()
{
    boost::log::core::get()->flush();
}

void CswLogger::registerRamLog()
{
    boost::shared_ptr< RamLogSink > backend(new RamLogSink());
    boost::shared_ptr< sink_t > sink(new sink_t(backend));
    sink->set_formatter(boost::log::expressions::stream
        << "[" << a_timestamp << "] "                   // <--- Compile error here
        << "[" << a_severity << "] "
        << "[" << a_file << "(" << a_line << ")] "
        << boost::log::expressions::message);

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

// RamlogSink Class declarations
void RamLogSink::consume(boost::log::record_view const& rec, string_type const& strType)
{
    logEntries_.emplace_back(strType);
}

void RamLogSink::flush()
{
    for (auto const& entry : logEntries_)
    {
        std::cout << entry << std::endl;
    }
    logEntries_.clear();
}

main.cpp:

#include "cswlogger.h"

CswLogger::init(true);
LOG_TRACE("This should not be printed");
LOG_ERROR("Very bad error that needs to be printed");
int theInt = 234;
LOG_FATAL("TheInt integer is: " << theInt);
CswLogger::flushLogs();

在添加“ Line”属性时,我也遇到了问题:

BOOST_LOG_ATTRIBUTE_KEYWORD(a_line, "Line", int)

我不得不更改为std :: string并将整数转换为

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

否则,行号以空字符串形式出现。

0 个答案:

没有答案