c++日志


//可按日期生成多个日志, 还可分年月日频率生成文件名

 

//这个代码我用工业现场24X7值守的程序纪录各种信息, 简单易用;

//一般用一个全局日志对象, 有临界排斥可以多线程安全使用。

//有两个类

//class LogFile;//用户定义日志文件名

//class LogFileEx;//有日志文件名自动生成功能 , 可分年月日频率生成文件名, 可指定日志存放的目录

//LogFile gLog("My.Log");

//gLog.Log("test", 4);//记录日志

//gLog.Log("系统启动");

//LogFileEx gLog(".", LogFileEx :: YEAR);//一年生成一个日志文件

//LogFileEx gLog(".//Log", LogFileEx :: MONTH);//一月生成一个日志文件

//LogFileEx gLog(".//Log", LogFileEx :: DAY);//一天生成一个日志文件

//注意日志所属目录创建失败会自动退出, 请注意目录的合法性, 文件生成频率看情况掌握

//24小时运行的程序可以每天生成一个日志文件, 以免内容过多

 

 

#ifndef _LOGFILE_H

#define _LOGFILE_H

#include <assert.h>

#include <time.h>

#include <stdio.h>

#include <windows.h>

 

 

class LogFile

{

public:

 

	LogFile(const char *szFileName = "Log.log"); //设定日志文件名

	virtual ~LogFile();

	const char * GetFileName(){ return _szFileName; }

	void SetFileName(const char *szName); //修改文件名, 同时关闭上一个日志文件

	bool IsOpen() { return _hFile != INVALID_HANDLE_VALUE; }

	void Close();

	void Log(LPCVOID lpBuffer, DWORD dwLength); //追加日志内容

	void Log(const char *szText){ Log(szText, strlen(szText)); }

 

protected:

	CRITICAL_SECTION _csLock;

	char _szFileName[MAX_PATH + 1];

	HANDLE _hFile;

 

	bool OpenFile(); //打开文件, 指针到文件尾

	DWORD Write(LPCVOID lpBuffer, DWORD dwLength);

	virtual void WriteLog( LPCVOID lpBuffer, DWORD dwLength); //写日志, 可以扩展修改

	void Lock()  { ::EnterCriticalSection(&_csLock); }

	void Unlock() { ::LeaveCriticalSection(&_csLock); }

 

 

private://屏蔽函数

	LogFile(const LogFile&);

	LogFile&operator = (const LogFile&);

};

 

 

class LogFileEx : public LogFile

{

public:

	enum LOG_TYPE{YEAR = 0, MONTH = 1, DAY = 2};

	LogFileEx(const char *szPath = ".", LOG_TYPE iType = MONTH);

	~LogFileEx();

	const char * GetPath(){ return _szPath; }

	void Log(LPCVOID lpBuffer, DWORD dwLength);

	void Log(const char *szText){ Log(szText, strlen(szText)); }

 

protected:

	char _szPath[MAX_PATH + 1];

	char _szLastDate[20];

	int _iType;

	void SetPath(const char *szPath);

 

private://屏蔽函数

	LogFileEx(const LogFileEx&);

	LogFileEx&operator = (const LogFileEx&);

};

#endif

#include "stdafx.h"

#include "Logfile.h"

 

 

//-----------------------------------------------------------------------------------------

 

LogFile::LogFile(const char *szFileName)//设定日志文件名

{

	_hFile = INVALID_HANDLE_VALUE;

	::InitializeCriticalSection(&_csLock);

	SetFileName(szFileName);

}

 

//-----------------------------------------------------------------------------------------

 

LogFile::~LogFile()

{

	::DeleteCriticalSection(&_csLock);

	Close();

}

 

//-----------------------------------------------------------------------------------------

 

 

void LogFile::SetFileName(const char *szName)//修改文件名, 同时关闭上一个日志文件

{

	Close();

	memset(_szFileName, 0, MAX_PATH + 1);

	strcpy_s(_szFileName, MAX_PATH + 1, szName);

}

 

//-----------------------------------------------------------------------------------------

 

bool LogFile::OpenFile()//打开文件, 指针到文件尾

{

	if(IsOpen())

		return true;

 

	if(strcmp(_szFileName, "") == 0)

		return false;

 

	_hFile =  CreateFile(

		_szFileName, 

		GENERIC_WRITE,

		FILE_SHARE_READ | FILE_SHARE_WRITE,

		NULL,

		OPEN_EXISTING,

		FILE_ATTRIBUTE_NORMAL,

		NULL 

		);

 

	if(!IsOpen() && GetLastError() == 2)//打开不成功, 且因为文件不存在, 创建文件

		_hFile =  CreateFile(

		_szFileName, 

		GENERIC_WRITE,

		FILE_SHARE_READ | FILE_SHARE_WRITE,

		NULL,

		OPEN_ALWAYS,

		FILE_ATTRIBUTE_NORMAL,

		NULL 

		); 

 

	if(IsOpen())

		SetFilePointer(_hFile, 0, NULL, FILE_END);

 

	return IsOpen();

}

 

