標籤:style blog http ar io color os sp for
Asio(http://think-async.com)官方樣本中給出了一個比較初步的Log Service,主要代碼在basic_logger.hpp、logger_service.hpp、logger_service.cpp這3個檔案。稍作改進(比如建立單獨目錄存放Log檔案、格式化Log檔案名稱以及每一行日誌、定時建立新的記錄檔)就可以搭建起一個可用的日誌系統。
新增一個logger類繼承自basic_logger<logger_service>,在logger中建立定時器和定時事件,每隔規定時間發出請求重建一個記錄檔。
對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時,不妨加上時間首碼,以便今後的日誌分析。
//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.5、單核、1G記憶體,寫入100萬條日誌需15秒。
利用Asio搭建日誌系統