c++マルチスレッド書き込みログの実用的なログクラスソース(c++builderをサポート)

9574 ワード

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();

       }

}
 

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;

}

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