利用Asio搭建日誌系統

  Asio(http://think-async.com)官方示例中給出了一個比較初步的日誌服務,主要代碼在basic_logger.hpplogger_service.hpplogger_service.cpp這3個文件。稍做改進(好比建立單獨目錄存放Log文件、格式化Log文件名以及每一行日誌、定時建立新的日誌文件)就能夠搭建起一個可用的日誌系統。html

  新增一個logger類繼承自basic_logger<logger_service>,在logger中建立定時器和定時事件,每隔規定時間發出請求從新生成一個日誌文件。async

  對basic_logger類中的use_file方法稍做修改,在此方法中建立存放Log文件的目錄,並響應生成新Log文件的請求,Log文件能夠利用生成時間命名以便進行區分。函數

  //basic_logger.hpp
  void use_file(const std::string& file)
  {
// create new dir for log files // create new log file's name depends on time
... ... service_.use_file(impl_, file); }
void log(const std::string& message) { service_.log(impl_, message); }

  從basic_logger.hpp的代碼能夠看出,真正的IO操做,不管是Log文件的建立仍是Log記錄的寫入,都是在logger_service中進行的。寫入Log時,不妨加上時間前綴,以便從此的日誌分析。post

  //logger_service.hpp
  void use_file(impl_type& /*impl*/, const std::string& file)
  {
       work_io_service_.post(boost::bind(
          &logger_service::use_file_impl, this, file));
  }

  void log(impl_type& impl, const std::string& message)
  {
     // add time prefix
     std::ostringstream os;
     os << ... ... << ": " << message;

     work_io_service_.post(boost::bind(
          &logger_service::log_impl, this, os.str()));
   }

  void use_file_impl(const std::string& file)
  {
     ofstream_.close();
     ofstream_.clear();
     ofstream_.open(file.c_str());
   }

   void log_impl(const std::string& text)
   {
     ofstream_ << text << std::endl;
   }

  在logger_service中,use_file和log都調用post方法把回調放入內部io對象的事件隊列。use_file_impl負責建立新的Log文件,log_impl負責寫入Log文件,全部的回調函數在單線程內被調用,這樣即使它們共享ofstream_,也無需加鎖保護。性能

  在虛擬機測試一下性能,CentOS 6.五、單核、1G內存,寫入100萬條日誌需15秒。測試

相關文章
相關標籤/搜索