由於日誌庫沒有自動保存最近幾天日誌文件的處理函數。這幾天手動編寫一個保存最近n天的函數。,我寫的c++控制檯程序。
日誌模塊處理邏輯:
創建一個定時器每小時定時檢測當前時間。
每天的凌晨一點,就更新新的日誌文件和刪除舊的日誌文件:
1.按日期生成日誌文件夾和日誌文件
限制最大300m大小,可增長3次的日誌文件。
2.保留最近n天的日誌文件夾
① 獲取當前所有日誌文件夾的路徑
② 根據路徑獲取文件夾的創建時間
③ 根據文件夾的創建時間與當前時間進行比較,
這個就是日期相差天數的比較。
超出n天,則刪除該文件夾及所含文件。
#include <iostream>
#include <vector>
#include <io.h>
#include <string>
#include <Windows.h>
#include <direct.h>
using namespace std;
int monthdays[2][12] = { { 31,28,31,30,31,30,31,31,30,31,30,31 },{ 31,29,31,30,31,30,31,31,30,31,30,31 } };
int yeardays[2] = { 365,366 };
int isLearyear(int year)
{
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
return 1;
else
return 0;
}
//日期靠前,當前日期
int caldays(int year1, int month1, int day1, int year2, int month2, int day2)
{
int sumdays = 0;
if (year1 == year2 && month1 == month2)
{
sumdays = day2 - day1;
}
else
if (year1 == year2)
{
sumdays += monthdays[isLearyear(year1)][month1 - 1] - day1;
//cout << " 1 :" << sumdays << endl;
for (int i = month1; i < month2 - 1; i++)
sumdays += monthdays[isLearyear(year1)][i];
//cout << "2:" << sumdays << endl;
sumdays += day2;
//cout << "3 :" << sumdays << endl;
}
else
{
sumdays += monthdays[isLearyear(year1)][month1 - 1] - day1;
for (int i = month1; i < 12; i++)
sumdays += monthdays[isLearyear(year1)][i];
for (int i = year1 + 1; i < year2; i++)
sumdays += yeardays[isLearyear(i)];
for (int i = 0; i < month2 - 1; i++)
sumdays += monthdays[isLearyear(year2)][i];
sumdays += day2;
}
return sumdays;
}
//獲取文件夾的創建時間
BOOL GetFileTime(HANDLE hFile, LPSTR lpszCreationTime)
{
FILETIME ftCreate, ftAccess, ftWrite;
SYSTEMTIME stUTC1, stLocal1;
// 獲取 FileTime
if (!GetFileTime(hFile, &ftCreate, &ftAccess, &ftWrite)) {
cout << "error!" << endl;
return FALSE;
}
//轉換: FileTime --> LocalTime
FileTimeToSystemTime(&ftCreate, &stUTC1);
SystemTimeToTzSpecificLocalTime(NULL, &stUTC1, &stLocal1);
//獲取創建時間
wsprintf(lpszCreationTime, "%02d/%02d/%02d %02d:%02d",
stLocal1.wYear, stLocal1.wMonth, stLocal1.wDay,
stLocal1.wHour, stLocal1.wMinute);
cout << "llvgiy" << endl;
return TRUE;
}
//轉爲系統時間
string print(FILETIME ftime)
{
char str[50];
SYSTEMTIME rtime;
FILETIME ltime;
memset(str, 0, 50);
//cout << "文件創建時間:" << ftime.dwHighDateTime << endl;
//cout << "文件創建時間:" << ftime.dwLowDateTime << endl;
FileTimeToLocalFileTime(&ftime, <ime);
FileTimeToSystemTime(<ime, &rtime); //將文件時間轉化爲系統時間
sprintf(str, "%04u%02u%02u", rtime.wYear, rtime.wMonth, rtime.wDay);
//printf("%s\n", str);
return str;
}
//清空文件夾內所有文件
void deleteAllfiles(string deletepath)
{
struct _finddata_t fileInfo;
intptr_t hFile = _findfirst(deletepath.c_str(), &fileInfo);
string p;
if ((hFile = _findfirst(p.assign(deletepath).append("\\*").c_str(), &fileInfo)) != -1)
{
do
{
//如果是目錄,存入列表
if ((fileInfo.attrib & _A_SUBDIR))
{
//是目錄
if (strcmp(fileInfo.name, ".") != 0 && strcmp(fileInfo.name, "..") != 0)
{
//cout << "是mulu" << endl;
continue;
//filespath.push_back(p.assign(path).append("\\").append(fileInfo.name));
}
}
else//是文件
{
//cout << p.assign(deletepath).append("\\").append(fileInfo.name) << endl;
string deletefile = p.assign(deletepath).append("\\").append(fileInfo.name);
remove(deletefile.c_str());
}
} while (_findnext(hFile, &fileInfo) == 0);
_findclose(hFile);
}
//刪除目錄
_rmdir(deletepath.c_str());
}
//比較文件夾創建時間進行刪除(保留n天日誌文件)
//日誌文件路徑-當前時間日期-保留的天數
void saveDays(string path,int saveday)
{
//計算文件夾的個數和添加文件夾的名字
vector<string> filespath;
struct _finddata_t fileInfo;
intptr_t hFile = _findfirst(path.c_str(), &fileInfo);
string p;
if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileInfo)) != -1)
{
do
{
//如果是目錄,存入列表
if ((fileInfo.attrib & _A_SUBDIR))
{
//是目錄
if (strcmp(fileInfo.name, ".") != 0 && strcmp(fileInfo.name, "..") != 0)
{
filespath.push_back(p.assign(path).append("\\").append(fileInfo.name));
}
}
} while (_findnext(hFile, &fileInfo) == 0);
_findclose(hFile);
}
//獲取文件夾的創建時間,和當前日期時間比較。
vector<string> filescreatetime;
for (int i = 0; i < filespath.size(); i++)
{
string folderpath = filespath[i];
cout << "文件路徑:"<<folderpath << endl;
//LPCSTR
HANDLE hDir = CreateFile(folderpath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
/* if (hDir == INVALID_HANDLE_VALUE)
{
printf("Get the dictionary failed!\n");
CloseHandle(hDir);
return;
}*/
//定義變量
FILETIME IpCreationTime; //文件夾的創建時間
FILETIME IpLastAccessTime; //對文件夾的最近訪問時間
FILETIME IpLastWriteTime; //文件夾的最近修改時間
if (GetFileTime(hDir, &IpCreationTime, &IpLastAccessTime, &IpLastWriteTime))
{
filescreatetime.push_back(print(IpCreationTime));
}
CloseHandle(hDir);
}
//超出n天則進行刪除文件夾
for (size_t i = 0; i < filescreatetime.size(); i++)
{
//計算文件與當前日期相差天數,超出則進行刪除
//獲取當前時間
//string curdate = gettime();
//獲取毫秒級時間操作
SYSTEMTIME sys;
GetLocalTime(&sys);
char chardate[50];
sprintf_s(chardate, "%04d%02d%02d"
, sys.wYear, sys.wMonth, sys.wDay
);
string curdate = chardate;
int currentyear = stoi(curdate.substr(0,4));
int currentmonth = stoi(curdate.substr(4, 2));
int currentday = stoi(curdate.substr(6, 2));
cout << "當前時間:" << currentyear<< " " << currentmonth<< " " << currentday << endl;
//20200520--0-7
int year = stoi(filescreatetime[i].substr(0, 4));
int month = stoi(filescreatetime[i].substr(4, 2));
int day = stoi(filescreatetime[i].substr(6, 2));
cout << "文件創建時間:" << year << " "<<month << " " << day << endl;
int sumday = caldays(year,month,day,currentyear, currentmonth,currentday);
cout << "相差天數:" << sumday << endl;
if ( sumday >= saveday)
{
cout << "刪除日誌文件夾,路徑"<< filespath[i] << endl;
//刪除該日誌文件-以及目錄
string deletepath = filespath[i];
deleteAllfiles(deletepath);
}
}
}
int main()
{
int num=0;
//啓動定時器1h
auto dairyTimer = SetTimer(NULL, 1, 3600*1000, NULL);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
if (msg.message == WM_TIMER)
{
//獲取毫秒級時間操作
SYSTEMTIME sys;
GetLocalTime(&sys);
char curtime[20];
sprintf_s(curtime, "%02d", sys.wHour);
string updatetime = curtime;
//到凌晨一點執行刪除更新日誌文件
if (updatetime == "01")
{
//自動保留7天日誌
//日誌存放路徑和保留天數
saveDays("log", 7);
num++;
cout << "執行次數: " << num << endl;
}
}
}
KillTimer(NULL, dairyTimer);
return 0;
}
效果圖:
創建一個線程去啓動這個定時器,就能時刻對日誌文件夾進行處理啦。
創建日誌的部分看你自己使用的日誌庫。我就不貼上來了,網上都有。
至此,完成了保留最近n天日誌文件的處理。
這個程序是肯定存在有bug的地方。具體是哪些,大家可以互相交流學習一下。把這個程序完善好。
有大佬的話,可以在評論區留言告訴我。謝謝大家。