1 Star 0 Fork 0

Miun11/Linux_learning

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
Log.hpp 6.54 KB
一键复制 编辑 原始数据 按行查看 历史
Miun11 提交于 2026-05-16 21:50 +08:00 . 日志与策略模式&&实现一个线程池
#ifndef __LOG_HPP__
#define __LOG_HPP__
#include <iostream>
#include <cstdio>
#include <string>
#include <filesystem> // c++17
#include <fstream> // 文件读写
#include <ctime>
#include <memory>
#include <unistd.h>
#include "Mutex.hpp"
namespace LogModuel
{
using namespace MutexModule;
const std::string CRLF = "\r\n"; // 回车换行
// 日志显示方法
// 基类
class LogStrategy
{
public:
virtual void SyncLog(const std::string message) = 0;
~LogStrategy() = default;
};
// 向显示器打印
class ConsoleLogStrategy : public LogStrategy
{
public:
virtual void SyncLog(const std::string message) override
{
// 显示器属于临界资源,加锁
Mutex_RAII guard(_mutex);
std::cout << message << CRLF;
}
~ConsoleLogStrategy()
{
}
private:
Mutex _mutex;
};
// 向文件打印
std::string gdefaultPath = "./";
std::string gdefaultName = "log.log";
class FileLogStrategy : public LogStrategy
{
public:
FileLogStrategy(std::string path = gdefaultPath, std::string name = gdefaultName)
: _path(path),
_name(name)
{
// 对路径做检查
Mutex_RAII guard(_mutex); // 加锁
if (std::filesystem::exists(_path))
{
return;
}
try
{
std::filesystem::create_directories(_path);
}
catch (const std::filesystem::filesystem_error &err)
{
std::cout << err.what() << std::endl;
}
}
virtual void SyncLog(const std::string message) override
{
Mutex_RAII guard(_mutex); // 加锁
// 构造文件完整路径
std::string filename = _path + (_path.back() == '/' ? "" : "/") + _name;
std::ofstream out(filename, std::ios::app); // 以追加方式打开文件,不存在创建
if (!out)
{
return;
}
out << message << CRLF;
out.close();
}
~FileLogStrategy()
{
}
private:
std::string _path;
std::string _name;
Mutex _mutex;
};
// 形成日志等级
enum class LogLevel
{
DEBUG,
INFO,
WARNING,
ERROR,
FATAL
};
// 将日志等级转化为字符串形式,LogLevel对象实际是一个整数
std::string Level2Str(LogLevel level)
{
switch (level)
{
case LogLevel::DEBUG:
return "DEBUG";
case LogLevel::INFO:
return "INFO";
case LogLevel::WARNING:
return "WARNING";
case LogLevel::ERROR:
return "ERROR";
case LogLevel::FATAL:
return "FATAL";
default:
return "UNKOWN";
}
}
// 获取时间
std::string Time()
{
time_t now = time(nullptr); // 获取当前时间戳
tm tm;
localtime_r(&now, &tm);
/*std::stringstream ss;
ss << "[" << tm.tm_year << "-" << tm.tm_mon
<< "-" << tm.tm_mday << " "
<< tm.tm_hour << ":" << tm.tm_min
<< ":" << tm.tm_sec << "]";*/
char buf[128];
// 格式控制
snprintf(buf, sizeof(buf), "%4d-%02d-%02d %02d:%02d:%02d",
tm.tm_year + 1900,
tm.tm_mon + 1,
tm.tm_mday,
tm.tm_hour,
tm.tm_min,
tm.tm_sec);
return buf;
}
class Logger
{
public:
Logger()
{
Enable_ConsoleLogStrategy();
}
// 创建实例化智能指针对象
void Enable_ConsoleLogStrategy()
{
_fllush_strategy = std::make_unique<ConsoleLogStrategy>();
}
void Enable_FileLogStrategy()
{
_fllush_strategy = std::make_unique<FileLogStrategy>();
}
// 形成一条日志
// 一条日志的形式:[时间] [日志等级] [pid] [文件名] [行数] - "内容"
// [2024-08-04 12:27:03] [DEBUG] [202938] [main.cc] [16] - hello world
class LogMessage
{
public:
LogMessage(LogLevel &level, const std::string &file, size_t line, Logger &logger)
: _cur_time(Time()),
_loglevel(Level2Str(level)),
_pid(getpid()),
_file(file),
_line_num(line),
_logger(logger)
{
// 日志左半部分
std::stringstream ss;
ss << "[" << _cur_time << "] ["
<< _loglevel << "] ["
<< _pid << "] ["
<< _file << "] ["
<< _line_num << "]"
<< " - ";
_log = ss.str();
}
// 日志输出形式: Logger() << "xxx" << xxx;
// 重载 <<
template <typename T>
LogMessage &operator<<(const T &info)
{
// 字符串流
std::stringstream ss;
ss << info;
_log += ss.str();
return *this; // 返回LogMessage对象,处理连续的<<,如: << "xxx" << 123 << 'a'
}
// 析构
~LogMessage()
{
// 调用日志显示方法(多态)
if (_logger._fllush_strategy)
{
// 由该智能指针类型决定调用哪个方法
_logger._fllush_strategy->SyncLog(_log);
}
}
private:
std::string _cur_time; // 时间
std::string _loglevel; // 日志等级
pid_t _pid; // 进程id
std::string _file; // 文件名
size_t _line_num; // 行号
std::string _log; // 整条日志
Logger &_logger; // 外部类对象,内部类用来调用日志显示方法
};
// 重载(),在内部类实例化Logger对象
LogMessage operator()(LogLevel level, const std::string file, size_t line)
{
return LogMessage(level, file, line, *this);
}
~Logger()
{
}
private:
std::unique_ptr<LogStrategy> _fllush_strategy; // 日志显示方法(智能指针)
};
Logger logger;
#define Log(level) logger(level, __FILE__, __LINE__)
}
#endif
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/miun11/Linux_learning.git
git@gitee.com:miun11/Linux_learning.git
miun11
Linux_learning
Linux_learning
master

搜索帮助