//-----------------------------------------------------------------------------------------

 

DWORD LogFile::Write(LPCVOID lpBuffer, DWORD dwLength)

{

	DWORD dwWriteLength = 0;

	if(IsOpen())

		WriteFile(_hFile, lpBuffer, dwLength, &dwWriteLength, NULL);

	return dwWriteLength;

}

 

//-----------------------------------------------------------------------------------------

 

 

void LogFile::WriteLog( LPCVOID lpBuffer, DWORD dwLength)//写日志, 可以扩展修改

{

	

	char temp[21] = {0};

	DWORD dwWriteLength;

	if(IsOpen())

	{

		time_t now;

		time(&now);

		tm timeInfo;

		localtime_s(&timeInfo, &now); //转换成tm结构

		strftime(temp, sizeof(temp), "%Y-%m-%d %H:%M:%S", &timeInfo);

		WriteFile(_hFile, "\xd\xa#-----------------------------", 32, &dwWriteLength, NULL);

		WriteFile(_hFile, temp, 19, &dwWriteLength, NULL);

		WriteFile(_hFile, "-----------------------------#\xd\xa", 32, &dwWriteLength, NULL);

		WriteFile(_hFile, lpBuffer, dwLength, &dwWriteLength, NULL);

		WriteFile(_hFile, "\xd\xa", 2, &dwWriteLength, NULL);

 

		FlushFileBuffers(_hFile);

	}

}

 

//-----------------------------------------------------------------------------------------

 

void LogFile::Close()

{

	if(IsOpen())

	{

		CloseHandle(_hFile);

		_hFile = INVALID_HANDLE_VALUE;

	}

}

 

//-----------------------------------------------------------------------------------------

 

void LogFile::Log(LPCVOID lpBuffer, DWORD dwLength)//追加日志内容

{

	assert(lpBuffer);

	__try

	{

		Lock();

		if(!OpenFile())

			return;

		WriteLog(lpBuffer, dwLength);

	}

	__finally

	{

		Unlock();

	} 

}

 

//LogFileEx**********************************************************************************

 

 

LogFileEx::LogFileEx(const char *szPath, LOG_TYPE iType)

{

	memset(_szPath, 0, sizeof(_szPath));

	SetPath(szPath);

	_iType = iType;

	memset(_szLastDate, 0, sizeof(_szLastDate));

}

 

//---------------------------------------------------------------------------------

 

LogFileEx::~LogFileEx()

{

	

}

 

//---------------------------------------------------------------------------------

 

 

void LogFileEx::Log(LPCVOID lpBuffer, DWORD dwLength)

{

	assert(lpBuffer);;

	static const char format[3][10] = {"%Y", "%Y-%m", "%Y%m%d"};

 

	__try

	{

		Lock();

 

		char temp[20] = {0};

		time_t now = time(NULL);

		tm timeInfo;

		localtime_s(&timeInfo, &now); //转成tm结构

		strftime(temp, sizeof(temp), format[_iType], &timeInfo);

		if(strcmp(_szLastDate, temp) != 0)//更换文件名

		{

			int len = sizeof(_szFileName);

			strcpy_s(_szFileName, len, _szPath); len -= strlen(_szPath);

			strcat_s(_szFileName, len, "//"); len -= 2;

			strcat_s(_szFileName, len, temp); len -= sizeof(temp);

			strcat_s(_szFileName, len, ".log"); len -= 4;

 

			strcpy_s(_szLastDate, sizeof(_szLastDate), temp);

			Close();

		}

		if(!OpenFile())

			return;

 

		WriteLog(lpBuffer, dwLength);

	}

	__finally

	{

		Unlock();

	}

}

 

//---------------------------------------------------------------------------------

void LogFileEx::SetPath(const char *szPath)

{

	assert(szPath);

	WIN32_FIND_DATA wfd;

	char temp[MAX_PATH + 1] = {0};

	if(FindFirstFile(szPath, &wfd) == INVALID_HANDLE_VALUE && CreateDirectory(szPath, NULL) == 0)

	{

		strcpy_s(temp, sizeof(temp), szPath);

		strcat_s(temp, sizeof(temp), " Create Fail. Exit Now! Error ID :");

		_ltoa_s(GetLastError(), temp + strlen(temp), 20, 10);

		MessageBox(NULL, temp, "Class LogFileEx", MB_OK);

		exit(1);

	}

	else

	{

		GetFullPathName(szPath, MAX_PATH, temp, NULL);

		strcpy_s(_szPath, sizeof(_szPath), temp);

	}

}

// Main.cpp : Defines the entry point for the console application.

//

 

#include "stdafx.h"

#include "Common/Logfile.h"

 

 

int _tmain(int argc, _TCHAR* argv[])

{

	LogFileEx log("../Debug/Logfiles");

 

	for (int i=0; i<1000000; ++i)

		log.Log("4646456015555555555555555555555555555555555555");

 

	printf("已完成");

	getchar();

	return 0;

}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值