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 枚举类型,包含 DEBUGINFOWARNINGERROR 四种级别,用于区分不同重要性的日志信息。
  • **互斥锁:**使用 std::mutex 确保日志写入操作的线程安全,防止多个线程同时写入控制台导致数据错乱。
  • 日志函数:printLog 函数接收日志信息,并使用可变参数列表来处理不同格式的日志信息。
  • 时间戳:printLog 函数获取当前时间,并以 YYYY-MM-DD HH:MM:SS 的格式输出时间戳。
  • 文件名、行号、函数名:printLog 函数使用 __FILE____LINE____FUNCTION__ 宏获取当前代码的位置信息,方便定位日志输出的位置。
  • 模块名:printLog 函数接收可选的模块名参数,方便区分不同模块的日志信息。
  • **日志宏:**定义了四个日志宏,分别对应不同的日志级别,方便开发者快速调用日志函数。

使用示例:

main 函数和 worker 函数中,使用日志宏输出不同级别的日志信息。

代码优势:

  • **线程安全:**使用互斥锁确保日志写入操作的线程安全。
  • **信息丰富:**包含时间戳、文件名、行号、函数名、日志级别和可选的模块信息,方便调试和分析。
  • **灵活方便:**使用宏定义简化日志输出操作,方便开发者快速使用。

改进建议:

  • 可以将日志输出到文件,方便长期保存和分析。
  • 可以使用不同的日志级别进行过滤,例如只输出 ERROR 级别的日志信息。
  • 可以使用第三方日志库,例如 spdlogboost.log,提供更强大的日志功能。
C++ 多线程日志记录 - 包含时间戳、文件名、行号和模块信息

原文地址: https://www.cveoy.top/t/topic/nkh6 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录