muduo学习笔记 日志类
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学习笔记 日志类相关推荐
- muduo学习笔记 线程类
learn_muduo 线程属性 线程标识 pthreadId_,pid_t 线程函数 func_ 线程名字 name_ 线程序号 numCreated_ bool started_; // 线程状态 ...
- muduo学习笔记-Acceptor类
Acceptor类一般由TCPServer创建,负责处理客户端发送的connect,它拥有一个acceptSocket_和acceptChannel_成员. 1.创建Acceptor : TcpSer ...
- muduo学习笔记:net部分之Http--HttpServer
前面[muduo学习笔记:net部分之Http–HttpRequest.HttpResponse 和 HttpContext]介绍了TCP数据数据Buffer承载的HTTP报文的解析,本文结合TcpS ...
- ASM学习笔记2 - 类的创建和修改 —— ClassWriter的综合应用
ASM学习笔记2 - 类的创建和修改 -- ClassWriter的综合应用 上回我们说到,通过使用ClassVisitor和ClassReader,我们能够分析已经存在的类.这一节中,我们将使用Cl ...
- Python学习笔记 (类与对象)
Python学习笔记 (类与对象) 1.类与对象 面向对象编程语言类: 一个模板, (人类)-是一个抽象的, 没有实体的对象: (eg: 张三, 李四) 属性: (表示这类东西的特征, 眼睛, 嘴巴, ...
- Machine Learning A-Z学习笔记12-分类模型性能评级及选择
Machine Learning A-Z学习笔记12-分类模型性能评级及选择 1.简单原理 一般认为假阴性比假阳性更严重,如核酸检测 用混淆矩阵表示如下图 准确率驳论(Accuracy Paradox ...
- JAVA学习笔记(类的学习)
JAVA学习笔记(类的学习) 类声明和类体 构造方法和对象创建 对象的引用和实体 成员变量 方法 方法重载 关键字this 包 import语句 访问权限 对象数组 反编译和文档生成器 JAR文件 1 ...
- python面向对象编程72讲_2020-07-22 Python学习笔记27类和面向对象编程
一些关于自己学习Python的经历的内容,遇到的问题和思考等,方便以后查询和复习. 声明:本人学习是在扇贝编程通过网络学习的,相关的知识.案例来源于扇贝编程.如果使用请说明来源. 第27关 类与面向对 ...
- muduo学习笔记:base部分之高性能日志库
服务端编程,日志必不可少,生产环境中应做到"Log Everything All The Time". 一个日志库答题分为前端(Logging.{h,cc})和后端(LogFile ...
最新文章
- 2019牛客暑期多校训练营(第三场)
- matlab利用数据求公式,matlab新手,求帮助!主要是如何将数据和公式导入
- 华为手机权限开启方法8
- 莫慌!网络推广平台更新网站SEO优化中,被K降权怎么办?
- mpls标签分配原理——Vecloud
- 每天在竞争中淘汰自己
- Java 12正式发布,新特性解读!
- Jenkins+Gradle+Git自动打apk包,并上传到ftp
- AQS源码阅读笔记(一)
- 前端开发-认识前端开发-0226
- gtest linux 性能测试,Linux下Gtest的安装与使用
- 采购订单暂存和持有相关的问题?
- Python告诉你NBA球星都喜欢在哪个位置出手?
- 数据防泄密,代码类数据难在哪里?
- xposed模块编写教程_Xposed插件开发入门详解,
- Invalid bound statement (not found): shopping_whith_payment.pay.dataobject.PayInfoMapper.insertSelec
- 调整DOSBOX窗口大小并运行程序
- 烽火为格兰仕集团私人订制-销售管家iCube平台
- 用python(numpy)复现matlab代码
- zabbix——分布式监控系统
热门文章
- python_day6 shutil模块
- java多线程之Concurrent包
- 使用Volley StringRequest Get的方式进行发票查询操作
- HDU 2612 Find a way
- SQL Server 2008 阻止保存要求重新创建表的更改
- 【数据结构与算法】之深入解析“柱状图中最大的矩形”的求解思路与算法示例
- Python之值得学习练手的22个迷你程序(附代码)
- 95. Unique Binary Search Trees II 不同的二叉搜索树 II
- Curses 中的 noecho() 函数
- 阿里云服务器上安装java配置jdk