learn_muduo

Logger

Logger有六个日志等级

  • TRACE
  • DEBUG
  • INFO
  • WARN
  • ERROR
  • FATAL

日志的输出语句是通过宏定义完成,编译期完成宏定义替换,创建Logger的临时对象。

#define LOG_TRACE if (muduo::Logger::logLevel() <= muduo::Logger::TRACE) \muduo::Logger(__FILE__, __LINE__, muduo::Logger::TRACE, __func__).stream()#define LOG_DEBUG if (muduo::Logger::logLevel() <= muduo::Logger::DEBUG) \muduo::Logger(__FILE__, __LINE__, muduo::Logger::DEBUG, __func__).stream()#define LOG_INFO if (muduo::Logger::logLevel() <= muduo::Logger::INFO) \muduo::Logger(__FILE__, __LINE__).stream()#define LOG_WARN muduo::Logger(__FILE__, __LINE__, muduo::Logger::WARN).stream()#define LOG_ERROR muduo::Logger(__FILE__, __LINE__, muduo::Logger::ERROR).stream()#define LOG_FATAL muduo::Logger(__FILE__, __LINE__, muduo::Logger::FATAL).stream()#define LOG_SYSERR muduo::Logger(__FILE__, __LINE__, false).stream()#define LOG_SYSFATAL muduo::Logger(__FILE__, __LINE__, true).stream()

Logger的构造函数

Logger::Logger(SourceFile file, int line): impl_(INFO, 0, file, line)
{}Logger::Logger(SourceFile file, int line, LogLevel level, const char* func): impl_(level, 0, file, line)
{impl_.stream_ << func << ' ';
}Logger::Logger(SourceFile file, int line, LogLevel level): impl_(level, 0, file, line)
{}Logger::Logger(SourceFile file, int line, bool toAbort): impl_(toAbort? FATAL:ERROR, errno, file, line)
{}

Impl类

Logger的构造函数中用到了Impl类,Impl类保存Logger的数据。

class Impl
{public:typedef Logger::LogLevel LogLevel;Impl(LogLevel level, int old_errno, const SourceFile& file, int line);void formatTime();void finish();Timestamp time_;LogStream stream_;LogLevel level_;int line_;SourceFile basename_;}; // class Impl

日志的时间,线程号,级别等在Impl构造函数初始化时完成,将这些信息写到LogStream对象中。

Logger::Impl::Impl(LogLevel level, int savedErrno, const SourceFile& file, int line): time_(Timestamp::now()),stream_(),level_(level),line_(line),basename_(file)
{formatTime();CurrentThread::tid();stream_ << T(CurrentThread::tidString(), CurrentThread::tidStringLength());stream_ << T(LogLevelName[level], 6);if (savedErrno != 0){stream_ << strerror_tl(savedErrno) << " (errno=" << savedErrno << ") ";}
}

Logger的析构

Logger是临时对象,因此Logger的析构接管日志的输出工作。

// 将msg输出到stdout
void defaultOutput(const char* msg, int len)
{size_t n = fwrite(msg, 1, len, stdout);
}Logger::OutputFunc g_output = defaultOutput;// 文件名和行号
void Logger::Impl::finish()
{stream_ << " - " << basename_ << ":" << line_ << "\n";
}Logger::~Logger()
{impl_.finish();const LogStream::Buffer& buf(stream().buffer());g_output(buf.data(), buf.length());if (impl_.level_ == FATAL) {g_flush();abort();}
}

LogStream

FixedBuffer

LogStream中维护一个FixedBuffer::Buffer的缓冲区,FixedBuffer提供了append()、data()、length()等一些字符串的基本操作。

template<int SIZE>
class FixedBuffer : noncopyable
{public:FixedBuffer(): cur_(data_){setCookie(cookieStart);}~FixedBuffer(){setCookie(cookieEnd);}void append(const char* buf, size_t len){if (implicit_cast<size_t>(avail()) > len){memcpy(cur_, buf, len);cur_ += len;}}const char* data() const {  return data_; }int length() const { return static_cast<int>(cur_ - data_); }// write to data_ directlychar* current() { return cur_; }int avail() { return static_cast<int>(end() - cur_); }void add(size_t len) { cur_ += len; }void reset() { cur_ = data_; }void bzero() { memZero(data_, sizeof(data_)); }// for used by GDBconst char* debugString();void setCookie(void (*cookie)()) { cookie_ = cookie; }// for used by unit teststring toString() const {return string(data_, length()); }StringPiece toStringPiece() const { return StringPiece(data_, length()); }private:const char* end() const { return data_ + sizeof data_; }// Must be outline function for cookies.static void cookieStart();static void cookieEnd();void (*cookie_)();char data_[SIZE];char* cur_;
}; // class fixedBuffer

LogStream

Logstream重载了各种 operator << 函数,用于处理多种类型的数据,将这些日志信息追加到Buffer中。

