C\C++ 日志记录

 

这是从csdn问答里看到的,是赵四老师的。找不到链接了。在此基础上做了一些修改。

这里可以定义清除多少天前的日志。

 

cpp:

#include "EParkingLog.h"
#include <corecrt_io.h>
#define MaxJsonBuffer 1024

CEParkingLog::CEParkingLog(char* pLogFileName)
{
	memset(m_szFileFlag, 0, sizeof(m_szFileFlag));
	if (pLogFileName != NULL)
	{
		memcpy(m_szFileFlag, pLogFileName, strlen(pLogFileName));
	}
	day = -1;
	changefile = 0;
	fp = NULL;
	m_Check = 0;
	m_Seq = 0;
	m_Temp = 0;
	string strTemp = GetLocalAppDataPath("EParking\\EParkingManage\\log\\");
	string strPath = strTemp;
	strcpy(file_name, strPath.c_str());
	_mkdir(file_name);

	name_len = strlen(file_name);
	ClearLog(15);
	InitializeCriticalSection(&m_LockInfo);
	InitializeCriticalSection(&m_LockCheck);
	InitializeCriticalSection(&m_LockSeq);	
	InitializeCriticalSection(&m_LockTemp);
}

CEParkingLog::~CEParkingLog(void)
{
} 


int CEParkingLog::WriteLogFile(const char *fmt,...)
{
	if (strlen(fmt) > MaxJsonBuffer - MAX_PATH)
	{
		return 0;
	}
	unsigned long res = 0;
	char *pLoginfo = new char[MaxJsonBuffer];
	char name[4096] = {0};
// 	time_t tm;
// 	struct tm *p_tm;
	SYSTEMTIME systi;
	GetLocalTime(&systi);
	va_list ap;
	memset(pLoginfo,0x00,MaxJsonBuffer);
	memset(name,0x00,sizeof(name));
	//取得当前时间
	//time(&tm);
	//p_tm = localtime(&tm);
	//取得文件名
	sprintf(name,"%s%04d-%02d-%02d %s.log",file_name, systi.wYear, systi.wMonth, systi.wDay,/*p_tm->tm_year+1900,p_tm->tm_mon+1,p_tm->tm_mday,*/ m_szFileFlag);
	if (day != systi.wDay/*p_tm->tm_mday*/)
	{
		day = systi.wDay/*p_tm->tm_mday*/;
		changefile = 1;
		if (fp != NULL)
		{
			fclose(fp);
			fp = NULL;
		}
	}
	//生成日志信息
	sprintf(pLoginfo, "[%04d-%02d-%02d %02d:%02d:%02d %3d]:", systi.wYear, systi.wMonth, systi.wDay, systi.wHour, systi.wMinute, systi.wSecond, systi.wMilliseconds); /*p_tm->tm_year + 1900, p_tm->tm_mon + 1, p_tm->tm_mday, p_tm->tm_hour,p_tm->tm_min,p_tm->tm_sec*/
	va_start(ap,fmt);
	vsprintf(pLoginfo+strlen(pLoginfo),fmt,ap);
	va_end(ap);
	//打开文件开始写
	EnterCriticalSection(&m_LockInfo);
	if (fp == NULL || changefile == 1)
	{
		fp = fopen(name,"a+");
		if (fp == NULL)
		{
			LeaveCriticalSection(&m_LockInfo);
			if (pLoginfo != NULL)
			{
				delete[] pLoginfo;
				pLoginfo = NULL;
			}
			return 0;
		}
		changefile = 0;
	}
	fwrite(pLoginfo,strlen(pLoginfo),1,fp);
	fwrite("\n", 1, 1, fp);
	fflush(fp);		//刷新
	res = ftell(fp);//用于得到文件当前位置相对于文件首的偏移字节数
	if (res > 30000000)
	{
		fclose(fp);
		fp = NULL;
		changefile = 1;
	}
	LeaveCriticalSection(&m_LockInfo);

	if (pLoginfo != NULL)
	{
		delete[] pLoginfo;
		pLoginfo = NULL;
	}
	return 1;
}

