源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

linux系统中c++写日志文件功能分享

  • 时间:2022-10-24 22:08 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:linux系统中c++写日志文件功能分享
简化了glog,只保留了写日志文件的功能,只是改写了linux版本,win版本未改写,可以用 LOG(INFO)<< 输出日志 也可用LOG_IF(INFO,condition)<<输出日志 也可直接调用日志类Logger::GetInstance().Error 等方式写日志 初始化时调用 InitLogging(argv[0],INFO,"./log/test"); 第一个参数是路径,第二个参数是最低日志级别,第三个参数表示日志文件的前缀和文件夹 FileHelper.h #ifndef FILEHELPER_H_ #define FILEHELPER_H_ #include <string> #include <vector> #include <fstream> #include <stdio.h> #ifdef _WIN32 #include <direct.h> #include <io.h> #else #include <stdarg.h> #include <sys/stat.h> #endif namespace FrameWork { #ifdef _WIN32 #define ACCESS _access #define MKDIR(a) _mkdir((a)) #else #define ACCESS access #define MKDIR(a) mkdir((a),0755) #endif class FileHelper { public:  static bool save(const std::string filename, std::string& content)  {         FILE *file = fopen(filename.c_str(), "wb");         if (file == NULL)             return false;   fwrite(content.c_str(),sizeof(char),content.size(),file);   fclose(file);   return true;  }     // used to open binary file     static bool open(const std::string filename, std::string& content)     {         FILE *file = fopen(filename.c_str(), "rb");         if (file == NULL)             return false;         fseek(file, 0, SEEK_END);         int len = ftell(file);   rewind(file);   content.clear();         char *buffer = new char[len];         fread(buffer, sizeof(char), len, file);         content.assign(buffer, len);         delete []buffer;   //int nRead;   //content.clear();   //char buffer[80];   //while(!feof(file)){   // nRead = fread(buffer,sizeof(char),sizeof(buffer),file);   // if(nRead > 0){   //  content.append(buffer);   // }   //}         fclose(file);         return true;     }     // used to open text file     static bool open(const std::string file_name, std::vector<std::string>& lines)     {         std::ifstream file(file_name.c_str(), std::ios::in);         if (!file)         {             return false;         }         lines.clear();         char buffer[BUFFER_SIZE];         while (file.getline(buffer, BUFFER_SIZE, '\n'))         {             lines.push_back(buffer);         }         return true;     }     static bool CreateDir(const char *pszDir)     {      size_t i = 0;      size_t iRet;      size_t iLen = strlen(pszDir);      char* buf=new char[iLen+1];      strncpy(buf,pszDir,iLen+1);      for (i = 0;i < iLen;i ++) {       if (pszDir[i] == '\\' || pszDir[i] == '/') {        buf[i] = '\0';        //如果不存在,创建        iRet = ACCESS(buf,0);        if (iRet != 0) {         iRet = MKDIR(buf);         if (iRet != 0) {          delete[] buf;          return false;         }        }        //支持linux,将所有\换成/        buf[i] = '/';       }      }      delete[] buf;      return true;     } private:     enum { BUFFER_SIZE = 3000 }; }; } /* namespace FrameWork */ #endif /* FILEHELPER_H_ */ [/code] Logger.cpp
[u]复制代码[/u] 代码如下:
#include "Logger.h" #include<cstring> #include<time.h> #include<cstdarg> #include<cstdlib> #include<assert.h> #include "FileHelper.h" #include "Mutex.h" namespace FrameWork { Mutex LogMessage::mutex; static char _defaltFolder[]="/var/tmp/"; static char _appName[MaxFilePathLen]; static char _appFolder[MaxFilePathLen]; static char _destFolder[MaxFilePathLen]; static char _destPrefix[MaxFilePathLen]; static LogLevel _destLevel; static char _levelInfos[][16]={  "Debug","Info","Warn","Error","Fatal" }; const int BUFFER_SIZE = 8196; static char _gBuffer[BUFFER_SIZE]; void combine_folder(char** destpath, char* basefolder,char* relativefolder) {  int lenb = strlen(basefolder);  int lenr = strlen(relativefolder);  char* pret = (char*)malloc((lenb+lenr+1)*sizeof(char));  int pos=lenb-1;  memset(pret,0,lenb+lenr+1);  while(pos>0 && ( basefolder[pos]!='/'))   pos--;  strncpy(*destpath,basefolder,pos+1);  if(relativefolder[0] == '\\' || relativefolder[0] == '/'){   strncpy(*destpath+pos+1,relativefolder+1,lenr-1);  }else{   strncpy(*destpath+pos+1,relativefolder,lenr);  } } static void InitPaths(const char* filename,const char* destFolder) {  memset(_appName,0,MaxFilePathLen);  memset(_appFolder,0,MaxFilePathLen);  memset(_destFolder,0,MaxFilePathLen);  memset(_destPrefix,0,MaxFilePathLen);  strcpy(_appName,filename);  int len = strlen(filename),lend;  int pos = len-1,posd,start;  while(pos >0 && filename[pos] != PathSplitChar)   pos--;  strncpy(_appFolder,filename,pos+1);  lend = strlen(destFolder);  posd = lend-1;  if(destFolder[lend-1] != PathSplitChar) {   //has prefix   while(posd >0 && destFolder[posd] != PathSplitChar)    posd--;  }  if(destFolder[0] == '.' && destFolder[1] == PathSplitChar){   strncpy(_destFolder,filename,pos+1);   start = 2;  } else{   pos = 8;   strcpy(_destFolder,_defaltFolder);   if(destFolder[0] != PathSplitChar){    start = 0;   }else{    start = 1;   }  }  strncpy(_destFolder+pos+1,destFolder+start,posd-start+1);  strncpy(_destPrefix,filename,pos+1);  strncpy(_destPrefix+pos+1,destFolder+start,lend-start); } void InitLogging(const char* filename,LogLevel minlevel,const char* destFolder) {  InitPaths(filename,destFolder);  _destLevel = minlevel; }   static string GetLocalDate(void) {  time_t t = time(0);  tm *ld;  char tmp[64] = "";  ld=localtime(&t);  strftime(tmp,sizeof(tmp),"%Y-%m-%d",ld);  return string(tmp); } static string GetCurTime(void) {  time_t t = time(0);  tm *ld;  char tmp[64] = "";  ld=localtime(&t);  strftime(tmp,sizeof(tmp),"%Y-%m-%d %H:%M:%S",ld);  return string(tmp); } Logger::Logger(LogLevel level,char * folder,char * prefix)  :level(level) {  std::string path;  path.append(prefix);  path.append(GetLocalDate());  path.append(".log");  FileHelper::CreateDir(folder);  logPrefix.append(prefix);  logPath = path;  logFile.open(path.c_str(),ios::app|ios::out);  logFile<<"Log file created at:"<<GetCurTime()<<endl; } Logger::~Logger() {  logFile.close(); } #define IMPLEMENT_LOG_FUNC1(cname,fname,lv) \ void cname::fname(string msg) {\     if(level <= lv){\         WriterMutexLock lock(&mutex);\         logFile<<"["<<GetCurTime().c_str()<<"][" #lv "]"<<msg.c_str()<<endl;\         logFile.flush();\     }\ } #define PRINT_ARGS_TO_BUFFER(fmt,buf) \     {\         memset(buf,0,sizeof(buf));\   va_list argp;\   va_start(argp,fmt);\   vsprintf(buf,fmt,argp);\   va_end(argp);\     } #define IMPLEMENT_LOG_FUNC2(cname,fname,lv) \ void cname::fname(const char* format,...) {\  if(level <= lv){\   WriterMutexLock lock(&mutex);\   PRINT_ARGS_TO_BUFFER(format,_gBuffer)\   logFile<<"["<<GetCurTime().c_str()<<"][" #lv "]"<<_gBuffer<<endl;\   logFile.flush();\  }\ } #define IMPLEMENT_LOG_FUNC(cname,fname,lv) \ IMPLEMENT_LOG_FUNC1(cname,fname,lv)\ IMPLEMENT_LOG_FUNC2(cname,fname,lv) IMPLEMENT_LOG_FUNC(Logger,Debug,DEBUG) IMPLEMENT_LOG_FUNC(Logger,Info,INFO) IMPLEMENT_LOG_FUNC(Logger,Warn,WARN) IMPLEMENT_LOG_FUNC(Logger,Error,ERROR) IMPLEMENT_LOG_FUNC(Logger,Fatal,FATAL) Logger& Logger::GetInstance() {  static Logger _logger(_destLevel,_destFolder,_destPrefix);  return _logger; } void Logger::Log(LogLevel lv, string msg) {  if(level <= lv){   WriterMutexLock lock(&mutex);   logFile<<"["<<GetCurTime().c_str()<<"]["<<_levelInfos[lv+1]<<"]"<<msg.c_str()<<endl;   logFile.flush();  } } void Logger::Log(LogLevel lv, const char* format,...) {  if(level <= lv){   WriterMutexLock lock(&mutex);   PRINT_ARGS_TO_BUFFER(format,_gBuffer)   logFile<<"["<<GetCurTime().c_str()<<"]["<<_levelInfos[lv+1]<<"]"<<_gBuffer<<endl;   logFile.flush();  } } void Logger::Log(const char* file, int line, LogLevel lv, string msg) {  if(level <= lv){   WriterMutexLock lock(&mutex);   logFile<<"["<<GetCurTime().c_str()<<"]["<<_levelInfos[lv+1]<<"]["<<file<<"]["<<line<<"]"<<msg.c_str();   logFile.flush();  } } Logger* Logger::GetInstancePtr() {  return &GetInstance(); } void Logger::Log(const char* file, int line, LogLevel lv, const char* format,...) {  if(level <= lv){   WriterMutexLock lock(&mutex);   PRINT_ARGS_TO_BUFFER(format,_gBuffer)   logFile<<"["<<GetCurTime().c_str()<<"]["<<_levelInfos[lv+1]<<"]["<<file<<"]["<<line<<"]"<<_gBuffer;   logFile.flush();  } } LogMessage::LogMessage(const char* file, int line, LogLevel lv) {  logger = Logger::GetInstancePtr();  mutex.Lock();  logger->Log(file,line,lv,""); } LogMessage::~LogMessage() {  logger->stream()<<endl;  logger->stream().flush();  mutex.Unlock(); } } /* namespace FrameWork */
Logger.h
[u]复制代码[/u] 代码如下:
#ifndef LOGGER_H_ #define LOGGER_H_ #include "ILogger.h" #include "Mutex.h" #include<fstream> #include<string> const int MaxFilePathLen = 1024; const char PathSplitChar = '/'; namespace FrameWork { enum LogLevel{     /// <summary>     /// 调试     /// </summary>     DEBUG = -1,     /// <summary>     /// 普通日志     /// </summary>     INFO = 0,     /// <summary>     /// 警告     /// </summary>     WARN,     /// <summary>     /// 错误     /// </summary>     ERROR,     /// <summary>     /// 崩溃     /// </summary>     FATAL,     /// <summary>     /// 超出错误级别     /// </summary>     OFF }; class ILogger { public:  //  virtual ~ILogger(){} #define ABSTRACT_LOG_FUNC(name) \     virtual void name(string msg)=0; \     virtual void name(const char* fmt,...)=0;     ABSTRACT_LOG_FUNC(Debug)     ABSTRACT_LOG_FUNC(Info)     ABSTRACT_LOG_FUNC(Warn)     ABSTRACT_LOG_FUNC(Error)     ABSTRACT_LOG_FUNC(Fatal) #undef ABSTRACT_LOG_FUNC #define ABSTRACT_LOG_FUNC_X(name) \     virtual void name(LogLevel lv,string msg)=0; \     virtual void name(LogLevel lv,const char* fmt,...)=0;\     virtual void name(const char* file,int line,LogLevel lv,string msg)=0;\     virtual void name(const char* file,int line,LogLevel lv,const char* fmt,...)=0;     ABSTRACT_LOG_FUNC_X(Log) #undef LOG_FUNC_X }; class Logger: public ILogger {  std::string logPath;  std::string logPrefix;  std::fstream logFile;  LogLevel level;  Mutex mutex;  Logger(LogLevel level,char * folder,char * prefix); public:  static Logger& GetInstance();  static Logger* GetInstancePtr();  virtual ~Logger();  inline fstream & stream(){return logFile;} #define DECLARE_LOG_FUNC(name) \     virtual void name(string msg); \     virtual void name(const char* fmt,...); #define DECLARE_LOG_FUNC_X(name) \     virtual void name(LogLevel lv,string msg); \     virtual void name(LogLevel lv,const char* fmt,...);\     virtual void name(const char* file,int line,LogLevel lv,string msg);\     virtual void name(const char* file,int line,LogLevel lv,const char* fmt,...);     DECLARE_LOG_FUNC(Debug)     DECLARE_LOG_FUNC(Info)     DECLARE_LOG_FUNC(Warn)     DECLARE_LOG_FUNC(Error)     DECLARE_LOG_FUNC(Fatal)     DECLARE_LOG_FUNC_X(Log) #undef DECLARE_LOG_FUNC_X #undef DECLARE_LOG_FUNC }; class LogMessage {  Logger* logger;  static Mutex mutex; public:  LogMessage(const char* file, int line,LogLevel lv);  ostream& stream(){return logger->stream();}  virtual ~LogMessage(); }; void InitLogging(const char* filename,LogLevel minlevel,const char* destFolder); void CloseLogging(); #define LOG(level) LogMessage(__FILE__, __LINE__,level).stream() #define LOG_IF(severity, condition) \  !(condition) ? (void) 0 : LOG(severity) #define LOG_ASSERT(condition)  \  LOG_IF(FATAL, !(condition)) << "Assert failed: " #condition #define CHECK(condition)  \  LOG_IF(FATAL, !(condition)) \  << "Check failed: " #condition " " } /* namespace FrameWork */ #endif /* LOGGER_H_ */
 main.cpp  
