c++ 多线程写日志的一个很实用的日志类源码(支持 c++ builder)

简介:

1.日志基类

.h文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//---------------------------------------------------------------------------
#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文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//---------------------------------------------------------------------------
 
 
#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文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//---------------------------------------------------------------------------
 
#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
1
  
1
cpp文件
1
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
//---------------------------------------------------------------------------
 
 
#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.随便测试的代码

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//---------------------------------------------------------------------------
 
#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;
}
//---------------------------------------------------------------------------
1
  
相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
3天前
|
存储 编译器 C语言
c++的学习之路:5、类和对象(1)
c++的学习之路:5、类和对象(1)
19 0
|
3天前
|
C++
c++的学习之路:7、类和对象(3)
c++的学习之路:7、类和对象(3)
19 0
|
2天前
|
设计模式 Java C++
【C++高阶(八)】单例模式&特殊类的设计
【C++高阶(八)】单例模式&特殊类的设计
|
2天前
|
编译器 C++
【C++基础(八)】类和对象(下)--初始化列表,友元,匿名对象
【C++基础(八)】类和对象(下)--初始化列表,友元,匿名对象
|
6天前
|
存储 安全 C语言
【C++】string类
【C++】string类
|
存储 编译器 Linux
标准库中的string类(中)+仅仅反转字母+字符串中的第一个唯一字符+字符串相加——“C++”“Leetcode每日一题”
标准库中的string类(中)+仅仅反转字母+字符串中的第一个唯一字符+字符串相加——“C++”“Leetcode每日一题”
|
8天前
|
编译器 C++
标准库中的string类(上)——“C++”
标准库中的string类(上)——“C++”
|
8天前
|
编译器 C++
自从学了C++之后,小雅兰就有对象了!!!(类与对象)(中)——“C++”
自从学了C++之后,小雅兰就有对象了!!!(类与对象)(中)——“C++”
|
8天前
|
存储 编译器 C++
自从学了C++之后,小雅兰就有对象了!!!(类与对象)(上)——“C++”
自从学了C++之后,小雅兰就有对象了!!!(类与对象)(上)——“C++”
|
9天前
|
C++
【C++成长记】C++入门 | 类和对象(下) |Static成员、 友元
【C++成长记】C++入门 | 类和对象(下) |Static成员、 友元