胧の宝藏之地
首页项目归档照片墙音乐灵境说说杂谈友链关于
封面

日志

写作时间:2026-07-25 23:53:44

Mutex.hpp

#pragma once

#include<iostream>
#include<pthread.h>


class Mutex
{
public:
    Mutex()
    {
        pthread_mutex_init(&_lock , nullptr);
    }

    void Lock()
    {
        pthread_mutex_lock(&_lock);
    }

    pthread_mutex_t *Ptr()
    {
        return &_lock;
    }

    void Unlock()
    {
        pthread_mutex_unlock(&_lock);
    }

    ~Mutex()
    {
        pthread_mutex_destroy(&_lock);
    }
private:
    pthread_mutex_t _lock;
};

class LockGuard
{
public:
    LockGuard(Mutex &lock):_lockref(lock)
    {
        _lockref.Lock();
    }

    ~LockGuard()
    {
        _lockref.Unlock();
    }
private:
    Mutex &_lockref;
};

Logger.hpp

#ifndef __LOGGER_HPP
#define __LOGGER_HPP

#include<iostream>
#include<cstdio>
#include<string>
#include<memory> 
#include<sstream>
#include<ctime>
#include<sys/time.h>
#include<unistd.h>
#include<filesystem>
#include<sys/stat.h>
#include<fstream>
#include"Mutex.hpp"

namespace NS_LOG_MODULE
{
    enum class LogLevel
    {
        INFO,
        WARNING,
        ERROR,
        FATAL,
        DEBUG
    };

    std::string LogLevel2Message(LogLevel level)
    {
        switch(level)
        {
            case LogLevel::INFO:
                    return "INFO";
            case LogLevel::WARNING:
                    return "WARNING";
            case LogLevel::ERROR:
                    return "ERROR";
            case LogLevel::FATAL:
                    return "FATAL";
            case LogLevel::DEBUG:
                    return "DEBUG";
            default:
                    return "UNKNOWN";
        }
    }

    std::string GetCurrentTime()
    {
        struct timeval current_time;
        int n = gettimeofday(&current_time , nullptr);
        (void)n;

        struct tm struct_time;
        localtime_r(&(current_time.tv_sec) , &struct_time);

        char timestr[128];
        snprintf(timestr , sizeof(timestr) , "%04d-%02d-%02d %02d:%02d:%02d.%ld" , 
                struct_time.tm_year + 1900,
                struct_time.tm_mon + 1,
                struct_time.tm_mday,
                struct_time.tm_hour,
                struct_time.tm_min,
                struct_time.tm_sec,
                current_time.tv_usec);
        return timestr;
    }

    // 策略模式,策略接口
    // 1. 显示器打印
    // 2. 文件写入
    class LogStrategy
    {
    public:
        virtual ~LogStrategy() = default;
        virtual void SyncLog(const std::string &message) = 0;

    };

    // 控制台日志刷新策略, 日志将来要向显示器打印
    class ConsoleStartegy : public LogStrategy 
    {
    public:
        void SyncLog(const std::string &message) override
        {
            LockGuard lockguard(_mutex);
            std::cerr <<message <<"\n";
        } 

        ~ConsoleStartegy()
        {}

    private:
        Mutex _mutex;
    };


    const std::string defaultpath = "./log";
    const std::string defaultname = "log.txt";

    // 文件策略
    class FileLogStrategy :public LogStrategy
    {
    public:
        FileLogStrategy(const std::string &path = defaultpath , const std::string &name = defaultname):
                        _logpath(path),
                        _logfilename(name)
        {
            if(std::filesystem::exists(_logpath))
                return;
            try
            {
                std::filesystem::create_directories(_logpath);
            }
            catch(const std::filesystem::filesystem_error &e)
            {
                std::cerr<<e.what() <<"\n";
            }

        }


        void SyncLog(const std::string &message) override
        {
            LockGuard lockguard(_mutex);
            if(!_logpath.empty() && _logpath.back() !='/')
            {
                _logpath += "/";
            }
            std::string targetlog = _logpath + _logfilename;
            std::ofstream out(targetlog , std::ios::app); // 追加写入
            if(!out.is_open())
            {
                std::cerr<<"open" <<targetlog <<"failen" <<std::endl;
                return;
            }
            out << message << "\n";
            out.close();
        }

        ~FileLogStrategy()
        {}

