FileLogHandler.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:5k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include <ndb_global.h>
  14. #include <FileLogHandler.hpp>
  15. #include <File.hpp>
  16. //
  17. // PUBLIC
  18. //
  19. FileLogHandler::FileLogHandler() : 
  20.   LogHandler(),
  21.   m_maxNoFiles(MAX_NO_FILES), 
  22.   m_maxFileSize(MAX_FILE_SIZE),
  23.   m_maxLogEntries(MAX_LOG_ENTRIES)
  24. {
  25.   m_pLogFile = new File_class("logger.log", "a+");
  26. }
  27. FileLogHandler::FileLogHandler(const char* aFileName, 
  28.        int maxNoFiles, 
  29.        long maxFileSize,
  30.        unsigned int maxLogEntries) : 
  31.   LogHandler(),
  32.   m_maxNoFiles(maxNoFiles), 
  33.   m_maxFileSize(maxFileSize),
  34.   m_maxLogEntries(maxLogEntries)
  35. {
  36.   m_pLogFile = new File_class(aFileName, "a+");
  37. }
  38. FileLogHandler::~FileLogHandler()
  39. {
  40.   delete m_pLogFile;
  41. }
  42. bool
  43. FileLogHandler::open()
  44. {
  45.   bool rc = true;
  46.   if (m_pLogFile->open())
  47.   {
  48.     if (isTimeForNewFile())
  49.     {
  50.       if (!createNewFile())
  51.       {
  52. setErrorCode(errno);
  53. rc = false; 
  54.       }
  55.     }
  56.   }
  57.   else
  58.   {
  59.     setErrorCode(errno);
  60.     rc = false;
  61.   }
  62.   return rc;
  63. }
  64. bool
  65. FileLogHandler::close()
  66. {
  67.   bool rc = true;
  68.   if (!m_pLogFile->close())
  69.   {
  70.     setErrorCode(errno);
  71.     rc = false;
  72.   }
  73.   return rc;
  74. }
  75. void 
  76. FileLogHandler::writeHeader(const char* pCategory, Logger::LoggerLevel level)
  77. {
  78.   char str[LogHandler::MAX_HEADER_LENGTH];
  79.   m_pLogFile->writeChar(getDefaultHeader(str, pCategory, level));
  80. }
  81. void 
  82. FileLogHandler::writeMessage(const char* pMsg)
  83. {
  84.   m_pLogFile->writeChar(pMsg);
  85. }
  86. void 
  87. FileLogHandler::writeFooter()
  88. {
  89.   static int callCount = 0;
  90.   m_pLogFile->writeChar(getDefaultFooter());
  91.   /**
  92.    * The reason I also check the number of log entries instead of
  93.    * only the log size, is that I do not want to check the file size
  94.    * after each log entry which requires system calls and is quite slow.
  95.    * TODO: Any better way?
  96.    */
  97.   if (callCount % m_maxLogEntries != 0) // Check every m_maxLogEntries
  98.   {
  99.     if (isTimeForNewFile())
  100.     {
  101.       if (!createNewFile())
  102.       {
  103. // Baby one more time...
  104. createNewFile();
  105.       }
  106.     }
  107.     callCount = 0;
  108.   }
  109.   callCount++;
  110.   // Needed on Cello since writes to the flash disk does not happen until 
  111.   // we flush and fsync.
  112.   m_pLogFile->flush();
  113. }
  114. //
  115. // PRIVATE
  116. //
  117. bool 
  118. FileLogHandler::isTimeForNewFile()
  119. {
  120.   return (m_pLogFile->size() >= m_maxFileSize); 
  121. }
  122. bool
  123. FileLogHandler::createNewFile()
  124. {
  125.   bool rc = true;
  126.   int fileNo = 1;
  127.   char newName[PATH_MAX];
  128.   do
  129.   {
  130.     if (fileNo >= m_maxNoFiles)
  131.     {
  132.       fileNo = 1;
  133.       BaseString::snprintf(newName, sizeof(newName),
  134.  "%s.%d", m_pLogFile->getName(), fileNo);
  135.       break;
  136.     }
  137.     BaseString::snprintf(newName, sizeof(newName),
  138.        "%s.%d", m_pLogFile->getName(), fileNo++); 
  139.     
  140.   } while (File_class::exists(newName));
  141.   
  142.   m_pLogFile->close();
  143.   if (!File_class::rename(m_pLogFile->getName(), newName))
  144.   {
  145.     setErrorCode(errno);
  146.     rc = false;
  147.   }
  148.   // Open again
  149.   if (!m_pLogFile->open())
  150.   {
  151.     setErrorCode(errno);
  152.     rc = false;
  153.   }
  154.   
  155.   return rc;
  156. }
  157. bool
  158. FileLogHandler::setParam(const BaseString &param, const BaseString &value){
  159.   if(param == "filename")
  160.     return setFilename(value);
  161.   if(param == "maxsize")
  162.     return setMaxSize(value);
  163.   if(param == "maxfiles")
  164.     return setMaxFiles(value);
  165.   return false;
  166. }
  167. bool
  168. FileLogHandler::setFilename(const BaseString &filename) {
  169.   close();
  170.   if(m_pLogFile)
  171.     delete m_pLogFile;
  172.   m_pLogFile = new File_class(filename.c_str(), "a+");
  173.   open();
  174.   return true;
  175. }
  176. bool
  177. FileLogHandler::setMaxSize(const BaseString &size) {
  178.   char *end;
  179.   long val = strtol(size.c_str(), &end, 0); /* XXX */
  180.   if(size.c_str() == end)
  181.     return false;
  182.   if(end[0] == 'M')
  183.     val *= 1024*1024;
  184.   if(end[0] == 'k')
  185.     val *= 1024;
  186.   m_maxFileSize = val;
  187.   return true;
  188. }
  189. bool
  190. FileLogHandler::setMaxFiles(const BaseString &files) {
  191.   char *end;
  192.   long val = strtol(files.c_str(), &end, 0);
  193.   if(files.c_str() == end)
  194.     return false;
  195.   m_maxNoFiles = val;
  196.   return true;
  197. }
  198. bool
  199. FileLogHandler::checkParams() {
  200.   if(m_pLogFile == NULL)
  201.     return false;
  202.   return true;
  203. }