个人如何建网站/企业网站优化排名
- //logger.h
- /*
- //类名:CLogger
- //功能介绍:Win平台日志记录功能,多线程安全,支持写日志级别的设置,日志格式包含日志等级,日志时间,文件名,行号信息
- //作者:sunflover 2016-1-15 14:31:27
- //使用方法:
- 1:将logger.h,logger.cpp添加到项目中
- 2:设置logger.cpp的预编译头选项为“不使用预编译头”
- 3:使用代码示例:
- #include "Logger.h"
- using namespace LOGGER;
- CLogger logger(LogLevel_Info,CLogger::GetAppPathA().append("log\\"));
- void main()
- {
- logger.TraceFatal("TraceFatal %d", 1);
- logger.TraceError("TraceError %s", "sun");
- logger.TraceWarning("TraceWarning");
- logger.TraceInfo("TraceInfo");
- logger.ChangeLogLevel(LOGGER::LogLevel_Error);
- logger.TraceFatal("TraceFatal %d", 2);
- logger.TraceError("TraceError %s", "sun2");
- logger.TraceWarning("TraceWarning");
- logger.TraceInfo("TraceInfo");
- }
- 执行结果:20160126_101329.log文件内容如下
- Fatal 2016-01-26 10:13:29 TraceFatal 1
- Error 2016-01-26 10:13:29 TraceError sun
- Warning 2016-01-26 10:13:29 TraceWarning
- Info 2016-01-26 10:13:29 TraceInfo
- Fatal 2016-01-26 10:13:29 TraceFatal 2
- Error 2016-01-26 10:13:29 TraceError sun2
- */
- namespace LOGGER
- {
- //日志级别的提示信息
- static const std::string strFatalPrefix = "Fatal\t";
- static const std::string strErrorPrefix = "Error\t";
- static const std::string strWarningPrefix = "Warning\t";
- static const std::string strInfoPrefix = "Info\t";
- //日志级别枚举
- typedef enum EnumLogLevel
- {
- LogLevel_Stop = 0, //什么都不记录
- LogLevel_Fatal, //只记录严重错误
- LogLevel_Error, //记录严重错误,普通错误
- LogLevel_Warning, //记录严重错误,普通错误,警告
- LogLevel_Info //记录严重错误,普通错误,警告,提示信息(也就是全部记录)
- };
- class CLogger
- {
- public:
- //nLogLevel:日志记录的等级,可空
- //strLogPath:日志目录,可空
- //strLogName:日志名称,可空
- CLogger(EnumLogLevel nLogLevel = EnumLogLevel::LogLevel_Info, const std::string strLogPath = "", const std::string strLogName = "");
- //析构函数
- virtual ~CLogger();
- public:
- //写严重错误信息
- void TraceFatal(const char *lpcszFormat, ...);
- //写错误信息
- void TraceError(const char *lpcszFormat, ...);
- //写警告信息
- void TraceWarning(const char *lpcszFormat, ...);
- //写提示信息
- void TraceInfo(const char *lpcszFormat, ...);
- //改变写日志级别
- void ChangeLogLevel(EnumLogLevel nLevel);
- //获取程序运行路径
- static std::string GetAppPathA();
- //格式化字符串
- static std::string FormatString(const char *lpcszFormat, ...);
- private:
- //写文件操作
- void Trace(const std::string &strLog);
- //获取当前系统时间
- std::string GetTime();
- //文件全路径得到文件名
- const char *path_file(const char *path, char splitter);
- private:
- //写日志文件流
- FILE * m_pFileStream;
- //写日志级别
- EnumLogLevel m_nLogLevel;
- //日志目录
- std::string m_strLogPath;
- //日志的名称
- std::string m_strLogName;
- //日志文件全路径
- std::string m_strLogFilePath;
- //线程同步的临界区变量
- CRITICAL_SECTION m_cs;
- };
- }
- //logger.cpp
- using std::string;
- using std::vector;
- namespace LOGGER
- {
- CLogger::CLogger(EnumLogLevel nLogLevel, const std::string strLogPath, const std::string strLogName)
- :m_nLogLevel(nLogLevel),
- m_strLogPath(strLogPath),
- m_strLogName(strLogName)
- {
- //初始化
- m_pFileStream = NULL;
- if (m_strLogPath.empty())
- {
- m_strLogPath = GetAppPathA();
- }
- if (m_strLogPath[m_strLogPath.length()-1] != '\\')
- {
- m_strLogPath.append("\\");
- }
- //创建文件夹
- MakeSureDirectoryPathExists(m_strLogPath.c_str());
- //创建日志文件
- if (m_strLogName.empty())
- {
- time_t curTime;
- time(&curTime);
- tm tm1;
- localtime_s(&tm1, &curTime);
- //日志的名称如:201601012130.log
- m_strLogName = FormatString("%04d%02d%02d_%02d%02d%02d.log", tm1.tm_year + 1900, tm1.tm_mon + 1, tm1.tm_mday, tm1.tm_hour, tm1.tm_min, tm1.tm_sec);
- }
- m_strLogFilePath = m_strLogPath.append(m_strLogName);
- //以追加的方式打开文件流
- fopen_s(&m_pFileStream, m_strLogFilePath.c_str(), "a+");
- InitializeCriticalSection(&m_cs);
- }
- //析构函数
- CLogger::~CLogger()
- {
- //释放临界区
- DeleteCriticalSection(&m_cs);
- //关闭文件流
- if (m_pFileStream)
- {
- fclose(m_pFileStream);
- m_pFileStream = NULL;
- }
- }
- //文件全路径得到文件名
- const char *CLogger::path_file(const char *path, char splitter)
- {
- return strrchr(path, splitter) ? strrchr(path, splitter) + 1 : path;
- }
- //写严重错误信息
- void CLogger::TraceFatal(const char *lpcszFormat, ...)
- {
- //判断当前的写日志级别
- if (EnumLogLevel::LogLevel_Fatal > m_nLogLevel)
- return;
- string strResult;
- if (NULL != lpcszFormat)
- {
- va_list marker = NULL;
- va_start(marker, lpcszFormat); //初始化变量参数
- size_t nLength = _vscprintf(lpcszFormat, marker) + 1; //获取格式化字符串长度
- std::vector<char> vBuffer(nLength, '\0'); //创建用于存储格式化字符串的字符数组
- int nWritten = _vsnprintf_s(&vBuffer[0], vBuffer.size(), nLength, lpcszFormat, marker);
- if (nWritten > 0)
- {
- strResult = &vBuffer[0];
- }
- va_end(marker); //重置变量参数
- }
- if (strResult.empty())
- {
- return;
- }
- string strLog = strFatalPrefix;
- strLog.append(GetTime()).append(strResult);
- //写日志文件
- Trace(strLog);
- }
- //写错误信息
- void CLogger::TraceError(const char *lpcszFormat, ...)
- {
- //判断当前的写日志级别
- if (EnumLogLevel::LogLevel_Error > m_nLogLevel)
- return;
- string strResult;
- if (NULL != lpcszFormat)
- {
- va_list marker = NULL;
- va_start(marker, lpcszFormat); //初始化变量参数
- size_t nLength = _vscprintf(lpcszFormat, marker) + 1; //获取格式化字符串长度
- std::vector<char> vBuffer(nLength, '\0'); //创建用于存储格式化字符串的字符数组
- int nWritten = _vsnprintf_s(&vBuffer[0], vBuffer.size(), nLength, lpcszFormat, marker);
- if (nWritten > 0)
- {
- strResult = &vBuffer[0];
- }
- va_end(marker); //重置变量参数
- }
- if (strResult.empty())
- {
- return;
- }
- string strLog = strErrorPrefix;
- strLog.append(GetTime()).append(strResult);
- //写日志文件
- Trace(strLog);
- }
- //写警告信息
- void CLogger::TraceWarning(const char *lpcszFormat, ...)
- {
- //判断当前的写日志级别
- if (EnumLogLevel::LogLevel_Warning > m_nLogLevel)
- return;
- string strResult;
- if (NULL != lpcszFormat)
- {
- va_list marker = NULL;
- va_start(marker, lpcszFormat); //初始化变量参数
- size_t nLength = _vscprintf(lpcszFormat, marker) + 1; //获取格式化字符串长度
- std::vector<char> vBuffer(nLength, '\0'); //创建用于存储格式化字符串的字符数组
- int nWritten = _vsnprintf_s(&vBuffer[0], vBuffer.size(), nLength, lpcszFormat, marker);
- if (nWritten > 0)
- {
- strResult = &vBuffer[0];
- }
- va_end(marker); //重置变量参数
- }
- if (strResult.empty())
- {
- return;
- }
- string strLog = strWarningPrefix;
- strLog.append(GetTime()).append(strResult);
- //写日志文件
- Trace(strLog);
- }
- //写一般信息
- void CLogger::TraceInfo(const char *lpcszFormat, ...)
- {
- //判断当前的写日志级别
- if (EnumLogLevel::LogLevel_Info > m_nLogLevel)
- return;
- string strResult;
- if (NULL != lpcszFormat)
- {
- va_list marker = NULL;
- va_start(marker, lpcszFormat); //初始化变量参数
- size_t nLength = _vscprintf(lpcszFormat, marker) + 1; //获取格式化字符串长度
- std::vector<char> vBuffer(nLength, '\0'); //创建用于存储格式化字符串的字符数组
- int nWritten = _vsnprintf_s(&vBuffer[0], vBuffer.size(), nLength, lpcszFormat, marker);
- if (nWritten > 0)
- {
- strResult = &vBuffer[0];
- }
- va_end(marker); //重置变量参数
- }
- if (strResult.empty())
- {
- return;
- }
- string strLog = strInfoPrefix;
- strLog.append(GetTime()).append(strResult);
- //写日志文件
- Trace(strLog);
- }
- //获取系统当前时间
- string CLogger::GetTime()
- {
- time_t curTime;
- time(&curTime);
- tm tm1;
- localtime_s(&tm1, &curTime);
- //2016-01-01 21:30:00
- string strTime = FormatString("%04d-%02d-%02d %02d:%02d:%02d ", tm1.tm_year + 1900, tm1.tm_mon + 1, tm1.tm_mday, tm1.tm_hour, tm1.tm_min, tm1.tm_sec);
- return strTime;
- }
- //改变写日志级别
- void CLogger::ChangeLogLevel(EnumLogLevel nLevel)
- {
- m_nLogLevel = nLevel;
- }
- //写文件操作
- void CLogger::Trace(const string &strLog)
- {
- try
- {
- //进入临界区
- EnterCriticalSection(&m_cs);
- //若文件流没有打开,则重新打开
- if (NULL == m_pFileStream)
- {
- fopen_s(&m_pFileStream, m_strLogFilePath.c_str(), "a+");
- if (!m_pFileStream)
- {
- return;
- }
- }
- //写日志信息到文件流
- fprintf(m_pFileStream, "%s\n", strLog.c_str());
- fflush(m_pFileStream);
- //离开临界区
- LeaveCriticalSection(&m_cs);
- }
- //若发生异常,则先离开临界区,防止死锁
- catch (...)
- {
- LeaveCriticalSection(&m_cs);
- }
- }
- string CLogger::GetAppPathA()
- {
- char szFilePath[MAX_PATH] = { 0 }, szDrive[MAX_PATH] = { 0 }, szDir[MAX_PATH] = { 0 }, szFileName[MAX_PATH] = { 0 }, szExt[MAX_PATH] = { 0 };
- GetModuleFileNameA(NULL, szFilePath, sizeof(szFilePath));
- _splitpath_s(szFilePath, szDrive, szDir, szFileName, szExt);
- string str(szDrive);
- str.append(szDir);
- return str;
- }
- string CLogger::FormatString(const char *lpcszFormat, ...)
- {
- string strResult;
- if (NULL != lpcszFormat)
- {
- va_list marker = NULL;
- va_start(marker, lpcszFormat); //初始化变量参数
- size_t nLength = _vscprintf(lpcszFormat, marker) + 1; //获取格式化字符串长度
- std::vector<char> vBuffer(nLength, '\0'); //创建用于存储格式化字符串的字符数组
- int nWritten = _vsnprintf_s(&vBuffer[0], vBuffer.size(), nLength, lpcszFormat, marker);
- if (nWritten > 0)
- {
- strResult = &vBuffer[0];
- }
- va_end(marker); //重置变量参数
- }
- return strResult;
- }
- }
有图有真相:
- //logger.h
- /*
- //类名:CLogger
- //功能介绍:Win平台日志记录功能,多线程安全,支持写日志级别的设置,日志格式包含日志等级,日志时间,文件名,行号信息
- //作者:sunflover 2016-1-15 14:31:27
- //使用方法:
- 1:将logger.h,logger.cpp添加到项目中
- 2:设置logger.cpp的预编译头选项为“不使用预编译头”
- 3:使用代码示例:
- #include "Logger.h"
- using namespace LOGGER;
- CLogger logger(LogLevel_Info,CLogger::GetAppPathA().append("log\\"));
- void main()
- {
- logger.TraceFatal("TraceFatal %d", 1);
- logger.TraceError("TraceError %s", "sun");
- logger.TraceWarning("TraceWarning");
- logger.TraceInfo("TraceInfo");
- logger.ChangeLogLevel(LOGGER::LogLevel_Error);
- logger.TraceFatal("TraceFatal %d", 2);
- logger.TraceError("TraceError %s", "sun2");
- logger.TraceWarning("TraceWarning");
- logger.TraceInfo("TraceInfo");
- }
- 执行结果:20160126_101329.log文件内容如下
- Fatal 2016-01-26 10:13:29 TraceFatal 1
- Error 2016-01-26 10:13:29 TraceError sun
- Warning 2016-01-26 10:13:29 TraceWarning
- Info 2016-01-26 10:13:29 TraceInfo
- Fatal 2016-01-26 10:13:29 TraceFatal 2
- Error 2016-01-26 10:13:29 TraceError sun2
- */
- namespace LOGGER
- {
- //日志级别的提示信息
- static const std::string strFatalPrefix = "Fatal\t";
- static const std::string strErrorPrefix = "Error\t";
- static const std::string strWarningPrefix = "Warning\t";
- static const std::string strInfoPrefix = "Info\t";
- //日志级别枚举
- typedef enum EnumLogLevel
- {
- LogLevel_Stop = 0, //什么都不记录
- LogLevel_Fatal, //只记录严重错误
- LogLevel_Error, //记录严重错误,普通错误
- LogLevel_Warning, //记录严重错误,普通错误,警告
- LogLevel_Info //记录严重错误,普通错误,警告,提示信息(也就是全部记录)
- };
- class CLogger
- {
- public:
- //nLogLevel:日志记录的等级,可空
- //strLogPath:日志目录,可空
- //strLogName:日志名称,可空
- CLogger(EnumLogLevel nLogLevel = EnumLogLevel::LogLevel_Info, const std::string strLogPath = "", const std::string strLogName = "");
- //析构函数
- virtual ~CLogger();
- public:
- //写严重错误信息
- void TraceFatal(const char *lpcszFormat, ...);
- //写错误信息
- void TraceError(const char *lpcszFormat, ...);
- //写警告信息
- void TraceWarning(const char *lpcszFormat, ...);
- //写提示信息
- void TraceInfo(const char *lpcszFormat, ...);
- //改变写日志级别
- void ChangeLogLevel(EnumLogLevel nLevel);
- //获取程序运行路径
- static std::string GetAppPathA();
- //格式化字符串
- static std::string FormatString(const char *lpcszFormat, ...);
- private:
- //写文件操作
- void Trace(const std::string &strLog);
- //获取当前系统时间
- std::string GetTime();
- //文件全路径得到文件名
- const char *path_file(const char *path, char splitter);
- private:
- //写日志文件流
- FILE * m_pFileStream;
- //写日志级别
- EnumLogLevel m_nLogLevel;
- //日志目录
- std::string m_strLogPath;
- //日志的名称
- std::string m_strLogName;
- //日志文件全路径
- std::string m_strLogFilePath;
- //线程同步的临界区变量
- CRITICAL_SECTION m_cs;
- };
- }
- //logger.cpp
- using std::string;
- using std::vector;
- namespace LOGGER
- {
- CLogger::CLogger(EnumLogLevel nLogLevel, const std::string strLogPath, const std::string strLogName)
- :m_nLogLevel(nLogLevel),
- m_strLogPath(strLogPath),
- m_strLogName(strLogName)
- {
- //初始化
- m_pFileStream = NULL;
- if (m_strLogPath.empty())
- {
- m_strLogPath = GetAppPathA();
- }
- if (m_strLogPath[m_strLogPath.length()-1] != '\\')
- {
- m_strLogPath.append("\\");
- }
- //创建文件夹
- MakeSureDirectoryPathExists(m_strLogPath.c_str());
- //创建日志文件
- if (m_strLogName.empty())
- {
- time_t curTime;
- time(&curTime);
- tm tm1;
- localtime_s(&tm1, &curTime);
- //日志的名称如:201601012130.log
- m_strLogName = FormatString("%04d%02d%02d_%02d%02d%02d.log", tm1.tm_year + 1900, tm1.tm_mon + 1, tm1.tm_mday, tm1.tm_hour, tm1.tm_min, tm1.tm_sec);
- }
- m_strLogFilePath = m_strLogPath.append(m_strLogName);
- //以追加的方式打开文件流
- fopen_s(&m_pFileStream, m_strLogFilePath.c_str(), "a+");
- InitializeCriticalSection(&m_cs);
- }
- //析构函数
- CLogger::~CLogger()
- {
- //释放临界区
- DeleteCriticalSection(&m_cs);
- //关闭文件流
- if (m_pFileStream)
- {
- fclose(m_pFileStream);
- m_pFileStream = NULL;
- }
- }
- //文件全路径得到文件名
- const char *CLogger::path_file(const char *path, char splitter)
- {
- return strrchr(path, splitter) ? strrchr(path, splitter) + 1 : path;
- }
- //写严重错误信息
- void CLogger::TraceFatal(const char *lpcszFormat, ...)
- {
- //判断当前的写日志级别
- if (EnumLogLevel::LogLevel_Fatal > m_nLogLevel)
- return;
- string strResult;
- if (NULL != lpcszFormat)
- {
- va_list marker = NULL;
- va_start(marker, lpcszFormat); //初始化变量参数
- size_t nLength = _vscprintf(lpcszFormat, marker) + 1; //获取格式化字符串长度
- std::vector<char> vBuffer(nLength, '\0'); //创建用于存储格式化字符串的字符数组
- int nWritten = _vsnprintf_s(&vBuffer[0], vBuffer.size(), nLength, lpcszFormat, marker);
- if (nWritten > 0)
- {
- strResult = &vBuffer[0];
- }
- va_end(marker); //重置变量参数
- }
- if (strResult.empty())
- {
- return;
- }
- string strLog = strFatalPrefix;
- strLog.append(GetTime()).append(strResult);
- //写日志文件
- Trace(strLog);
- }
- //写错误信息
- void CLogger::TraceError(const char *lpcszFormat, ...)
- {
- //判断当前的写日志级别
- if (EnumLogLevel::LogLevel_Error > m_nLogLevel)
- return;
- string strResult;
- if (NULL != lpcszFormat)
- {
- va_list marker = NULL;
- va_start(marker, lpcszFormat); //初始化变量参数
- size_t nLength = _vscprintf(lpcszFormat, marker) + 1; //获取格式化字符串长度
- std::vector<char> vBuffer(nLength, '\0'); //创建用于存储格式化字符串的字符数组
- int nWritten = _vsnprintf_s(&vBuffer[0], vBuffer.size(), nLength, lpcszFormat, marker);
- if (nWritten > 0)
- {
- strResult = &vBuffer[0];
- }
- va_end(marker); //重置变量参数
- }
- if (strResult.empty())
- {
- return;
- }
- string strLog = strErrorPrefix;
- strLog.append(GetTime()).append(strResult);
- //写日志文件
- Trace(strLog);
- }
- //写警告信息
- void CLogger::TraceWarning(const char *lpcszFormat, ...)
- {
- //判断当前的写日志级别
- if (EnumLogLevel::LogLevel_Warning > m_nLogLevel)
- return;
- string strResult;
- if (NULL != lpcszFormat)
- {
- va_list marker = NULL;
- va_start(marker, lpcszFormat); //初始化变量参数
- size_t nLength = _vscprintf(lpcszFormat, marker) + 1; //获取格式化字符串长度
- std::vector<char> vBuffer(nLength, '\0'); //创建用于存储格式化字符串的字符数组
- int nWritten = _vsnprintf_s(&vBuffer[0], vBuffer.size(), nLength, lpcszFormat, marker);
- if (nWritten > 0)
- {
- strResult = &vBuffer[0];
- }
- va_end(marker); //重置变量参数
- }
- if (strResult.empty())
- {
- return;
- }
- string strLog = strWarningPrefix;
- strLog.append(GetTime()).append(strResult);
- //写日志文件
- Trace(strLog);
- }
- //写一般信息
- void CLogger::TraceInfo(const char *lpcszFormat, ...)
- {
- //判断当前的写日志级别
- if (EnumLogLevel::LogLevel_Info > m_nLogLevel)
- return;
- string strResult;
- if (NULL != lpcszFormat)
- {
- va_list marker = NULL;
- va_start(marker, lpcszFormat); //初始化变量参数
- size_t nLength = _vscprintf(lpcszFormat, marker) + 1; //获取格式化字符串长度
- std::vector<char> vBuffer(nLength, '\0'); //创建用于存储格式化字符串的字符数组
- int nWritten = _vsnprintf_s(&vBuffer[0], vBuffer.size(), nLength, lpcszFormat, marker);
- if (nWritten > 0)
- {
- strResult = &vBuffer[0];
- }
- va_end(marker); //重置变量参数
- }
- if (strResult.empty())
- {
- return;
- }
- string strLog = strInfoPrefix;
- strLog.append(GetTime()).append(strResult);
- //写日志文件
- Trace(strLog);
- }
- //获取系统当前时间
- string CLogger::GetTime()
- {
- time_t curTime;
- time(&curTime);
- tm tm1;
- localtime_s(&tm1, &curTime);
- //2016-01-01 21:30:00
- string strTime = FormatString("%04d-%02d-%02d %02d:%02d:%02d ", tm1.tm_year + 1900, tm1.tm_mon + 1, tm1.tm_mday, tm1.tm_hour, tm1.tm_min, tm1.tm_sec);
- return strTime;
- }
- //改变写日志级别
- void CLogger::ChangeLogLevel(EnumLogLevel nLevel)
- {
- m_nLogLevel = nLevel;
- }
- //写文件操作
- void CLogger::Trace(const string &strLog)
- {
- try
- {
- //进入临界区
- EnterCriticalSection(&m_cs);
- //若文件流没有打开,则重新打开
- if (NULL == m_pFileStream)
- {
- fopen_s(&m_pFileStream, m_strLogFilePath.c_str(), "a+");
- if (!m_pFileStream)
- {
- return;
- }
- }
- //写日志信息到文件流
- fprintf(m_pFileStream, "%s\n", strLog.c_str());
- fflush(m_pFileStream);
- //离开临界区
- LeaveCriticalSection(&m_cs);
- }
- //若发生异常,则先离开临界区,防止死锁
- catch (...)
- {
- LeaveCriticalSection(&m_cs);
- }
- }
- string CLogger::GetAppPathA()
- {
- char szFilePath[MAX_PATH] = { 0 }, szDrive[MAX_PATH] = { 0 }, szDir[MAX_PATH] = { 0 }, szFileName[MAX_PATH] = { 0 }, szExt[MAX_PATH] = { 0 };
- GetModuleFileNameA(NULL, szFilePath, sizeof(szFilePath));
- _splitpath_s(szFilePath, szDrive, szDir, szFileName, szExt);
- string str(szDrive);
- str.append(szDir);
- return str;
- }
- string CLogger::FormatString(const char *lpcszFormat, ...)
- {
- string strResult;
- if (NULL != lpcszFormat)
- {
- va_list marker = NULL;
- va_start(marker, lpcszFormat); //初始化变量参数
- size_t nLength = _vscprintf(lpcszFormat, marker) + 1; //获取格式化字符串长度
- std::vector<char> vBuffer(nLength, '\0'); //创建用于存储格式化字符串的字符数组
- int nWritten = _vsnprintf_s(&vBuffer[0], vBuffer.size(), nLength, lpcszFormat, marker);
- if (nWritten > 0)
- {
- strResult = &vBuffer[0];
- }
- va_end(marker); //重置变量参数
- }
- return strResult;
- }
- }
有图有真相: