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; }
关键要点说明
- 成员变量与构造器初始化:
- 在类中添加
boost::shared_ptr类型的成员m_ptrLogger,构造器接收该类型的const引用,直接在初始化列表中赋值m_ptrLogger(logger_ptr)即可完成共享。
- 在类中添加
- BOOST_LOG_SEV宏的正确用法:
BOOST_LOG_SEV需要接收Logger实例的引用,因此要对shared_ptr进行解引用操作*m_ptrLogger,不能直接传入shared_ptr对象。
- main函数的注意事项:
- 必须先创建Logger的实例(通过
new或make_shared),不能使用空的shared_ptr,否则会导致空指针访问错误。
- 必须先创建Logger的实例(通过
内容的提问来源于stack exchange,提问作者mikefo
相关产品推荐
相关产品推荐

