muduo库源码学习(base):Logfile

来源:互联网 发布:系统交互流程图软件 编辑:程序博客网 时间:2024/06/05 19:10

本文件使用的是C++17版本

#ifndef MUDUO_BASE_LOGFILE_H#define MUDUO_BASE_LOGFILE_H#include <muduo/base/Mutex.h>#include <muduo/base/Types.h>#include <memory>namespace muduo{namespace FileUtil{class AppendFile;}class LogFile : noncopyable//文件日志类{ public:  LogFile(const string& basename,          size_t rollSize,          bool threadSafe = true,          int flushInterval = 3,          int checkEveryN = 1024);  ~LogFile();  void append(const char* logline, int len);  void flush();  bool rollFile();//生成新日志文件 private:  void append_unlocked(const char* logline, int len);  //如果打算开辟新文件,根据basename和当前时间,得到意图创建的文件名字  static string getLogFileName(const string& basename, time_t* now);  const string basename_;  const size_t rollSize_;//日志文件的极限容量,超过后,将导致开辟新文件  const int flushInterval_;  const int checkEveryN_;  int count_;  std::unique_ptr<MutexLock> mutex_;  time_t startOfPeriod_;  time_t lastRoll_;//记录文件创建时间  time_t lastFlush_;//记录上次刷新时间  std::unique_ptr<FileUtil::AppendFile> file_;  const static int kRollPerSeconds_ = 60*60*24;//刷新时间};}#endif  // MUDUO_BASE_LOGFILE_H

#include <muduo/base/LogFile.h>#include <muduo/base/FileUtil.h>#include <muduo/base/ProcessInfo.h>#include <assert.h>#include <stdio.h>#include <time.h>using namespace muduo;LogFile::LogFile(const string& basename,                 size_t rollSize,                 bool threadSafe,                 int flushInterval,                 int checkEveryN)  : basename_(basename),    rollSize_(rollSize),    flushInterval_(flushInterval),    checkEveryN_(checkEveryN),    count_(0),    mutex_(threadSafe ? new MutexLock : NULL),//是否要求线程安全    startOfPeriod_(0),    lastRoll_(0),    lastFlush_(0){  assert(basename.find('/') == string::npos);//文件名里没有古怪的符号  rollFile();}LogFile::~LogFile(){}void LogFile::append(const char* logline, int len){  if (mutex_)//没有必要专写一个加锁版本  {    MutexLockGuard lock(*mutex_);    append_unlocked(logline, len);  }  else  {    append_unlocked(logline, len);  }}void LogFile::flush()//立刻写到文件{  if (mutex_)  {    MutexLockGuard lock(*mutex_);    file_->flush();  }  else  {    file_->flush();  }}void LogFile::append_unlocked(const char* logline, int len)//具体的追加函数{  file_->append(logline, len);//先写入  if (file_->writtenBytes() > rollSize_)//如果超出滚动临界大小,则滚动文件  {    rollFile();  }  else  {    ++count_;//追写次数    if (count_ >= checkEveryN_)//追写次数超过指定次数    {      count_ = 0;//清零。也就是说,追写次数和文件大小共同决定了日志滚动      time_t now = ::time(NULL);      time_t thisPeriod_ = now / kRollPerSeconds_ * kRollPerSeconds_;//time_t就是个long int,这里把天数的余数清除掉      if (thisPeriod_ != startOfPeriod_)//不是同一天      {        rollFile();//滚动日志文件      }      else if (now - lastFlush_ > flushInterval_)//达到刷新间隔      {        lastFlush_ = now;        file_->flush();//写文件      }    }  }}bool LogFile::rollFile()//尝试滚动文件,对时间再检查一次{  time_t now = 0;  string filename = getLogFileName(basename_, &now);//得到文件名和当前时间  time_t start = now / kRollPerSeconds_ * kRollPerSeconds_;//保存1970到现在经过的天数  if (now > lastRoll_)//这不应该有误  {    lastRoll_ = now;//滚动时间    lastFlush_ = now;//刷新时间    startOfPeriod_ = start;//创建时间(天)    file_.reset(new FileUtil::AppendFile(filename));//重新设置一个可追加的文件    return true;  }  return false;//不应该发生}string LogFile::getLogFileName(const string& basename, time_t* now){  string filename;  filename.reserve(basename.size() + 64);  filename = basename;  char timebuf[32];  struct tm tm;  *now = time(NULL);  gmtime_r(now, &tm); // FIXME: localtime_r ?  strftime(timebuf, sizeof timebuf, ".%Y%m%d-%H%M%S.", &tm);  filename += timebuf;//文件名+日期  filename += ProcessInfo::hostname();//再加上主机名  char pidbuf[32];  snprintf(pidbuf, sizeof pidbuf, ".%d", ProcessInfo::pid());  filename += pidbuf;//再加上线程id  filename += ".log";//尾缀  return filename;}


原创粉丝点击