Asio(http://think-async.com)官方示例中給出了一個比較初步的日誌服務,主要代碼在basic_logger.hpp、logger_service.hpp、logger_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秒。測試