场景想象:就像给程序装行车记录仪
- 程序崩溃时查"事故录像"(调试日志)
- 监控程序运行状态(信息记录)
- 记录用户操作轨迹(审计日志)
手动写日志的痛点:
// 传统做法:又累又不安全
void manual_log() {
ofstream file("log.txt");
file << "Error: 文件打开失败"; // 要自己处理线程安全
file.close(); // 可能忘记关闭
}
二、五大热门日志库推荐1. spdlog(秋名山车神级)
- 特点:速度飞快(异步日志)、功能丰富
- 适合:高性能需求项目
#include <spdlog/spdlog.h>
void use_spdlog() {
// 创建控制台日志器
auto console = spdlog::stdout_color_mt("console");
console->info("欢迎使用spdlog!"); // 打印绿色信息
// 创建文件日志器(每天滚动)
auto file_logger = spdlog::daily_logger_mt("file_log", "logs/daily.txt");
file_logger->error("发现严重错误:代码第{}行", 25);
}
2. glog(谷歌大佬专用)
- 特点:稳定可靠、支持分级日志
- 适合:大型长期运行系统
#include <glog/logging.h>
void use_glog() {
google::InitGoogleLogging("MyApp");
FLAGS_log_dir = "logs/"; // 设置日志目录
LOG(INFO) << "系统启动中..."; // 普通信息
LOG(WARNING) << "内存使用超过80%"; // 黄色警告
LOG(ERROR) << "数据库连接失败"; // 红色错误
}
3. Boost.Log(瑞士军刀)
- 特点:功能全面、高度可定制
- 适合:复杂日志需求项目
#include <boost/log/trivial.hpp>
void use_boost_log() {
BOOST_LOG_TRIVIAL(info) << "用户登录成功";
BOOST_LOG_TRIVIAL(warning) << "检测到异常访问";
BOOST_LOG_TRIVIAL(error) << "支付验证失败";
}
三、什么是线程安全?生活化解释:
想象超市收银台:
- 线程安全:多个顾客(线程)排队结账,收银员一次只服务一个
- 非线程安全:顾客们同时抢着结账,钱会算错
代码中的线程安全问题:
// 不安全示例:多个线程同时写文件
void unsafe_log(const string& msg) {
ofstream file("log.txt", ios::app);
file << msg << endl; // 可能发生写入冲突
}
// 安全示例:加锁保护
mutex log_mutex;
void safe_log(const string& msg) {
lock_guard<mutex> guard(log_mutex); // 自动上锁
ofstream file("log.txt", ios::app);
file << msg << endl;
}
四、各日志库的线程安全性
日志库 | 线程安全机制 | 安全等级 |
spdlog | 默认线程安全,内置锁机制 | ⭐⭐⭐⭐ |
glog | 部分线程安全,需自行控制输出目标 | ⭐⭐⭐☆ |
Boost.Log | 通过前端/后端设计实现安全,需配置 | ⭐⭐⭐☆ |
Easylogging | 支持多线程,但异步模式需手动启用 | ⭐⭐⭐☆ |
log4cplus | 完全线程安全,采用线程本地存储 | ⭐⭐⭐⭐ |
spdlog线程安全示例:
// 异步日志器(自动处理多线程)
void async_logging() {
auto async_log = spdlog::basic_logger_mt<spdlog::async_factory>(
"async_log", "logs/async.txt");
// 多个线程同时记录
vector<thread> threads;
for(int i=0; i<5; i){
threads.emplace_back([&] {
async_log->info("线程{}正在工作", this_thread::get_id());
});
}
for(auto& t : threads) t.join();
}
五、如何选择日志库?
- 新手入门:spdlog(简单易用)
- 企业级应用:glog(稳定可靠)
- 需要高度定制:Boost.Log(功能强大)
- Java转C :log4cplus(熟悉风格)
- 小型项目:Easylogging (轻量快捷)
选择口诀:
性能优先选spdlog,大厂风格用glog
定制需求Boost上,跨平台考虑log4cplus
最后提醒:
- 即使日志库声称线程安全,也要注意:
- 避免全局变量共享
- 正确初始化日志对象
- 异步日志注意刷新策略
- 生产环境建议:定期日志归档 设置日志级别