C++語言編寫寫日志類
使用C++語言編寫寫日志類,支持寫日志級別設(shè)置、支持多線程、支持可變形參表寫日志。
主要提供以下接口:
- 1、設(shè)置寫日志的級別
- 2、寫關(guān)鍵日志信息
- 3、寫錯誤日志信息
- 4、寫警告日志信息
- 5、寫一般日志信息
#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
#ifndef LOGGER_H_
#define LOGGER_H_
#include <Windows.h>
#include <stdio.h>
#include "CommandDefine.h"
/*
* 類名:Logger
* 作用:提供寫日志功能,支持多線程,支持可變形參數(shù)操作,支持寫日志級別的設(shè)置
* 接口:SetLogLevel:設(shè)置寫日志級別
TraceKeyInfo:忽略日志級別,寫關(guān)鍵信息
TraceError:寫錯誤信息
TraceWarning:寫警告信息
TraceInfo:寫一般信息
*/
class Logger
{
public:
//默認(rèn)構(gòu)造函數(shù)
Logger();
//構(gòu)造函數(shù)
Logger(const char * strLogPath, EnumLogLevel nLogLevel = EnumLogLevel::LogLevelNormal);
//析構(gòu)函數(shù)
virtual ~Logger();
public:
//寫關(guān)鍵信息
void TraceKeyInfo(const char * strInfo, ...);
//寫錯誤信息
void TraceError(const char* strInfo, ...);
//寫警告信息
void TraceWarning(const char * strInfo, ...);
//寫一般信息
void TraceInfo(const char * strInfo, ...);
//設(shè)置寫日志級別
void SetLogLevel(EnumLogLevel nLevel);
private:
//寫文件操作
void Trace(const char * strInfo);
//獲取當(dāng)前系統(tǒng)時間
char * GetCurrentTime();
//創(chuàng)建日志文件名稱
void GenerateLogName();
//創(chuàng)建日志路徑
void CreateLogPath();
private:
//寫日志文件流
FILE * m_pFileStream;
//寫日志級別
EnumLogLevel m_nLogLevel;
//日志的路徑
char m_strLogPath[MAX_STR_LEN];
//日志的名稱
char m_strCurLogName[MAX_STR_LEN];
//線程同步的臨界區(qū)變量
CRITICAL_SECTION m_cs;
};
#endif
#include "Logger.h"
#include <imagehlp.h>
#include <time.h>
#include <string.h>
#include <stdarg.h>
#pragma comment(lib, "DbgHelp.lib")
//默認(rèn)構(gòu)造函數(shù)
Logger::Logger()
{
//初始化
memset(m_strLogPath, 0, MAX_STR_LEN);
memset(m_strCurLogName, 0, MAX_STR_LEN);
m_pFileStream = NULL;
//設(shè)置默認(rèn)的寫日志級別
m_nLogLevel = EnumLogLevel::LogLevelNormal;
//初始化臨界區(qū)變量
InitializeCriticalSection(&m_cs);
//創(chuàng)建日志文件名
GenerateLogName();
}
//構(gòu)造函數(shù)
Logger::Logger(const char * strLogPath, EnumLogLevel nLogLevel):m_nLogLevel(nLogLevel)
{
//初始化
m_pFileStream = NULL;
strcpy(m_strLogPath, strLogPath);
InitializeCriticalSection(&m_cs);
CreateLogPath();
GenerateLogName();
}
//析構(gòu)函數(shù)
Logger::~Logger()
{
//釋放臨界區(qū)
DeleteCriticalSection(&m_cs);
//關(guān)閉文件流
if(m_pFileStream)
fclose(m_pFileStream);
}
//寫關(guān)鍵信息接口
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, ...)
{
//判斷當(dāng)前的寫日志級別,若設(shè)置為不寫日志則函數(shù)返回
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, ...)
{
//判斷當(dāng)前的寫日志級別,若設(shè)置為只寫錯誤信息則函數(shù)返回
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, ...)
{
//判斷當(dāng)前的寫日志級別,若設(shè)置只寫錯誤和警告信息則函數(shù)返回
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;
}
//獲取系統(tǒng)當(dāng)前時間
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;
}
//設(shè)置寫日志級別
void Logger::SetLogLevel(EnumLogLevel nLevel)
{
m_nLogLevel = nLevel;
}
//寫文件操作
void Logger::Trace(const char * strInfo)
{
if(!strInfo)
return;
try
{
//進入臨界區(qū)
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);
//離開臨界區(qū)
LeaveCriticalSection(&m_cs);
}
//若發(fā)生異常,則先離開臨界區(qū),防止死鎖
catch(...)
{
LeaveCriticalSection(&m_cs);
}
}
//創(chuàng)建日志文件的名稱
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+");
}
}
//創(chuàng)建日志文件的路徑
void Logger::CreateLogPath()
{
if(0 != strlen(m_strLogPath))
{
strcat(m_strLogPath, "\\");
}
MakeSureDirectoryPathExists(m_strLogPath);
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)C++有所幫助。
您可能感興趣的文章
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用函數(shù)刪除字符
- 04-02c語言的正則匹配函數(shù) c語言正則表達式函數(shù)庫
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言中對數(shù)函數(shù)的表達式 c語言中對數(shù)怎么表達
- 04-02c語言用函數(shù)寫分段 用c語言表示分段函數(shù)
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排序法函數(shù)
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段函數(shù)
- 04-02C語言中怎么打出三角函數(shù) c語言中怎么打出三角函數(shù)的值
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求階乘


閱讀排行
本欄相關(guān)
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言的正則匹配函數(shù) c語言正則表達
- 04-02c語言用函數(shù)寫分段 用c語言表示分段
- 04-02c語言中對數(shù)函數(shù)的表達式 c語言中對
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數(shù) c語言中怎
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
隨機閱讀
- 01-11ajax實現(xiàn)頁面的局部加載
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 01-10delphi制作wav文件的方法
- 01-10C#中split用法實例總結(jié)
- 04-02jquery與jsp,用jquery
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改


