C++ 多线程日志记录 - 包含时间戳、文件名、行号和模块信息
C++ 多线程日志记录示例
本文提供了一个简单的 C++ 多线程日志记录示例代码。该代码使用互斥锁确保线程安全,并包含时间戳、文件名、行号、函数名、日志级别和可选的模块信息,方便调试和分析。
#include <iostream>
#include <mutex>
#include <thread>
enum LogLevel {
DEBUG,
INFO,
WARNING,
ERROR
};
std::mutex log_mutex;
void printLog(const char* file, int line, const char* function, LogLevel level, const char* module, const char* format, ...) {
va_list args;
va_start(args, format);
std::lock_guard<std::mutex> lock(log_mutex);
// 获取当前时间
time_t now = time(nullptr);
tm* timeinfo = localtime(&now);
// 打印时间戳
std::cout << '[' << timeinfo->tm_year + 1900 << '-'
<< std::setw(2) << std::setfill('0') << timeinfo->tm_mon + 1 << '-'
<< std::setw(2) << std::setfill('0') << timeinfo->tm_mday << ' '
<< std::setw(2) << std::setfill('0') << timeinfo->tm_hour << ':'
<< std::setw(2) << std::setfill('0') << timeinfo->tm_min << ':'
<< std::setw(2) << std::setfill('0') << timeinfo->tm_sec << '] ';
// 打印文件名、行号、函数名
std::cout << '[' << file << ':' << line << ' ' << function << '] ';
// 打印日志级别
switch (level) {
case DEBUG:
std::cout << '[DEBUG] ';
break;
case INFO:
std::cout << '[INFO] ';
break;
case WARNING:
std::cout << '[WARNING] ';
break;
case ERROR:
std::cout << '[ERROR] ';
break;
}
// 打印模块名
if (module != nullptr) {
std::cout << '[' << module << '] ';
}
// 打印日志消息
vprintf(format, args);
std::cout << std::endl;
va_end(args);
}
#define LOG_DEBUG(module, format, ...) printLog(__FILE__, __LINE__, __FUNCTION__, DEBUG, module, format, ##__VA_ARGS__)
#define LOG_INFO(module, format, ...) printLog(__FILE__, __LINE__, __FUNCTION__, INFO, module, format, ##__VA_ARGS__)
#define LOG_WARNING(module, format, ...) printLog(__FILE__, __LINE__, __FUNCTION__, WARNING, module, format, ##__VA_ARGS__)
#define LOG_ERROR(module, format, ...) printLog(__FILE__, __LINE__, __FUNCTION__, ERROR, module, format, ##__VA_ARGS__)
void worker() {
LOG_DEBUG('worker', 'Starting worker thread');
// 执行一些工作
LOG_DEBUG('worker', 'Finished worker thread');
}
int main() {
LOG_INFO(nullptr, 'Starting program');
std::thread t(worker);
t.join();
LOG_INFO(nullptr, 'Exiting program');
return 0;
}
代码解释:
- **日志级别:**定义了
LogLevel枚举类型,包含DEBUG、INFO、WARNING和ERROR四种级别,用于区分不同重要性的日志信息。 - **互斥锁:**使用
std::mutex确保日志写入操作的线程安全,防止多个线程同时写入控制台导致数据错乱。 - 日志函数:
printLog函数接收日志信息,并使用可变参数列表来处理不同格式的日志信息。 - 时间戳:
printLog函数获取当前时间,并以YYYY-MM-DD HH:MM:SS的格式输出时间戳。 - 文件名、行号、函数名:
printLog函数使用__FILE__、__LINE__和__FUNCTION__宏获取当前代码的位置信息,方便定位日志输出的位置。 - 模块名:
printLog函数接收可选的模块名参数,方便区分不同模块的日志信息。 - **日志宏:**定义了四个日志宏,分别对应不同的日志级别,方便开发者快速调用日志函数。
使用示例:
在 main 函数和 worker 函数中,使用日志宏输出不同级别的日志信息。
代码优势:
- **线程安全:**使用互斥锁确保日志写入操作的线程安全。
- **信息丰富:**包含时间戳、文件名、行号、函数名、日志级别和可选的模块信息,方便调试和分析。
- **灵活方便:**使用宏定义简化日志输出操作,方便开发者快速使用。
改进建议:
- 可以将日志输出到文件,方便长期保存和分析。
- 可以使用不同的日志级别进行过滤,例如只输出
ERROR级别的日志信息。 - 可以使用第三方日志库,例如
spdlog或boost.log,提供更强大的日志功能。
原文地址: https://www.cveoy.top/t/topic/nkh6 著作权归作者所有。请勿转载和采集!