wxl

简单易用的日志类(C++, BC, VC, 多线程) 可按日期生成多个日志, 还可分年月日频率生成文件名

/*
  Log File Library(WIN98/NT/2000) 
  Compile by: BC++ 5; C++ BUILDER; VC++; VC.NET; 
  copyright(c) 2004.5 - 2005.3 llbird wushaojian@21cn.com http://blog.csdn.net/wujian53
  */
  /*
  Use:
  //这个代码我用工业现场24X7值守的程序纪录各种信息, 简单易用;
  //一般用一个全局日志对象, 有临界排斥可以多线程安全使用。
  //有两个类
  class LogFile;//用户定义日志文件名
  class LogFileEx;//有日志文件名自动生成功能 , 可分年月日频率生成文件名, 可指定日志存放的目录
  LogFile gLog("My.Log");
  gLog.Log("test", 4);//记录日志
  gLog.Log("系统启动");
  LogFileEx gLog(".", LogFileEx :: YEAR);//一年生成一个日志文件
  LogFileEx gLog(".\\Log", LogFileEx :: MONTH);//一月生成一个日志文件
  LogFileEx gLog(".\\Log", LogFileEx :: DAY);//一天生成一个日志文件
  //注意日志所属目录创建失败会自动退出, 请注意目录的合法性, 文件生成频率看情况掌握
  //24小时运行的程序可以每天生成一个日志文件, 以免内容过多
  */
  #ifndef _LOGFILE_H
  #define _LOGFILE_H
  #include <assert.h>
  #include <time.h>
  #include <stdio.h>
  #include <windows.h>
  class LogFile
  {
  protected:
  CRITICAL_SECTION _csLock;
  char * _szFileName;
  HANDLE _hFile;
  bool OpenFile()//打开文件, 指针到文件尾
  {
   if(IsOpen())
   return true;
   if(!_szFileName)
   return false;
   _hFile = CreateFile(
   _szFileName, 
   GENERIC_WRITE,
   FILE_SHARE_READ | FILE_SHARE_WRITE,
   NULL,
   OPEN_EXISTING,
   FILE_ATTRIBUTE_NORMAL,
   NULL 
   );
   if(!IsOpen() && GetLastError() == 2)//打开不成功, 且因为文件不存在, 创建文件
   _hFile = CreateFile(
   _szFileName, 
   GENERIC_WRITE,
   FILE_SHARE_READ | FILE_SHARE_WRITE,
   NULL,
   OPEN_ALWAYS,
   FILE_ATTRIBUTE_NORMAL,
   NULL 
   ); 
   if(IsOpen())
   SetFilePointer(_hFile, 0, NULL, FILE_END);
   return IsOpen();
  }
  DWORD Write(LPCVOID lpBuffer, DWORD dwLength)
  {
   DWORD dwWriteLength = 0;
   if(IsOpen())
   WriteFile(_hFile, lpBuffer, dwLength, &dwWriteLength, NULL);
   return dwWriteLength;
  }
  virtual void WriteLog( LPCVOID lpBuffer, DWORD dwLength)//写日志, 可以扩展修改
  {
   time_t now;
   char temp[21];
   DWORD dwWriteLength;
   if(IsOpen())
   {
   time(&now);
   strftime(temp, 20, "%Y-%m-%d %H:%M:%S", localtime(&now));
   WriteFile(_hFile, "\xd\xa#-----------------------------", 32, &dwWriteLength, NULL);
   WriteFile(_hFile, temp, 19, &dwWriteLength, NULL);
   WriteFile(_hFile, "-----------------------------#\xd\xa", 32, &dwWriteLength, NULL);
   WriteFile(_hFile, lpBuffer, dwLength, &dwWriteLength, NULL);
   WriteFile(_hFile, "\xd\xa", 2, &dwWriteLength, NULL);
   
   FlushFileBuffers(_hFile);
   }
  }
  void Lock() { ::EnterCriticalSection(&_csLock); }
  void Unlock() { ::LeaveCriticalSection(&_csLock); }
  public:
   
  LogFile(const char *szFileName = "Log.log")//设定日志文件名
  {
   _szFileName = NULL;
   _hFile = INVALID_HANDLE_VALUE;
   ::InitializeCriticalSection(&_csLock);
   SetFileName(szFileName);
  }
  virtual ~LogFile()
  {
   ::DeleteCriticalSection(&_csLock);
   Close();
   if(_szFileName)
   delete []_szFileName;
  }
  const char * GetFileName()
  {
   return _szFileName;
  }
  void SetFileName(const char *szName)//修改文件名, 同时关闭上一个日志文件
  {
   assert(szName);
   if(_szFileName)
   delete []_szFileName;
   Close();
   _szFileName = new char[strlen(szName) + 1];
   assert(_szFileName);
   strcpy(_szFileName, szName);
  }
  bool IsOpen()
  {
   return _hFile != INVALID_HANDLE_VALUE;
  }
  void Close()
  {
   if(IsOpen())
   {
   CloseHandle(_hFile);
   _hFile = INVALID_HANDLE_VALUE;
   }
  }
  void Log(LPCVOID lpBuffer, DWORD dwLength)//追加日志内容
  {
   assert(lpBuffer);
   __try
   {
   Lock();
   if(!OpenFile())
   return;
   WriteLog(lpBuffer, dwLength);
   }
   __finally
   {
   Unlock();
   } 
  }
  void Log(const char *szText)
  {
   Log(szText, strlen(szText));
  }
  private://屏蔽函数
  LogFile(const LogFile&);
  LogFile&operator = (const LogFile&);
  };
  class LogFileEx : public LogFile
  {
  protected:
  char *_szPath;
  char _szLastDate[9];
  int _iType;
  void SetPath(const char *szPath)
  {
   assert(szPath);
   WIN32_FIND_DATA wfd;
   char temp[MAX_PATH + 1] = {0};
   if(FindFirstFile(szPath, &wfd) == INVALID_HANDLE_VALUE && CreateDirectory(szPath, NULL) == 0)
   {
   strcat(strcpy(temp, szPath), " Create Fail. Exit Now! Error ID :");
   ltoa(GetLastError(), temp + strlen(temp), 10);
   MessageBox(NULL, temp, "Class LogFileEx", MB_OK);
   exit(1);
   }
   else
   {
   GetFullPathName(szPath, MAX_PATH, temp, NULL);
   _szPath = new char[strlen(temp) + 1];
   assert(_szPath);
   strcpy(_szPath, temp);
   }
  }
  public:
  enum LOG_TYPE{YEAR = 0, MONTH = 1, DAY = 2};
  LogFileEx(const char *szPath = ".", LOG_TYPE iType = MONTH)
  {
   _szPath = NULL;
   SetPath(szPath);
   _iType = iType;
   memset(_szLastDate, 0, 9);
  }
  ~LogFileEx()
  {
   if(_szPath)
   delete []_szPath;
  }
  const char * GetPath()
  {
   return _szPath;
  }
  void Log(LPCVOID lpBuffer, DWORD dwLength)
  {
   assert(lpBuffer);
   char temp[10];
   static const char format[3][10] = {"%Y", "%Y-%m", "%Y%m%d"};
   
   __try
   {
   Lock();
   
   time_t now = time(NULL);
   strftime(temp, 9, format[_iType], localtime(&now));
   if(strcmp(_szLastDate, temp) != 0)//更换文件名
   {
   strcat(strcpy(_szFileName, _szPath), "\\");
   strcat(strcat(_szFileName, temp), ".log");
   strcpy(_szLastDate, temp);
   Close();
   }
   if(!OpenFile())
   return;
   
   WriteLog(lpBuffer, dwLength);
   }
   __finally
   {
   Unlock();
   }
  }
  void Log(const char *szText)
  {
   Log(szText, strlen(szText));
  }
  private://屏蔽函数
  LogFileEx(const LogFileEx&);
  LogFileEx&operator = (const LogFileEx&);
  };
  #endif(王朝网络 wangchao.net.cn)

posted on 2012-05-16 17:18  wxl  阅读(735)  评论(0编辑  收藏  举报

导航