unsigned long CEParkingLog::WriteCheck()
{
	EnterCriticalSection(&m_LockCheck);
	m_Check++;
	LeaveCriticalSection(&m_LockCheck);
	return m_Check;
}

unsigned long CEParkingLog::WriteSeq()
{
	EnterCriticalSection(&m_LockSeq);
	m_Seq++;
	LeaveCriticalSection(&m_LockSeq);
	return m_Seq;
}

unsigned long CEParkingLog::WriteTemp()
{
	EnterCriticalSection(&m_LockTemp);
	m_Temp++;
	LeaveCriticalSection(&m_LockTemp);
	return m_Temp;
}

std::string CEParkingLog::GetLocalAppDataPath()
{  
    char m_lpszDefaultDir[MAX_PATH];  
    char szDocument[MAX_PATH] = {0};     
    memset(m_lpszDefaultDir, 0, _MAX_PATH);  
  
    LPITEMIDLIST pidl = NULL;  
    SHGetSpecialFolderLocation(NULL,   CSIDL_LOCAL_APPDATA,   &pidl);  
    if   (pidl && SHGetPathFromIDListA(pidl, szDocument))  
    {     
        GetShortPathNameA(szDocument,m_lpszDefaultDir, _MAX_PATH);  
    }  
  
    std::string wsR = m_lpszDefaultDir;  
  
    return wsR;  
}  
  
std::string CEParkingLog::GetLocalAppDataPath(std::string appName)
{  
    std::string path =  GetLocalAppDataPath();  
    path.append("\\");  
    path.append(appName);  
  
    if ( _access(path.c_str(), 0) == -1 )  
    {  
        _mkdir(path.c_str());  
    }  
  
    return path;  
}

// 功能:删除nDays天及之前的日志文件
// @nDays: 0-不删除日志,3-删除3天及之前的日志(保留今天、昨天、前天的日志) ...
void CEParkingLog::ClearLog(UINT nDays) // 删除N天前的日志
{
	if (nDays > 0)
	{
		WIN32_FIND_DATAA FindFileData;
		
		char szFileName[512] = { 0 };
		strcpy(szFileName, file_name);
		strcat(szFileName, "*.log");
		string m_sLogFolder = file_name;
		HANDLE hFind = ::FindFirstFileA(szFileName, &FindFileData);
		if (INVALID_HANDLE_VALUE == hFind) return;
		while (TRUE)
		{
			if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) // 遇到文件夹
			{
			}
			else // 遇到文件
			{
				try
				{
					string sFileName = FindFileData.cFileName;
					//sFileName.Format("%s", FindFileData.cFileName);
					if (sFileName.length() == 14)
					{
						string sFileFullPath = m_sLogFolder + "\\" + sFileName;// 文件全路径
						//sFileName.replace("-", "");
						int  nFileName = atoi(sFileName.c_str());   // 取得文件的日期,如:20101030
						SYSTEMTIME systi;
						GetLocalTime(&systi);
						tagDate dtBegin;
						tagDate dtEnd;

						dtBegin.year = atoi(sFileName.substr(0, 4).c_str());
						dtBegin.month = atoi(sFileName.substr(5, 2).c_str());
						dtBegin.day = atoi(sFileName.substr(8, 2).c_str());
						dtEnd.year = systi.wYear;
						dtEnd.month = systi.wMonth;
						dtEnd.day = systi.wDay;
						//CTime tNowTime = CTime::GetCurrentTime();
						//tNowTime = tNowTime - CTimeSpan(nDays, 0, 0, 0); // 指向nDays天前的日期
						//__int64 nNowTime = _atoi64(tNowTime.Format("%Y%m%d"));
						if (DateDiff(dtBegin, dtEnd) > nDays)
						{
							::DeleteFileA(sFileFullPath.c_str());
						}
					}
				}
				catch (exception ex)
				{
					//printf("删除超过15天的日志模块出错\n");
				}
			}
			if (!FindNextFileA(hFind, &FindFileData))
				break;
		}
		FindClose(hFind);
	}
}

