框架模块设计
功能叙述
日志系统的作用就是将一条消息格式化指定格式的字符串之后,写入到指定位置
这个指定位置就有说法了
- 标准输出
- 指定文件
- 滚动文件
我们可以写入到其中的一种,或者三种同时写入,也可以扩展到数据库、远程服务器
除此之外,写入的时候,也要支持同步和异步的写入方式
日志输出以日志器为单位,支持多日志器,因此就需要对日志器管理
模块划分
- 日志等级模块:对不同日志进行等级划分、对日志的输出进行控制,提供按照等级枚举字符串的功能
- OFF:关闭
- DEBUG:调试,调试信息输出
- INFO:提示,提示型日志信息
- WARN:警告,不影响运行,但可能不安全
- ERROR:错误,程序运行出错的日志
- FATAL:致命,代码异常
- 日志消息模块:日志中所含的各类信息
- 时间
- 线程ID
- 日志等级
- 日志数据
- 日志文件名
- 日志行号
- 消息格式化模块:设置日志的输出格式,提供对消息格式化的功能
- 格式化内容:[%d{%H:%M:%S}]%T[%t]%T[%p]%T[%c]%T%f:%l%T%m%n
- [12:01:54] [(TID)] [FATAL] [root] main.cc:13 套接字创建失败\n
- 日志落地模块:负责对日志指定方向的写入输出
- 日志器模块:对上面模块的整合、日志输出等级、日志信息格式化、日志消息落地模块
- 同步日志器模块
- 异步日志器模块
- 异步线程模块:负责异步日志落地
- 单例日志器管理模块:对日志全局管理,在项目任何位置,获取日志器执行输出
模块关系图
实用工具类
设计
提前设计一些零碎的功能性接口,以便于后面项目的开发
- 获取系统时间
- 判断文件是否存在
- 获取文件路径
- 创建目录
namespace Xulog
{
namespace Util
{
class Date
{
public:
static size_t getTime()
{
return (size_t)time(nullptr);
}
};
class File{
public:
static bool exists(const std::string& pathname);
static std::string path(const std::string& pathname);
static void createDirectory(const std::string& pathname);
};
}
}
实现
static bool exists(const std::string &pathname)
{
struct stat st;
if (stat(pathname.c_str(), &st) < 0) // 判断文件是否存在
return false;
return true;
}
static std::string path(const std::string &pathname)
{
size_t pos = pathname.find_last_of("/\\"); // 查找最后一个'/'或者'\'
if (pos == std::string::npos)
return "."; // 如果没有找到路径分隔符,返回当前目录
return pathname.substr(0, pos + 1); // 获取文件路径的目录部分
}
static void createDirectory(const std::string &pathname)
{
size_t pos = 0, idx = 0; // pos表示'/'的位置,idx表示起始位置
while (idx < pathname.size())
{
pos = pathname.find_first_of("/\\", idx); // 找第一个'\'
if (pos == std::string::npos) // 如果没有任何目录,直接创建
{
mkdir(pathname.c_str(), 0777);
return;
}
std::string parent_dir = pathname.substr(0, pos + 1); // 找到父级目录
if (exists(parent_dir) == true) // 如果存在则直接找下一个
{
idx = pos + 1;
continue;
}
mkdir(parent_dir.c_str(), 0777);
idx = pos + 1;
}
}
测试
#include "util.hpp"
int main()
{
std::cout << Xulog::Util::Date::getTime() << std::endl;
std::string pathname = "./dir1/dir2/";
Xulog::Util::File::createDirectory(Xulog::Util::File::path(pathname));
return 0;
}