阅读源码要带有目的,一开始就是像搞清楚,到底别人是如何实现高效的异步日志系统的,其中异步消息队列是如何实现的,抱着这个目的一直找,最终找到了答案。 主要逻辑是放在AsyncAppender中,和FileAppender与ConsoleAppender不同的是,AsyncAppender是节点追加器,继承AppenderAttachable 可以追加像FileAppender和ConsoleAppender一样的叶子节点,AsyncAppender属于缓冲节点,通过生产者消费者实现缓冲,提高多线程执行效率
其中学到的知识点有,
condition_variable.wait()实际上做了4件事情
1阻塞当前线程
2解锁当前lock
3等待通知
4重新lock上锁,如果多个线程同事收到通知,同用一个互斥量枷锁时,也只有一个会接着执行
简单使用示例如下
LoggerPtr root = Logger::getRootLogger(); LayoutPtr layout = SimpleLayoutPtr(new log4cxx::SimpleLayout()); AsyncAppenderPtr asyncAppender = AsyncAppenderPtr(new AsyncAppender()); FileAppenderPtr fileAppender = FileAppenderPtr(new FileAppender()); fileAppender->setLayout(layout); fileAppender->setImmediateFlush(true); Pool p; fileAppender->setFile(LOG4CXX_STR("11.log")); fileAppender->setAppend(true); fileAppender->activateOptions(p); asyncAppender->setName(LOG4CXX_STR("async-test2")); asyncAppender->addAppender(fileAppender); root->addAppender(asyncAppender); root->debug("m1"); root->debug("m2");
调试中遇到的问题和解决思路
当用网上给的配置文件调用时,在测试文件写入的过程中发现,多线程执行的情况下,写文件居然在不同线程中执行,意味着并不支持多线程缓冲队列,差点放弃,不可能这么大的一个库不考虑异步问题,随后在漫无目的中阅读源码,发现,居然有AsyncAppender,但是在调试源码过程中发现,AsyncAppender和FileAppender始终无法同时配置,不知道配置文件改怎么写,后来再看测试用例时发现异步测试用例的用法中直接创建了rootlogger等对象调用,不用写配置文件,最终才测试成功,实现异步缓冲文件日志