//是否闰年  
int CEParkingLog::IsLeapYear(int year)
{
	return ((year % 4 == 0) && (year % 100 != 0) || year % 400 == 0);
}

//得到date.month的最大天数  
int CEParkingLog::GetLastDay(tagDate date)
{
	int num;
	switch (date.month)
	{
	case 1:
	case 3:
	case 5:
	case 7:
	case 8:
	case 10:
	case 12:
		num = 31;
		break;
	case 2:
		num = 28 + IsLeapYear(date.year);
		break;
	default:
		num = 30;
	}
	return num;
}

//日期是否合法  
int CEParkingLog::IsDateValid(tagDate date)
{
	if (date.year < 0 || date.month < 1 || date.month> 12)
		return 0;

	if (date.day <1 || date.day> GetLastDay(date))
		return 0;

	return 1;
}

//date+1  
void CEParkingLog::AddDay(tagDate *date)
{
	date->day++;
	if (date->day > GetLastDay(*date))
	{
		date->day = 1;
		date->month++;
		if (date->month > 12)
		{
			date->month = 1;
			date->year++;
		}
	}
}

//date1比date2小返回值为1,否则为0  
int CEParkingLog::Compare(tagDate date1, tagDate date2)
{
	if (date1.year < date2.year)
		return 1;
	if (date1.year <= date2.year && date1.month < date2.month)
		return 1;
	if (date1.year <= date2.year && date1.month <= date2.month && date1.day < date2.day)
		return 1;

	return 0;
}
//计算两个日期的间隔天数  
long CEParkingLog::DateDiff(tagDate date1, tagDate date2)
{
	long delta = 0;
	tagDate date3;
	//若date1 > date2,交换date1,date2  
	if (!Compare(date1, date2))
	{
		date3 = date2;
		date2 = date1;
		date1 = date3;
	}

	//date1比date2少时,date1日期加1  
	while (Compare(date1, date2))
	{
		AddDay(&date1);
		delta++;
	}
	return delta;
}


.h:

/*
功能:日志记录
日志目录:在APPData\\local\\EParking\\EParkingManage\\log\\2017-01-01.log
程序每次启动时,检测日志目录中日志文件的日期,如果是15天前的日志,则删除。
*/

#pragma once
#ifndef _CLASS_EPARKING_LOG_H_
#define _CLASS_EPARKING_LOG_H_
#define   WIN32_LEAN_AND_MEAN  
#include <windows.h>
#include <stdio.h>
#include <time.h> 
#include <direct.h> 
#include <string>
#include <Shlobj.h>  
#pragma comment( lib, "shell32.lib")
using namespace std;

struct tagDate
{
	int year;
	int month;
	int day;
};

class CEParkingLog
{
public:
	CEParkingLog(char* pLogFileName);//在日期后面的标志,如2017-09-18 server.log
public:
	~CEParkingLog(void);
	int WriteLogFile(const char *fmt,...);
	unsigned long WriteCheck();
	unsigned long WriteSeq();
	unsigned long WriteTemp();

private:
	char file_name[256];
	FILE *fp;
	int name_len;
	unsigned long m_Check ;
	unsigned long m_Seq ;
	unsigned long m_Temp;
	int day;
	int changefile;
	char m_szFileFlag[20];

	CRITICAL_SECTION m_LockInfo;
	CRITICAL_SECTION m_LockCheck;
	CRITICAL_SECTION m_LockSeq;
	CRITICAL_SECTION m_LockTemp;
private:
	//获取appdata目录
	std::string GetLocalAppDataPath();
	std::string GetLocalAppDataPath(std::string appName);

	void ClearLog(UINT nDays); // 删除N天前的日志;

	//以下是日期比较,根据是文件名上的日期和当前系统日期
	int IsLeapYear(int year);//闰年
	int GetLastDay(tagDate date);
	int IsDateValid(tagDate date);
	void AddDay(tagDate *date);
	int Compare(tagDate date1, tagDate date2);
	long DateDiff(tagDate date1, tagDate date2);//返回日期比较的结果
};
#endif //_CLASS_LOG_MY

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值