[u]复制代码[/u] 代码如下:
 #include <iostream> #include "Logger.h" using namespace std; using namespace FrameWork; int main(int argc,char* argv[]) {  InitLogging(argv[0],INFO,"./log/test");  cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!  LOG(INFO)<<"info test";  LOG(WARN)<<"WARN TEST %d"<<20;  LOG(ERROR)<<"Error test %d %s"<<20<<"nihao";  Logger::GetInstance().Error("error test common");  Logger::GetInstance().Fatal("fatal test common %d ",100);  Logger::GetInstance().Info("info test normal %d %s ",50,"zhongguoren");  return 0; }  
 Mutex.h  
[u]复制代码[/u] 代码如下:
 #ifndef MUTEX_H_ #define MUTEX_H_ #include <pthread.h> #include <stdlib.h> namespace FrameWork { typedef pthread_mutex_t MutexType; class Mutex { public:  // Create a Mutex that is not held by anybody.  This constructor is  // typically used for Mutexes allocated on the heap or the stack.  // See below for a recommendation for constructing global Mutex  // objects.  inline Mutex();  // Destructor  inline ~Mutex();  inline void Lock();    // Block if needed until free then acquire exclusively  inline void Unlock();  // Release a lock acquired via Lock()  inline bool TryLock(); // If free, Lock() and return true, else return false  // Note that on systems that don't support read-write locks, these may  // be implemented as synonyms to Lock() and Unlock().  So you can use  // these for efficiency, but don't use them anyplace where being able  // to do shared reads is necessary to avoid deadlock.  inline void ReaderLock();   // Block until free or shared then acquire a share  inline void ReaderUnlock(); // Release a read share of this Mutex  inline void WriterLock() { Lock(); }     // Acquire an exclusive lock  inline void WriterUnlock() { Unlock(); } // Release a lock from WriterLock()  // TODO(hamaji): Do nothing, implement correctly.  inline void AssertHeld() {} private:  MutexType mutex_;  // We want to make sure that the compiler sets is_safe_ to true only  // when we tell it to, and never makes assumptions is_safe_ is  // always true.  volatile is the most reliable way to do that.  volatile bool is_safe_;  inline void SetIsSafe() { is_safe_ = true; }  // Catch the error of writing Mutex when intending MutexLock.  Mutex(Mutex* /*ignored*/) {}  // Disallow "evil" constructors  Mutex(const Mutex&);  void operator=(const Mutex&); }; #define SAFE_PTHREAD(fncall)  do {   /* run fncall if is_safe_ is true */  \  if (is_safe_ && fncall(&mutex_) != 0) abort();                           \  } while (0)  Mutex::Mutex()             {   SetIsSafe();   if (is_safe_ && pthread_mutex_init(&mutex_, NULL) != 0) abort();  }  Mutex::~Mutex()            { SAFE_PTHREAD(pthread_mutex_destroy); }  void Mutex::Lock()         { SAFE_PTHREAD(pthread_mutex_lock); }  void Mutex::Unlock()       { SAFE_PTHREAD(pthread_mutex_unlock); }  bool Mutex::TryLock()      { return is_safe_ ?   pthread_mutex_trylock(&mutex_) == 0 : true; }  void Mutex::ReaderLock()   { Lock(); }  void Mutex::ReaderUnlock() { Unlock(); }  class MutexLock {  public:   explicit MutexLock(Mutex *mu) : mu_(mu) { mu_->Lock(); }   ~MutexLock() { mu_->Unlock(); }  private:   Mutex * const mu_;   // Disallow "evil" constructors   MutexLock(const MutexLock&);   void operator=(const MutexLock&);  };  // ReaderMutexLock and WriterMutexLock do the same, for rwlocks  class ReaderMutexLock {  public:   explicit ReaderMutexLock(Mutex *mu) : mu_(mu) { mu_->ReaderLock(); }   ~ReaderMutexLock() { mu_->ReaderUnlock(); }  private:   Mutex * const mu_;   // Disallow "evil" constructors   ReaderMutexLock(const ReaderMutexLock&);   void operator=(const ReaderMutexLock&);  };  class WriterMutexLock {  public:   explicit WriterMutexLock(Mutex *mu) : mu_(mu) { mu_->WriterLock(); }   ~WriterMutexLock() { mu_->WriterUnlock(); }  private:   Mutex * const mu_;   // Disallow "evil" constructors   WriterMutexLock(const WriterMutexLock&);   void operator=(const WriterMutexLock&);  }; } /* namespace FrameWork */ #endif /* MUTEX_H_ */  
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部