class LogStream : noncopyable
{typedef LogStream self;public:typedef detail::FixedBuffer<detail::kSmallBuffer> Buffer;/* 重载的operator<<函数,将日志信息存放在缓冲区中 */self& operator<<(const char* str){if (str){buffer_.append(str, strlen(str));}else{buffer_.append("(null)", 6);}return *this;}/* ... */private:Buffer buffer_;static const int kMaxNumericSize = 32;
};

muduo学习笔记 日志类相关推荐

  1. muduo学习笔记 线程类

    learn_muduo 线程属性 线程标识 pthreadId_,pid_t 线程函数 func_ 线程名字 name_ 线程序号 numCreated_ bool started_; // 线程状态 ...

  2. muduo学习笔记-Acceptor类

    Acceptor类一般由TCPServer创建,负责处理客户端发送的connect,它拥有一个acceptSocket_和acceptChannel_成员. 1.创建Acceptor : TcpSer ...

  3. muduo学习笔记:net部分之Http--HttpServer

    前面[muduo学习笔记:net部分之Http–HttpRequest.HttpResponse 和 HttpContext]介绍了TCP数据数据Buffer承载的HTTP报文的解析,本文结合TcpS ...

  4. ASM学习笔记2 - 类的创建和修改 —— ClassWriter的综合应用

    ASM学习笔记2 - 类的创建和修改 -- ClassWriter的综合应用 上回我们说到,通过使用ClassVisitor和ClassReader,我们能够分析已经存在的类.这一节中,我们将使用Cl ...

  5. Python学习笔记 (类与对象)

    Python学习笔记 (类与对象) 1.类与对象 面向对象编程语言类: 一个模板, (人类)-是一个抽象的, 没有实体的对象: (eg: 张三, 李四) 属性: (表示这类东西的特征, 眼睛, 嘴巴, ...

  6. Machine Learning A-Z学习笔记12-分类模型性能评级及选择

    Machine Learning A-Z学习笔记12-分类模型性能评级及选择 1.简单原理 一般认为假阴性比假阳性更严重,如核酸检测 用混淆矩阵表示如下图 准确率驳论(Accuracy Paradox ...

  7. JAVA学习笔记(类的学习)

    JAVA学习笔记(类的学习) 类声明和类体 构造方法和对象创建 对象的引用和实体 成员变量 方法 方法重载 关键字this 包 import语句 访问权限 对象数组 反编译和文档生成器 JAR文件 1 ...

  8. python面向对象编程72讲_2020-07-22 Python学习笔记27类和面向对象编程

    一些关于自己学习Python的经历的内容,遇到的问题和思考等,方便以后查询和复习. 声明:本人学习是在扇贝编程通过网络学习的,相关的知识.案例来源于扇贝编程.如果使用请说明来源. 第27关 类与面向对 ...

  9. muduo学习笔记:base部分之高性能日志库

    服务端编程,日志必不可少,生产环境中应做到"Log Everything All The Time". 一个日志库答题分为前端(Logging.{h,cc})和后端(LogFile ...

最新文章

  1. 2019牛客暑期多校训练营(第三场)
  2. matlab利用数据求公式,matlab新手,求帮助!主要是如何将数据和公式导入
  3. 华为手机权限开启方法8
  4. 莫慌!网络推广平台更新网站SEO优化中,被K降权怎么办?
  5. mpls标签分配原理——Vecloud
  6. 每天在竞争中淘汰自己
  7. Java 12正式发布,新特性解读!
  8. Jenkins+Gradle+Git自动打apk包,并上传到ftp
  9. AQS源码阅读笔记(一)
  10. 前端开发-认识前端开发-0226
  11. gtest linux 性能测试,Linux下Gtest的安装与使用
  12. 采购订单暂存和持有相关的问题?
  13. Python告诉你NBA球星都喜欢在哪个位置出手?
  14. 数据防泄密,代码类数据难在哪里?
  15. xposed模块编写教程_Xposed插件开发入门详解,
  16. Invalid bound statement (not found): shopping_whith_payment.pay.dataobject.PayInfoMapper.insertSelec
  17. 调整DOSBOX窗口大小并运行程序
  18. 烽火为格兰仕集团私人订制-销售管家iCube平台
  19. 用python(numpy)复现matlab代码
  20. zabbix——分布式监控系统

热门文章

  1. python_day6 shutil模块
  2. java多线程之Concurrent包
  3. 使用Volley StringRequest Get的方式进行发票查询操作
  4. HDU 2612 Find a way
  5. SQL Server 2008 阻止保存要求重新创建表的更改
  6. 【数据结构与算法】之深入解析“柱状图中最大的矩形”的求解思路与算法示例
  7. Python之值得学习练手的22个迷你程序(附代码)
  8. 95. Unique Binary Search Trees II 不同的二叉搜索树 II
  9. Curses 中的 noecho() 函数
  10. 阿里云服务器上安装java配置jdk