目录
前言
muduo中的日志,是诊断日志。用于将代码运行时的重要信息进行保存,方便故障诊断和追踪。
日志一般有两种,一种是同步日志,一种是异步日志,同步日志就是当需要写出一条日志信息的时候,只有等到这条日志消息完全写出之后才能执行后续的程序,可见,这种方式的日志的问题就在于程序可能会阻塞在磁盘写入操作上;
而另一种异步日志则不会,异步日志的思路是需要写日志消息的时候只是将日志消息进行存储,当积累到一定量或者到达一定时间间隔时,由后台线程自动将存储的所有日志进行输出,可见,对于异步日志来说,每次有日志消息产生的时候,只需要一个存储的行为即可,存储结束就可以执行后面的业务代码了,而真正写入到磁盘的操作,是由后台线程进行的,这样做的好处就是:前台线程不会阻塞在写日志上,后台线程真正写出日志时,日志消息往往已经积累了很多,此时只需要调用一次IO函数,如fwrite,而不需要每条消息都调用一个IO函数,如此减少了IO函数调用次数,提高了效率。
而muduo中实现的,就是异步日志。
muduo中的日志消息格式为:时间 线程id 日志级别 日志正文 源文件名及行号。
日志设置了6种级别:TRACE、DEBUG、INFO、WARN、ERROR和FATAL。
日志的输出形式为流形式:日志级别<<message; 如 LOG_ERROR<<"file cannot open!";
如上所述,异步日志的实现关键,是先将日志消息进行存储,然后由后台线程进行写出。muduo将“日志存储”和“日志输出”分为了两大块,现在先来看看日志的存储部分。
日志存储的实现
前面说过,日志的输出形式为流形式,但muduo并没有使用C++自带的iostream等流库,而是使用自己实现的LogStream,用简短的代码量实现需要的功能,抛去其它不需要的冗杂的功能,使得代码效率更高。
实现”日志流“的基础,还需要一个内置的缓冲区,muduo通过FixedBuffer类来实现,如下所示:
/*LogStream.h*/
template<int SIZE>//构造时需要指定缓冲区大小
class FixedBuffer : noncopyable
{
public:
FixedBuffer()
: cur_(data_)
{
setCookie(cookieStart);
}
~FixedBuffer()
{
setCookie(cookieEnd);
}
void append(const cha