ceph日志代码分析
1 类结构
image.png2 流程
-
Log在CephContext构造函数里面进行构造
-
Log::m_subsys由配置构建,Option::subsys>=0来控制是否是日志系统的等级设置。等级设置越高,小于等于该等级的日志都需要打印,打印就越详细。
-
Log 启动线程来刷脏:
3.1. 交换m_new和m_flush, 通过右值引用来减少拷贝
3.2. 刷到graylog:graylog是一个集中日志系统,可以通过配置log_to_graylog、err_to_graylog、log_graylog_host、log_graylog_host来控制
3.3. 提交日志到EntryRing m_recent:
a) 是一个循环buffer,最大数量为10000,写死的; 没有日志等级限制;
b) 通过命令来(
ceph daemon osd.4 log dump
)触发dump,先把已有的日志buffer输出,再开始m_recent的日志,输出完还需要写回作为最近的日志c) dump到日志文件,可以通过 "--- begin dump of recent events ---"来定位
d) 日志的等级<=m_stderr_crash(默认是-1, 由配置err_to_stderr以及log_to_stderr控制,具体参考以下截图)会输出到终端,前提是要小于该子系统的日志等级
image.pnge) core的时候也会触发,参考assert.cc -> dump_recent()
f) 杀进程的时候也应该会触发,参考handle_fatal_signal()
3 用户如何使用:
a) 流程:dout(v)->ldout(cct,v)->dout_impl(cct, dout_subsys,v) dout_prefix --> submit_entry()
b) ldout中引用dout_context需要cpp/cc文件中定义
c) dout_subsys也需要在cpp/cc文件中定义
d) dout_prefix可以在cpp/cc重定义, 输出自己的头标志
e) derr 同dout,不需要参数,因为err等级为-1
4 总结
1) 日志本来是可以直接输出到文件,但是io较耗时,所以输出到缓存中,通过交换buffer(右值拷贝)来避免io影响业务逻辑,单独起一个线程不断的刷日志到文件。
2) 同时也可以输出dump_recent来看详细日志, 这个是没有日志级别限制的,平时一般用不到,排查问题的可以输出。
3) 通过subsysmap来控制日志的级别。
4) 提交日志的时候,队列数量超过了m_max_new就会等待flush,通过条件变量实现,m_max_new通过配置log_max_new来控制,默认是1000.