log

#ifndef COMMAND_DEFINE_H
#define COMMAND_DEFINE_H
//日誌級別的提示信息
static const char * KEYINFOPREFIX   = " Key: \n";
static const char * ERRORPREFIX = " Error: \n";
static const char * WARNINGPREFIX   = " Warning: \n";
static const char * INFOPREFIX      = " Info: \n";
 
static const int MAX_STR_LEN = 1024;
//日誌級別枚舉
typedef enum EnumLogLevel
{
    LogLevelAll = 0,    //所有信息都寫日誌
    LogLevelMid,        //寫錯誤、警告信息
    LogLevelNormal,     //只寫錯誤信息
    LogLevelStop        //不寫日誌
};
 
#endif

[2].[文件] Logger.h ~ 1KB    下載(230) 跳至 [1] [2] [3]

?
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
#ifndef LOGGER_H_
#define LOGGER_H_
#include <Windows.h>
#include <stdio.h>
#include "CommandDefine.h"
/*
    * 類名:Logger
    * 作用:提供寫日誌功能,支持多線程,支持可變形參數操作,支持寫日誌級別的設置
    * 接口:SetLogLevel:設置寫日誌級別
            TraceKeyInfo:忽略日誌級別,寫關鍵信息
            TraceError:寫錯誤信息
            TraceWarning:寫警告信息
            TraceInfo:寫一般信息
*/
class Logger
{
public:
    //默認構造函數
    Logger();
    //構造函數
    Logger(const char * strLogPath, EnumLogLevel nLogLevel = EnumLogLevel::LogLevelNormal);
    //析構函數
    virtual ~Logger();
public:
    //寫關鍵信息
    void TraceKeyInfo(const char * strInfo, ...);
    //寫錯誤信息
    void TraceError(const char* strInfo, ...);
    //寫警告信息
    void TraceWarning(const char * strInfo, ...);
    //寫一般信息
    void TraceInfo(const char * strInfo, ...);
    //設置寫日誌級別
    void SetLogLevel(EnumLogLevel nLevel);
private:
    //寫文件操作
    void Trace(const char * strInfo);
    //獲取當前系統時間
    char * GetCurrentTime();
    //創建日誌文件名稱
    void GenerateLogName();
    //創建日誌路徑
    void CreateLogPath();
private:
    //寫日誌文件流
    FILE * m_pFileStream;
    //寫日誌級別
    EnumLogLevel m_nLogLevel;
    //日誌的路徑
    char m_strLogPath[MAX_STR_LEN];
    //日誌的名稱
    char m_strCurLogName[MAX_STR_LEN];
    //線程同步的臨界區變量
    CRITICAL_SECTION m_cs;
};
 
#endif

[3].[文件] Logger.cpp ~ 4KB    下載(210) 跳至 [1] [2] [3]

?
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
#include "Logger.h"
#include <imagehlp.h>
#include <time.h>
#include <string.h>
#include <stdarg.h>
 
#pragma comment(lib, "DbgHelp.lib")
 
//默認構造函數
Logger::Logger()
{
    //初始化
    memset(m_strLogPath, 0, MAX_STR_LEN);
    memset(m_strCurLogName, 0, MAX_STR_LEN);
    m_pFileStream = NULL;
    //設置默認的寫日誌級別
    m_nLogLevel = EnumLogLevel::LogLevelNormal;
    //初始化臨界區變量
    InitializeCriticalSection(&m_cs);
    //創建日誌文件名
    GenerateLogName();
}
 
//構造函數
Logger::Logger(const char * strLogPath, EnumLogLevel nLogLevel):m_nLogLevel(nLogLevel)
{
    //初始化
    m_pFileStream = NULL;
    strcpy(m_strLogPath, strLogPath);
    InitializeCriticalSection(&m_cs);
    CreateLogPath();
    GenerateLogName();
}
 
 
//析構函數
Logger::~Logger()
{
    //釋放臨界區
    DeleteCriticalSection(&m_cs);
    //關閉文件流
    if(m_pFileStream)
        fclose(m_pFileStream);
}
 
//寫關鍵信息接口
void Logger::TraceKeyInfo(const char * strInfo, ...)
{
    if(!strInfo)
        return;
    char pTemp[MAX_STR_LEN] = {0};
    strcpy(pTemp, GetCurrentTime());
    strcat(pTemp, KEYINFOPREFIX);
    //獲取可變形參
    va_list arg_ptr = NULL;
    va_start(arg_ptr, strInfo);
    vsprintf(pTemp + strlen(pTemp), strInfo, arg_ptr);
    va_end(arg_ptr);
    //寫日誌文件
    Trace(pTemp);
    arg_ptr = NULL;
 
}
 