    private:
        std::string _logpath;
        std::string _logfilename;
        Mutex _mutex;
    };

    class Logger
    {
        // 日志生成



    public:
        Logger()
        {
            UseConsoleStrategy();
        }

        void UseConsoleStrategy()
        {
            _strategy = std::make_unique<ConsoleStartegy>();
        }

        void UseFileStrategy()
        {
            _strategy = std::make_unique<FileLogStrategy>();
        }

        // void Debug(const std::string &message)
        // {
        //     if(_strategy != nullptr)
        //     {
        //         _strategy->SyncLog(message);
        //     }
        // }

        class LogMessage
        {
        public:
            LogMessage(LogLevel level , std::string &filename , int line , Logger &logger):
            _level(level),
            _curr_time(GetCurrentTime()),
            _pid(getpid()),
            _filename(filename),
            _line(line),
            _logger(logger)
            {
                std::stringstream ss;
                ss  <<"[" <<_curr_time <<"] " 
                    <<"[" <<LogLevel2Message(_level) <<"] "
                    <<"[" <<_pid <<"] " 
                    <<"[" <<_filename <<"] "
                    <<"[" <<_line <<"] "
                    <<" : ";    

                    _loginfo = ss.str();
            }

            template<typename T>
            LogMessage &operator << (const T &info)
            {
                std::stringstream ss;
                ss <<info;
                _loginfo += ss.str();
                return *this; // 返回当前LogMessage对象
            }

            ~LogMessage()
            {
                if(_logger._strategy)
                {
                    _logger._strategy->SyncLog(_loginfo);
                }
            }

        private:
            LogLevel _level;
            std::string _curr_time;
            pid_t _pid;
            std::string _filename;
            int _line;
            std::string _loginfo;
            Logger &_logger;
        };

        LogMessage operator()(LogLevel level , std::string filename , int line)
        {
            return LogMessage(level , filename , line , *this);
        }

        ~Logger()
        {}

    private:
        std::unique_ptr<LogStrategy> _strategy;  // 刷新策略
    };

Logger logger;

#define ENABLE_CONSOLE_LOG_STRATEGY() logger.UseConsoleStrategy();
#define ENABLE_FILE_LOG_STRATEGY() logger.UseFileStrategy();


#define LOG(level) logger(level , __FILE__ , __LINE__)


}



#endif

‍

Main.cc

#include "Logger.hpp"
#include"Mutex.hpp"

using namespace NS_LOG_MODULE;


int main()
{

    // ENABLE_CONSOLE_LOG_STRATEGY();
    ENABLE_FILE_LOG_STRATEGY();

    LOG(LogLevel::DEBUG) <<"hello world " <<"star";
    LOG(LogLevel::WARNING) <<"hello world " <<"star";
    LOG(LogLevel::FATAL) <<"hello world " <<"star";
    LOG(LogLevel::ERROR) <<"hello world " <<"star";
    LOG(LogLevel::INFO) <<"hello world " <<"star";


    // ENABLE_CONSOLE_LOG_STRATEGY();
    // logger.Debug("console strategy!");
    // logger.Debug("console strategy!");
    // logger.Debug("console strategy!");
    // logger.Debug("console strategy!");

    // ENABLE_FILE_LOG_STRATEGY();
    // logger.Debug("file strategy!");
    // logger.Debug("file strategy!");
    // logger.Debug("file strategy!");
    // logger.Debug("file strategy!");

    // ENABLE_CONSOLE_LOG_STRATEGY();
    // logger.Debug("console strategy!");
    // logger.Debug("console strategy!");
    // logger.Debug("console strategy!");
    // logger.Debug("console strategy!");

    // std::cout<<GetCurrentTime() <<std::endl;
    // sleep(1000);
    // std::cout<<GetCurrentTime() <<std::endl;
    // sleep(1);
    // std::cout<<GetCurrentTime() <<std::endl;
    // sleep(1);
    // std::cout<<GetCurrentTime() <<std::endl;
    // sleep(1);



    return 0;
}

‍

Makefile

logger : Main.cc
    g++ -o $@ $^ -std=c++17 -g
.PHONY:clean
clean:
    rm -f logger

‍

avatar

胧

RECOMMENDED

线程控制

2026-07-21 01:47:21

线程池——单例模式

2026-07-27 22:36:45

进程控制

2026-07-11 20:27:31

Table of Contents