首页 > 编程 > C++ > 正文

教你C++语言编写写日志类的步骤

2020-02-24 14:28:36
字体:
来源:转载
供稿:网友

编写日志类是用C++语言编写的,它支持设置日志级别,支持多线程,支持可变形参数表写入日志,下文是武林技术频道小编给大家带来的教你C++语言编写写日志类的步骤,一起来看看吧!
主要提供以下接口:

  • 1、设置写日志的级别
  • 2、写关键日志信息
  • 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 * 作用:提供写日志功能,支持多线程,支持可变形参数操作,支持写日志级别的设置 * 接口: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
#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);}

教你C++语言编写写日志类的步骤,大家都了解了吗?通过武林技术频道相关人士的介绍,相信大家都清楚了吧,希望上文信息可以帮助到您!

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表