//寫錯誤信息
void Logger::TraceError(const char* strInfo, ...)
{
    //判斷當前的寫日誌級別,若設置爲不寫日誌則函數返回
    if(m_nLogLevel >= EnumLogLevel::LogLevelStop)
        return;
    if(!strInfo)
        return;
    char pTemp[MAX_STR_LEN] = {0};
    strcpy(pTemp, GetCurrentTime());
    strcat(pTemp, ERRORPREFIX);
    va_list arg_ptr = NULL;
    va_start(arg_ptr, strInfo);
    vsprintf(pTemp + strlen(pTemp), strInfo, arg_ptr);
    va_end(arg_ptr);
    Trace(pTemp);
    arg_ptr = NULL;
}
 
//寫警告信息
void Logger::TraceWarning(const char * strInfo, ...)
{
    //判斷當前的寫日誌級別,若設置爲只寫錯誤信息則函數返回
    if(m_nLogLevel >= EnumLogLevel::LogLevelNormal)
        return;
    if(!strInfo)
        return;
    char pTemp[MAX_STR_LEN] = {0};
    strcpy(pTemp, GetCurrentTime());
    strcat(pTemp, WARNINGPREFIX);
    va_list arg_ptr = NULL;
    va_start(arg_ptr, strInfo);
    vsprintf(pTemp + strlen(pTemp), strInfo, arg_ptr);
    va_end(arg_ptr);
    Trace(pTemp);
    arg_ptr = NULL;
}
 
 
//寫一般信息
void Logger::TraceInfo(const char * strInfo, ...)
{
    //判斷當前的寫日誌級別,若設置只寫錯誤和警告信息則函數返回
    if(m_nLogLevel >= EnumLogLevel::LogLevelMid)
        return;
    if(!strInfo)
        return;
    char pTemp[MAX_STR_LEN] = {0};
    strcpy(pTemp, GetCurrentTime());
    strcat(pTemp,INFOPREFIX);
    va_list arg_ptr = NULL;
    va_start(arg_ptr, strInfo);
    vsprintf(pTemp + strlen(pTemp), strInfo, arg_ptr);
    va_end(arg_ptr);
    Trace(pTemp);
    arg_ptr = NULL;
}
 
//獲取系統當前時間
char * Logger::GetCurrentTime()
{
    time_t curTime;
    struct tm * pTimeInfo = NULL;
    time(&curTime);
    pTimeInfo = localtime(&curTime);
    char temp[MAX_STR_LEN] = {0};
    sprintf(temp, "%02d:%02d:%02d", pTimeInfo->tm_hour, pTimeInfo->tm_min, pTimeInfo->tm_sec);
    char * pTemp = temp;
    return pTemp;  
}
 
//設置寫日誌級別
void Logger::SetLogLevel(EnumLogLevel nLevel)
{
    m_nLogLevel = nLevel;
}
 
//寫文件操作
void Logger::Trace(const char * strInfo)
{
    if(!strInfo)
        return;
    try
    {
        //進入臨界區
        EnterCriticalSection(&m_cs);
        //若文件流沒有打開,則重新打開
        if(!m_pFileStream)
        {
            char temp[1024] = {0};
            strcat(temp, m_strLogPath);
            strcat(temp, m_strCurLogName);
            m_pFileStream = fopen(temp, "a+");
            if(!m_pFileStream)
            {
                return;
            }
        }
        //寫日誌信息到文件流
        fprintf(m_pFileStream, "%s\n", strInfo);
        fflush(m_pFileStream);
        //離開臨界區
        LeaveCriticalSection(&m_cs);
    }
    //若發生異常,則先離開臨界區,防止死鎖
    catch(...)
    {
        LeaveCriticalSection(&m_cs);
    }
}
 
//創建日誌文件的名稱
void Logger::GenerateLogName()
{
    time_t curTime;
    struct tm * pTimeInfo = NULL;
    time(&curTime);
    pTimeInfo = localtime(&curTime);
    char temp[1024] = {0};
    //日誌的名稱如:2013-01-01.log
    sprintf(temp, "%04d-%02d-%02d.log", pTimeInfo->tm_year+1900, pTimeInfo->tm_mon + 1, pTimeInfo->tm_mday);
    if(0 != strcmp(m_strCurLogName, temp))
    {
        strcpy(m_strCurLogName,temp);
        if(m_pFileStream)
            fclose(m_pFileStream);
        char temp[1024] = {0};
        strcat(temp, m_strLogPath);
        strcat(temp, m_strCurLogName);
        //以追加的方式打開文件流
        m_pFileStream = fopen(temp, "a+");
    }
 
}
 
//創建日誌文件的路徑
void Logger::CreateLogPath()
{
    if(0 != strlen(m_strLogPath))
    {
        strcat(m_strLogPath, "\\");
    }
    MakeSureDirectoryPathExists(m_strLogPath);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章