C++多线程日志记录器Logger简单实现

最基本的简单实现,没有实际意义,仅为博主的学习记录 《C++高级编程 第三版》 [美] Marc Gregoire 著
IDE : Code::Blocks
Compiler : GNU GCC Compiler have g++ follow the C++14 ISO C++ language standard [-std=c++14]
Console application ProjectName : LoggerMultiThread

Logger.h

#ifndef LOGGER_MULTI_THREAD_H
#define LOGGER_MULTI_THREAD_H

#include <fstream>
#include <string>
#include <queue>
#include <atomic>
#include <mutex>
#include <condition_variable>
#include <thread>

class Logger {
public:
    // 构造函数创建后台线程
    Logger() : isExited(false) {
        mThread = std::thread{&Logger::process, this};
    }

    // 显示删除复制构造函数和赋值运算符
    Logger(const Logger& src) = delete;
    Logger& operator=(const Logger& rhs) = delete;

    // 析构函数唤醒后台线程,将消息列队的信息全部写出到文件后,销毁对象
    ~Logger() {
        {
            // 上锁 (锁在此花括号代码块中有效,避免出现死锁)
            std::unique_lock<std::mutex> lock(mut);
            isExited = true;
            // 唤醒后台线程
            condVar.notify_all();
        }
        // 此时锁已释放,后台线程可获得锁
        mThread.join();
    }

    // 客户调用借口,向消息列队写入一条消息,并唤醒后台线程
    void log(const std::string& entry) {
        std::unique_lock<std::mutex> lock(mut);
        messagesQueue.push(entry);
        condVar.notify_all();
    }

private:
    // 后台线程,将消息列队中的信息写入文件
    void process() {
        std::ofstream ofs("log.txt", std::ios::out /*| std::ios::app*/);
        if (ofs.fail()) {
            std::cerr << "Failed to open logFile." << std::endl;
        }
        // 上锁
        std::unique_lock<std::mutex> lock(mut);
        while (true) {
            // 判断是否退出,若退出为假,等待唤醒
            if (!isExited) {
                condVar.wait(lock);
            }
            // 释放锁
            lock.unlock();
            while (true) {
                // 上锁,每次处理一条信息,每次处理时上锁和释放锁,防止线程阻塞时间过长
                lock.lock();
                if (messagesQueue.empty()) { break; }
                else {
                    ofs << messagesQueue.front() << std::endl;
                    messagesQueue.pop();
                }
                lock.unlock();
            }
            if (isExited) break;
        }
    }

    std::queue<std::string> messagesQueue; //! 消息列队
    std::atomic<bool> isExited; //! 退出状态 原子bool类型
    std::mutex mut; //! 非定时互斥体
    std::condition_variable condVar; //! 条件变量
    std::thread mThread; //! 线程
};

#endif // LOGGER_MULTI_THREAD_H

main.cpp

#include <iostream>
#include <sstream>
#include <functional>
#include <vector>
#include "Logger.h"

using namespace std;

void func(int id, Logger& logger) {
    // do something else.
    for (size_t i = 0; i < 74; ++i) {
        stringstream ss;
        ss << "The No." << id << " thread's test for the " << i << " times to call Logger's log.";
        logger.log(ss.str());
    }
}

void Test() {
    Logger logger;
    vector<thread> myThreads;
    for (size_t i = 0; i < 10; ++i) {
        myThreads.emplace_back(func, i, ref(logger));
    }
    for (auto& aThread : myThreads) {
        aThread.join();
    }
}

int main() {
    Test();
    return 0;
}
C++中,日志记录法是一种常见的调试技术,可以帮助我们在代码中插入记录,以便在程序运行时查看信息和错误。下面是一个简单的示例,演示如何在C++中使用日志记录法: ```cpp #include <iostream> #include <fstream> // 定义日志记录级别 enum LogLevel { LOG_LEVEL_DEBUG, LOG_LEVEL_INFO, LOG_LEVEL_WARNING, LOG_LEVEL_ERROR, }; // 定义日志记录器 class Logger { public: Logger() : m_logLevel(LOG_LEVEL_DEBUG) {} void setLogLevel(LogLevel level) { m_logLevel = level; } void log(LogLevel level, const std::string& message) { if (level < m_logLevel) { return; } std::ofstream file("log.txt", std::ios_base::app); file << "[" << getCurrentTime() << "] " << levelToString(level) << ": " << message << std::endl; } private: LogLevel m_logLevel; std::string getCurrentTime() { // 获取当前时间的代码 } std::string levelToString(LogLevel level) { // 将日志级别转换为字符串的代码 } }; int main() { Logger logger; // 设置日志记录级别 logger.setLogLevel(LOG_LEVEL_WARNING); // 记录日志 logger.log(LOG_LEVEL_DEBUG, "这是一个调试信息"); logger.log(LOG_LEVEL_INFO, "这是一个普通信息"); logger.log(LOG_LEVEL_WARNING, "这是一个警告信息"); logger.log(LOG_LEVEL_ERROR, "这是一个错误信息"); return 0; } ``` 在上面的代码中,我们定义了一个`Logger`类,它可以记录不同级别的日志。我们可以使用`setLogLevel()`方法来设置日志记录级别,然后使用`log()`方法来记录日志。在`log()`方法中,我们首先检查当前日志级别是否大于等于要记录的日志级别,如果是,就将日志记录到文件中。 在实际应用中,我们可能需要更复杂的日志记录器,例如支持多线程、异步日志等功能。但是,无论如何,日志记录法都是一种非常有用的调试技术,可以帮助我们更好地理解和调试代码。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值