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