C++ boost::log 详解:从基础到实战
C++ boost::log 详解:从基础到实战
- 一、C++ boost::log 详解
- 1、引言
- 2、核心概念
- 2.1 、日志记录器 (Logger)
- 2.2 、严重性级别 (Severity Levels)
- 2.3 、属性 (Attributes)
- 2.4 、接收器 (Sinks)
- 2.5 、格式化器 (Formatters)
- 2.6 、过滤器 (Filters)
- 3、基本用法
- 3.1 、最简单的日志记录
- 3.2 、带格式化的基本配置
- 3.3 、文件日志记录
- 4、 高级配置
- 4.1、 自定义日志记录器
- 4.2 、异步日志记录
- 4.3、 条件日志记录
- 二、使用教程
- 1、下载库
- 2、Visual Studio新建工程
- 3、将源码解压到工程目录下
- 4、添加路径
- 5、测试代码
一、C++ boost::log 详解
1、引言
在 C++ 开发中,日志记录是调试、监控和问题排查的重要工具。boost::log是 Boost 库中一个功能强大、高度可配置的日志系统,提供了企业级的日志解决方案。与简单的std::cout或第三方日志库相比,boost::log具有以下优势:
- 高性能:异步日志、过滤机制减少性能开销
- 高度可配置:支持多种输出格式、目标和过滤规则
- 线程安全:内置线程安全机制,适合多线程环境
- 丰富的特性:支持严重性级别、属性、格式化等高级功能
- 跨平台:支持 Windows、Linux、macOS 等主流平台
2、核心概念
2.1 、日志记录器 (Logger)
日志记录器是日志系统的入口点,每个记录器可以有自己的配置和属性。
2.2 、严重性级别 (Severity Levels)
boost::log定义了标准的严重性级别:
trace- 最详细的调试信息debug- 调试信息info- 一般信息(默认)warning- 警告信息error- 错误信息fatal- 致命错误
2.3 、属性 (Attributes)
属性是与日志记录关联的键值对,可以包含:
- 时间戳
- 线程ID
- 进程ID
- 源代码位置
- 自定义属性
2.4 、接收器 (Sinks)
接收器决定日志的输出目标:
- 控制台输出
- 文件输出
- 网络输出
- 系统日志 (syslog)
2.5 、格式化器 (Formatters)
格式化器控制日志消息的显示格式。
2.6 、过滤器 (Filters)
过滤器决定哪些日志记录应该被处理。
3、基本用法
3.1 、最简单的日志记录
#include<boost/log/trivial.hpp>intmain(){// 使用 BOOST_LOG_TRIVIAL 宏记录日志BOOST_LOG_TRIVIAL(trace)<<"这是一条 trace 级别的日志";BOOST_LOG_TRIVIAL(debug)<<"这是一条 debug 级别的日志";BOOST_LOG_TRIVIAL(info)<<"这是一条 info 级别的日志";BOOST_LOG_TRIVIAL(warning)<<"这是一条 warning 级别的日志";BOOST_LOG_TRIVIAL(error)<<"这是一条 error 级别的日志";BOOST_LOG_TRIVIAL(fatal)<<"这是一条 fatal 级别的日志";return0;}3.2 、带格式化的基本配置
#include<boost/log/trivial.hpp>#include<boost/log/utility/setup/console.hpp>#include<boost/log/utility/setup/common_attributes.hpp>intmain(){// 初始化控制台接收器boost::log::add_console_log(std::clog,boost::log::keywords::format="[%TimeStamp%] [%Severity%]: %Message%");// 添加常用属性(时间戳、进程ID、线程ID)boost::log::add_common_attributes();// 记录日志BOOST_LOG_TRIVIAL(info)<<"应用程序启动";BOOST_LOG_TRIVIAL(warning)<<"内存使用率较高";BOOST_LOG_TRIVIAL(error)<<"文件打开失败";return0;}3.3 、文件日志记录
#include<boost/log/trivial.hpp>#include<boost/log/utility/setup/file.hpp>#include<boost/log/utility/setup/common_attributes.hpp>intmain(){// 设置文件接收器boost::log::add_file_log(boost::log::keywords::file_name="app_%Y%m%d_%H%M%S.log",boost::log::keywords::rotation_size=10*1024*1024,// 10MBboost::log::keywords::max_size=100*1024*1024,// 100MBboost::log::keywords::time_based_rotation=boost::log::sinks::file::rotation_at_time_point(0,0,0),boost::log::keywords::format="[%TimeStamp%] [%Severity%] [%ProcessID%:%ThreadID%]: %Message%",boost::log::keywords::auto_flush=true);// 添加常用属性boost::log::add_common_attributes();// 记录日志for(inti=0;i<100;++i){BOOST_LOG_TRIVIAL(info)<<"处理第 "<<i<<" 个任务";}return0;}4、 高级配置
4.1、 自定义日志记录器
#include<boost/log/core.hpp>#include<boost/log/trivial.hpp>#include<boost/log/expressions.hpp>#include<boost/log/sources/severity_logger.hpp>#include<boost/log/utility/setup/file.hpp>#include<boost/log/utility/setup/console.hpp>#include<boost/log/utility/setup/common_attributes.hpp>namespacelogging=boost::log;namespacesrc=boost::log::sources;namespacekeywords=boost::log::keywords;namespaceexpr=boost::log::expressions;// 定义自定义严重性级别enumseverity_level{normal,notification,warning,error,critical};// 重载 << 操作符以便输出自定义级别std::ostream&operator<<(std::ostream&strm,severity_level level){staticconstchar*strings[]={"normal","notification","warning","error","critical"};if(static_cast<std::size_t>(level)<sizeof(strings)/sizeof(*strings))strm<<strings[level];elsestrm<<static_cast<int>(level);returnstrm;}intmain(){// 创建自定义日志记录器src::severity_logger<severity_level>lg;// 设置控制台输出logging::add_console_log(std::clog,keywords::filter=expr::attr<severity_level>("Severity")>=warning,keywords::format=expr::stream<<expr::format_date_time<boost::posix_time::ptime>("TimeStamp","%Y-%m-%d %H:%M:%S")<<" ["<<expr::attr<severity_level>("Severity")<<"] "<<expr::message);// 设置文件输出logging::add_file_log(keywords::file_name="custom_%Y%m%d.log",keywords::filter=expr::attr<severity_level>("Severity")>=normal,keywords::format=expr::stream<<expr::format_date_time<boost::posix_time::ptime>("TimeStamp","%Y-%m-%d %H:%M:%S.%f")<<" ["<<expr::attr<severity_level>("Severity")<<"] "<<"["<<expr::attr<attrs::current_thread_id::value_type>("ThreadID")<<"] "<<expr::message);// 添加常用属性logging::add_common_attributes();// 记录不同级别的日志BOOST_LOG_SEV(lg,normal)<<"正常操作";BOOST_LOG_SEV(lg,notification)<<"系统通知";BOOST_LOG_SEV(lg,warning)<<"警告信息";BOOST_LOG_SEV(lg,error)<<"错误发生";BOOST_LOG_SEV(lg,critical)<<"严重错误!";return0;}4.2 、异步日志记录
#include<boost/log/core.hpp>#include<boost/log/trivial.hpp>#include<boost/log/expressions.hpp>#include<boost/log/sinks/async_frontend.hpp>#include<boost/log/sinks/text_file_backend.hpp>#include<boost/log/utility/setup/common_attributes.hpp>namespacelogging=boost::log;namespacesinks=boost::log::sinks;namespacekeywords=boost::log::keywords;typedefsinks::asynchronous_sink<sinks::text_file_backend>sink_t;intmain(){// 创建异步接收器后端boost::shared_ptr<sinks::text_file_backend>backend=boost::make_shared<sinks::text_file_backend>(keywords::file_name="async_%Y%m%d_%H%M%S_%N.log",keywords::rotation_size=10*1024*1024,keywords::time_based_rotation=sinks::file::rotation_at_time_point(0,0,0));// 创建异步接收器前端boost::shared_ptr<sink_t>sink(newsink_t(backend));// 设置格式化sink->set_formatter(logging::expressions::stream<<logging::expressions::format_date_time<boost::posix_time::ptime>("TimeStamp","%Y-%m-%d %H:%M:%S")<<" ["<<logging::trivial::severity<<"] "<<logging::expressions::message);// 将接收器添加到核心logging::core::get()->add_sink(sink);// 添加常用属性logging::add_common_attributes();// 高性能日志记录(不会阻塞主线程)for(inti=0;i<100000;++i){BOOST_LOG_TRIVIAL(info)<<"异步日志记录测试 "<<i;}// 刷新并移除接收器sink->flush();logging::core::get()->remove_sink(sink);return0;}4.3、 条件日志记录
#include<boost/log/trivial.hpp>#include<boost/log/utility/setup/console.hpp>#include<boost/log/utility/setup/common_attributes.hpp>// 条件日志宏#defineLOG_IF(condition,level)\if(condition)BOOST_LOG_TRIVIAL(level)#defineLOG_LEVEL(level)BOOST_LOG_TRIVIAL(level)intmain(){// 初始化日志boost::log::add_console_log(std::clog);boost::log::add_common_attributes();booldebug_mode=true;interror_count=5;// 条件日志记录LOG_IF(debug_mode,debug)<<"调试信息:当前在调试模式";LOG_IF(error_count>0,error)<<"发现 "<<error_count<<" 个错误";// 根据条件设置日志级别if(debug_mode){// 设置只记录 debug 及以上级别的日志boost::log::core::get()->set_filter(boost::log::trivial::severity>=boost::log::trivial::debug);}else{// 设置只记录 info 及以上级别的日志boost::log::core::get()->set_filter(boost::log::trivial::severity>=boost::log::trivial::info);}LOG_LEVEL(trace)<<"这条 trace 日志在非调试模式下不会显示";LOG_LEVEL(debug)<<"调试信息";LOG_LEVEL(info)<<"一般信息";return0;}二、使用教程
1、下载库
访问链接https://www.boost.org/
2、Visual Studio新建工程
3、将源码解压到工程目录下
新建一个main.cpp文件
将下载的压缩包解压到main.cpp同级目录,并改名为boost
4、添加路径
5、测试代码
#include<iostream>#include<string>#include<boost/lexical_cast.hpp>// 只需这一个头文件intmain(){// ==========================================// 1. 字符串 → 整数// ==========================================std::string str_num="12345";intnum=boost::lexical_cast<int>(str_num);std::cout<<"字符串转 int: "<<num<<"\n";// ==========================================// 2. 字符串 → 浮点数// ==========================================std::string str_float="3.1415926";doublepi=boost::lexical_cast<double>(str_float);std::cout<<"字符串转 double: "<<pi<<"\n";// ==========================================// 3. 数字 → 字符串// ==========================================intage=28;std::string str_age=boost::lexical_cast<std::string>(age);std::cout<<"int 转字符串: "<<str_age<<"\n";// ==========================================// 4. 浮点数 → 字符串// ==========================================doubleprice=99.8;std::string str_price=boost::lexical_cast<std::string>(price);std::cout<<"double 转字符串: "<<str_price<<"\n";// ==========================================// 5. 布尔值 ↔ 字符串// ==========================================boolb=true;std::string str_bool=boost::lexical_cast<std::string>(b);std::cout<<"bool 转字符串: "<<str_bool<<"\n";boolb2=boost::lexical_cast<bool>("1");std::cout<<"字符串 \"1\" 转 bool: "<<std::boolalpha<<b2<<"\n";// ==========================================// 6. 错误处理(转换失败会抛异常)// ==========================================try{// 这个字符串无法转数字,会抛异常std::string bad_str="abc";intbad_num=boost::lexical_cast<int>(bad_str);std::cout<<bad_num<<"\n";}catch(constboost::bad_lexical_cast&e){std::cout<<"转换失败: "<<e.what()<<"\n";}return0;}运行结果
字符串转int:12345字符串转double:3.14159int转字符串:28double转字符串:99.799999999999997bool转字符串:1字符串"1"转bool:true转换失败:bad lexical cast:source type value couldnotbe interpreted as target C:\Users\徐鹏\Desktop\新建文件夹\Project2\x64\Debug\Project2.exe(进程30564)已退出,代码为0(0x0)。 要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。 按任意键关闭此窗口...