- 索引
- 1、简介
- 2、遇到的问题
- 3、代码改进
- 4、测试
========》以下全部代码查看《========
索引【C++模块实现】| 【01】日志系统实现
【C++模块实现】| 【02】日志系统优化
【C++模块实现】| 【03】文件管理模块
【C++模块实现】| 【04】配置模块
【C++模块实现】| 【05】日志模块增加配置模块的功能
结合前面的配置模块,我们已经将日志系统的配置项通过配置模块进行加载; 但该日志系统中没有提供循环覆盖写文件功能,故本节将参考网上一些文章对其进行完善;
结合参考的文章,做出了一些简单的循环覆盖写文件: 首先配置中设定日志保存的期限、日志文件的内存上限以及扩张的文件数(log1.txt、log2.txt),可以有多种方式,可以按时间进行文 件划分,但本次只简单的设置按个数划分; 方法一:通过检查文件每个文件的日期,若文件数没有到达限制个数,则创建它做为日志副本; 否则直接将文件修改日志最小的(即最早生成的)作为日志的存储副本; 【如:】若限定最多生成5个文件数(log1.txt、log2.txt、log3.txt、log4.txt、log5.txt),日志只往log.txt中写入, 当log.txt写满时,将遍历这5个文件,若文件不存在,则直接移动到该文件,若存在,则移动到文件修改日期最早的那个文件; 方法二: 在配置中增添一项用来记录日志更新到第几个文件数file_num; 当log.txt文件写满时,先检查各个文件日志是否存在,若存在则检查是否过期,若过期则删除,且log.txt日志直接移动到 该日志文件中,若不存在,则log.txt直接移动到该日志文件中,若满足期限且存在,则移动到logfile_num.txt中; 该file_num若有变动,则会对配置文件进行更新记录,便于下次加载; 上述方法测试,暂时没有问题,只是简单的实现,若有其他缺漏,或方法不适用,麻烦各位指点。2、遇到的问题
2.1 日志文件大小的限制没有达到预期的要求
每次进入该判断时,文件大小是正确的,但后续对文件进行移动的时候却显示文件的大小远大于该限制; 后面发现没有对该文件进行关闭操作,应该是缓冲区中的内容还没有写入到文件中导致的; 后续在此处对文件关闭即解决
2.2 yamlstring
当配置项的内容有更新时,需要回写到配置文件时,将YAML::Node格式的内容压入stringstream中后写入文件格式出现问题; 后续提供toYaml接口,和toYamlString分开; 以下是错误格式:3、代码改进
struct stat st;
if(!stat(m_filename.c_str(), &st)) {
if(st.st_size > m_file_buf) { // 判断文件是否写满了
m_filestream.close();
std::string newFile = m_filename.substr(0, m_filename.rfind('.'));
int i;
//
//
//
for(i=1; i<=m_backups_files ; ++i) {
std::string tmp = newFile + std::to_string(i) + ".txt";
if(stat(tmp.c_str(), &st)) { // 判断文件是否存在
break;
}
if(((time(0) - st.st_mtime) / (24 * 60 * 60)) > m_backups_days) {
FSUtil::Rm(tmp);
}
}
FSUtil::Mv(m_filename, newFile+std::to_string(m_file_num) + ".txt");
FSUtil::Rm(m_filename);
FSUtil::OpenForWrite(m_filestream, m_filename.c_str(), std::ios::app);
m_file_num += 1;
if(m_file_num > m_backups_files) m_file_num = 1;
IsChange = true; // 若为true则需要更新yaml配置文件
}
4、测试
测试循环覆盖写文件
此时的配置文件为:
测试代码
#include#include "../sylar/log.h" #include "../sylar/util.h" #include "../sylar/config.h" #include #include int main(int argc, char** argv) { sylar::Logger::ptr g_logger = SYLAR_LOG_NAME("root"); sylar::Config::LoadFromYaml("/root/code/log_server/bin/conf/log.yml"); // 输出日志 std::cout << g_logger->toYamlString() << std::endl; for(int i=0; i<160000; ++i) { SYLAR_LOG_INFO(g_logger) << i; sleep(1); } return 0; }
参考文章
=========》Log4j2 RollingFileAppender《=========
=========》滚动文件附加器指南《=========
=========》RollingFileWithCleanupAppender《=========



