You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++ Boost Log:将Logger作为参数传入类构造器而非使用全局Logger

解决Boost Logger从全局实例改为构造器传入的问题

问题背景

原本实现的CC2Logger类依赖全局的GLOBAL_C2LOGGER,现在需要改为通过构造器传入boost::shared_ptr类型的Logger实例,让多个CC2Logger对象可以共享不同的Logger实例,按Tag输出到对应文件。之前尝试传递shared_ptr和使用BOOST_LOG_SEV宏时遇到语法错误,无法正常工作。

修改后的代码实现

CC2Logger.h

#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/trivial.hpp>
#include <boost/shared_ptr.hpp>
#include <string>
#include <sstream>

BOOST_LOG_ATTRIBUTE_KEYWORD(tag_attr, "Tag", std::string);

class CC2Logger {
public:
    // 修改构造器,添加Logger的shared_ptr参数
    CC2Logger(const boost::shared_ptr<boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level>>& logger_ptr,
              const std::string& folderName = "logs/", 
              const std::string& fileBaseName = "LOG_", 
              const std::string& fileExtName = ".log");

    void log(boost::log::trivial::severity_level logMessageLevel, const std::string& logMessage);
    void log(boost::log::trivial::severity_level logMessageLevel, const std::stringstream& logMessage);

private:
    boost::shared_ptr<boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level>> m_ptrLogger;
    const std::string m_tag;
    const std::string m_folderName;
    const std::string m_fileBaseName;
    const std::string m_fileExtName;
};

CC2Logger.cc

#include "CC2Logger.h"
#include <boost/log/expressions.hpp>
#include <boost/log/sinks/text_file_backend.hpp>
#include <boost/log/utility/setup/file.hpp>

namespace keywords = boost::log::keywords;

// 假设ROTATE_FILE_AFTER_NUM_BYTES和GLOBAL_C2LOGGER_LOGFMT_STRING已定义
constexpr size_t ROTATE_FILE_AFTER_NUM_BYTES = 1024 * 1024 * 10; // 示例:10MB
const char* GLOBAL_C2LOGGER_LOGFMT_STRING = "%TimeStamp% [%Severity%] [%Tag%] %Message%";

CC2Logger::CC2Logger(const boost::shared_ptr<boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level>>& logger_ptr,
                     const std::string& folderName, 
                     const std::string& fileBaseName, 
                     const std::string& fileExtName) :
    m_ptrLogger(logger_ptr),
    m_folderName(folderName), 
    m_fileBaseName(fileBaseName), 
    m_fileExtName(fileExtName), 
    m_tag(fileBaseName) {
        
    auto sink = boost::log::add_file_log(
        keywords::target = m_folderName,
        keywords::file_name = m_fileBaseName + "_%Y%m%d-%H%M%S-%4N" + m_fileExtName,
        keywords::rotation_size = ROTATE_FILE_AFTER_NUM_BYTES
    );
    sink->set_formatter(boost::log::parse_formatter(GLOBAL_C2LOGGER_LOGFMT_STRING));
    sink->set_filter(tag_attr == m_tag);
}

void CC2Logger::log(boost::log::trivial::severity_level logMessageLevel, const std::string& logMessage) {
    BOOST_LOG_SCOPED_THREAD_TAG("Tag", m_tag);
    // 对shared_ptr解引用,传入Logger实例的引用给BOOST_LOG_SEV
    BOOST_LOG_SEV(*m_ptrLogger, logMessageLevel) << logMessage;
}

void CC2Logger::log(boost::log::trivial::severity_level logMessageLevel, const std::stringstream& logMessage) {
    BOOST_LOG_SCOPED_THREAD_TAG("Tag", m_tag);
    const std::string logMessage_str = logMessage.str();
    BOOST_LOG_SEV(*m_ptrLogger, logMessageLevel) << logMessage_str;
}

修正后的main函数

注意要先实例化Logger对象,不能使用空的shared_ptr:

#include "CC2Logger.h"
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/utility/setup/formatter_parser.hpp>

int main(int argc, char* argv[]) {
    boost::log::add_common_attributes();
    boost::log::register_simple_formatter_factory<boost::log::trivial::severity_level, char>("Severity");
    
    // 实例化Logger对象,不能用空的shared_ptr
    boost::shared_ptr<boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level>> a_logger(
        new boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level>()
    );
    boost::shared_ptr<boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level>> b_logger(
        new boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level>()
    );
    
    CC2Logger CTestLogger_A(a_logger, "logs/", "LOG_aA", ".log");
    CC2Logger CTestLogger_B(a_logger, "logs/", "LOG_aB", ".log");
    CC2Logger CTestLogger_C(b_logger, "logs/", "LOG_bC", ".log");

    CTestLogger_A.log(boost::log::trivial::trace, "A simple trace message to file LOG_aA...log using a_logger.");
    CTestLogger_A.log(boost::log::trivial::info, "A simple info message to file LOG_aA...log also using a_logger."); 
    CTestLogger_C.log(boost::log::trivial::info, "A simple info message to file LOG_bC...log using b_logger.");

    return 0;
}

关键要点说明

  1. 成员变量与构造器初始化:
    • 在类中添加boost::shared_ptr类型的成员m_ptrLogger,构造器接收该类型的const引用,直接在初始化列表中赋值m_ptrLogger(logger_ptr)即可完成共享。
  2. BOOST_LOG_SEV宏的正确用法:
    • BOOST_LOG_SEV需要接收Logger实例的引用,因此要对shared_ptr进行解引用操作*m_ptrLogger,不能直接传入shared_ptr对象。
  3. main函数的注意事项:
    • 必须先创建Logger的实例(通过new或make_shared),不能使用空的shared_ptr,否则会导致空指针访问错误。

内容的提问来源于stack exchange,提问作者mikefo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 15:45:14