C++ multithreaded log writing a very practical log class source code (support c++ builder)
1.日志基类
.h文件
//---------------------------------------------------------------------------
#ifndef UnitLogWriterH
#define UnitLogWriterH
#include <vcl.h>
#include <time.h>
#include <assert.h>
//---------------------------------------------------------------------------
class LogFile
{
protected:
CRITICAL_SECTION _csLock;
char * _szFileName;
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); }
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));
}
private://屏蔽函数
LogFile(const LogFile&);
LogFile&operator = (const LogFile&);
};
#endif
基类cpp文件
//---------------------------------------------------------------------------
#pragma hdrstop
#include "UnitLogWriter.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
LogFile::LogFile(const char *szFileName)
{
_szFileName = NULL;
_hFile = INVALID_HANDLE_VALUE;
::InitializeCriticalSection(&_csLock);
SetFileName(szFileName);
}
//-------------------------------------------------------------------------
LogFile::~LogFile()
{
::DeleteCriticalSection(&_csLock);
Close();
if(_szFileName)
delete []_szFileName;
}
//-------------------------------------------------------------------------
bool LogFile::OpenFile()
{
if(IsOpen())
return true;
if(!_szFileName)
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)
{
time_t now;
char temp[21];
DWORD dwWriteLength;
if(IsOpen())
{
time(&now);
strftime(temp, 20, "%Y-%m-%d %H:%M:%S", localtime(&now));
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::SetFileName(const char *szName)
{
assert(szName);
if(_szFileName)
delete []_szFileName;
Close();
_szFileName = new char[strlen(szName) + 1];
assert(_szFileName);
strcpy(_szFileName, szName);
}
//-------------------------------------------------------------------------
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();
}
}
1
2.日志派生类
.h文件
//---------------------------------------------------------------------------
#ifndef LogFileExH
#define LogFileExH
#include <assert.h>
#include "UnitLogWriter.h"
//---------------------------------------------------------------------------
class LogFileEx : public LogFile
{
protected:
char *_szPath;
char _szLastDate[9];
int _iType;
void SetPath(const char *szPath);
public:
enum LOG_TYPE{YEAR = 0, MONTH = 1, DAY = 2};
LogFileEx(const char *szPath = ".", LOG_TYPE iType = MONTH);
~LogFileEx();
const char * GetPath();
void Log(LPCVOID lpBuffer, DWORD dwLength);
void Log(const char *szText);
void Log(const AnsiString&szText);
private://屏蔽函数
LogFileEx(const LogFileEx&);
LogFileEx&operator = (const LogFileEx&);
};
#endif
cpp文件
//---------------------------------------------------------------------------
#pragma hdrstop
#include "LogFileEx.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
//-------------------------------------------------------------------------
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)
{
strcat(strcpy(temp, szPath), " Create Fail. Exit Now! Error ID :");
ltoa(GetLastError(), temp + strlen(temp), 10);
MessageBox(NULL, temp, "Class LogFileEx", MB_OK);
exit(1);
}
else
{
GetFullPathName(szPath, MAX_PATH, temp, NULL);
_szPath = new char[strlen(temp) + 1];
assert(_szPath);
strcpy(_szPath, temp);
}
}
//-------------------------------------------------------------------------
LogFileEx::LogFileEx(const char *szPath , LOG_TYPE iType)
{
_szPath = NULL;
SetPath(szPath);
_iType = iType;
memset(_szLastDate, 0, 9);
}
//-------------------------------------------------------------------------
LogFileEx::~LogFileEx()
{
if(_szPath)
delete []_szPath;
}
//-------------------------------------------------------------------------
const char * LogFileEx::GetPath()
{
return _szPath;
}
//-------------------------------------------------------------------------
void LogFileEx::Log(LPCVOID lpBuffer, DWORD dwLength)
{
assert(lpBuffer);
char temp[10];
static const char format[3][10] = {"%Y", "%Y-%m", "%Y%m%d"};
__try
{
Lock();
time_t now = time(NULL);
strftime(temp, 9, format[_iType], localtime(&now));
if(strcmp(_szLastDate, temp) != 0)//更换文件名
{
strcat(strcpy(_szFileName, _szPath), "\\");
strcat(strcat(_szFileName, temp), ".log");
strcpy(_szLastDate, temp);
Close();
}
if(!OpenFile())
return;
WriteLog(lpBuffer, dwLength);
}
__finally
{
Unlock();
}
}
//-------------------------------------------------------------------------
void LogFileEx::Log(const char *szText)
{
Log(szText, strlen(szText));
}
//-------------------------------------------------------------------------
void LogFileEx::Log(const AnsiString&szText)
{
Log(szText.c_str(),szText.Length());
}
3.随便测试的代码
//---------------------------------------------------------------------------
#include <vcl.h>
#include <conio.h>
#include "LogFileEx.h"
#pragma hdrstop
//---------------------------------------------------------------------------
#pragma argsused
int main(int argc, char* argv[])
{
LogFileEx log;
log.Log("哈哈");
AnsiString temp="adsfsadfsadfsaf";
log.Log(temp);
log.Log(temp);
getch();
return 0;
}
//---------------------------------------------------------------------------
Copy the code