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秒。测试