Kaynağa Gözat

添加日志文件数量支持。

zzj 6 yıl önce
ebeveyn
işleme
d3777fc6b2
2 değiştirilmiş dosya ile 91 ekleme ve 6 silme
  1. 58 5
      logger.cpp
  2. 33 1
      test.cpp

+ 58 - 5
logger.cpp

@@ -15,22 +15,55 @@
 
 #include "log.h"
 
+#include <dirent.h>
+#include <string.h>
+#include <fnmatch.h>
+
+static void dir_clean(const char*dir,const char*pattern,int count)
+{
+	struct dirent **namelist;
+	int n = scandir(dir, &namelist, NULL, alphasort);
+
+	if (n < 0)
+		return;
+
+	char fname[512];
+	strcpy(fname,dir);
+	strcat(fname,"/");
+	char*p=&fname[strlen(fname)];
+
+	for (int i=n-1;i>=0;i--)
+	{
+		if(0==fnmatch(pattern,namelist[i]->d_name,0) && count--<=0)
+		{
+			strcpy(p,namelist[i]->d_name);
+			remove(fname);
+			printf("remove file:%s\n",fname);
+		}
+		free(namelist[i]);
+	}
+	free(namelist);
+}
+
+
 struct log_file
 {
 	std::string _fname; //文件名模板 /home/zzj/test.log
 	FILE*   _fp;
-	long    _min_size;//文件切割的最大的字节数,当达到这个字节数后,下个对齐时间将切换日志文件
-	long    _cur_size;//当前文件的大小
+	long _min_size;//文件切割的最大的字节数,当达到这个字节数后,下个对齐时间将切换日志文件
+	long _cur_size;//当前文件的大小
 	time_t	_last_time;//最后操作文件的时间
 	int 	_time_align;//日志文件名对齐的时间,支持 dhm -- 天、小时、分钟
+	int     _file_count;
 
 	zclock  _err_clock,_check_dir_clock;
 
-	log_file(const boost::string_ref&fpath,uint32_t min_size=10,int time_align='h')
+	log_file(const boost::string_ref&fpath,int file_count=0,int min_size=10,int time_align='h')
 		:_fname(fpath)
 		,_fp(0)
-		,_min_size(min_size<<20)
+		,_min_size((1LL*min_size)<<20)
 		,_cur_size(0)
+		,_file_count(file_count)
 	{
 		switch(time_align)
 		{
@@ -73,6 +106,24 @@ struct log_file
 		return name;
 	}
 
+	void check_file_count()
+	{
+		if(!_file_count)
+			return;
+
+		int pos1=_fname.find_last_of('/');
+		if(pos1==-1)
+			return;
+
+		std::string fn=_fname.substr(pos1+1);
+		int pos2=fn.find_last_of('.');
+		if(pos2==-1)
+			return;
+		fn.insert(pos2,"_*");
+
+		dir_clean(_fname.substr(0,pos1).c_str(),fn.c_str(),_file_count);
+	}
+
 	int reopen()
 	{
 		if(_fp) fclose(_fp);
@@ -81,6 +132,7 @@ struct log_file
 		_cur_size=(uint32_t)ftell(_fp);
 
 		_check_dir_clock.reset();
+		check_file_count();
 		return 0;
 	}
 
@@ -184,6 +236,7 @@ static std::shared_ptr<logger> read_config(config_file*f, const char*log_name)
 
 	const char* qsize=f->get(log_name,"queue_size","2048");
 	const char* min_size=f->get(log_name,"min_size","10");
+	const char* file_count=f->get(log_name,"file_count","0");
 	const char* time_align=f->get(log_name,"time_align","m");
 
 	std::unique_ptr<log_queue> queue(new log_queue());
@@ -203,7 +256,7 @@ static std::shared_ptr<logger> read_config(config_file*f, const char*log_name)
 		return nullptr;
 	}
 	
-	std::unique_ptr<log_file> file(new log_file(fname, atoi(min_size),time_align[0]));
+	std::unique_ptr<log_file> file(new log_file(fname, atoi(file_count), atoi(min_size),time_align[0]));
 	std_info("初始化日志%s成功:{文件名=%s, 输出队列大小=%dkB, 最小切换大小=%dMB, 切换对齐时间=%c}",
 		log_name,fname,atoi(qsize),atoi(min_size),time_align[0]);
 

+ 33 - 1
test.cpp

@@ -3,16 +3,48 @@
 #include <iostream>
 #include <thread>
 #include <log.h>
+#include <dirent.h>
+#include <string.h>
+#include <fnmatch.h>
+
+void dir_clean(const char*dir,const char*pattern,int count)
+{
+	struct dirent **namelist;
+	int n = scandir(dir, &namelist, NULL, alphasort);
+
+	if (n < 0)
+		return;
+
+	char fname[512];
+	strcpy(fname,dir);
+	strcat(fname,"/");
+	char*p=&fname[strlen(fname)];
+
+	for (int i=n-1;i>=0;i--)
+	{
+		if(0==fnmatch(pattern,namelist[i]->d_name,0) && count--<=0)
+		{
+			strcpy(p,namelist[i]->d_name);
+			remove(fname);
+			printf("remove file:%s\n",fname);
+		}
+		free(namelist[i]);
+	}
+	free(namelist);
+}
 
 int main() 
 { 
+	dir_clean("/home/zzj/ya-src/dist/log","yals_*.log",3);
+	dir_clean("../dist/log","yals_*.log",3);
+	
 	log_init("../etc/log.ini");
 
 	std::string s(100,'1');
 	for(int i=0;;i++)
 	{
 		log_info("%s",s.c_str());
-		usleep(10000);
+		usleep(10);
 	}
 
 	std::this_thread::yield();