SRS的日志文件模块SrsFileLog—SRS源码分析
作者:罗上文,微信:Loken1,公众号:FFmpeg弦外之音
关于 SRS 日志的基本介绍以及 切割等功能,请阅读 SRS 官方文档《日志》与《日志切割》。本文主要讲解 SRS 日志模块的代码实现。
SRS 日志模块的实现类是 SrsFileLog
,如下:
class SrsFileLog : public ISrsLog, public ISrsReloadHandler
{
private:
// Defined in SrsLogLevel.
SrsLogLevel level_;
private:
char* log_data;
...省略...
可以看到,SrsFileLog
继承了 两个接口(Interface
),ISrsLog
与 ISrsReloadHandler
。ISrsLog
接口比较简单,这里就不说了。
我们重点讲一下 ISrsReloadHandler
这个接口,SrsFileLog
为什么要继承 ISrsReloadHandler
,如果不继承会有什么问题?
我们直接把继承删掉,看看编译会不会报错,如下:
我们 make
编译一下,会报以下错误。
通过这种方式,我们排查到了 SrsFileLog
使用到 ISrsReloadHandler
的地方。
我估计他的用法与逻辑是这样的,SrsFileLog
里面有一些日志文件存储路径,存储方式等配置,这些配置可以通过 reload
srs.conf
文件来重新加载的。SRS 重新加载配置文件的命令如下:
./etc/init.d/srs reload
那 srs.conf
的配置怎么修改到 SrsFileLog
里面呢?答:通过 subscribe
接口,SrsConfig
模块提供了一个 subscribe
函数来注册外部的模块,如下:
subscribes
变量是一个 vector
来的。
// The reload subscribers, when reload, callback all handlers.
std::vector<ISrsReloadHandler*> subscribes;
然后他在哪里使用这个 vector 呢?
答:在 do_reload_listen()
、do_reload_max_connections()
等函数里面如下:
这个配置 reload
的整体逻辑是这样的,会有一个协程 SrsSignalManager::cycle()
在阻塞不断读取信号事件,当产生了 reload
信号,就会调 server->on_signal()
来处理信号。经过多层函数调用之后,最后会遍历每一个 订阅者(subscriber)来执行各种 reload 方法。
但是我测试下来,虽然 SrsFileLog
继承了 ISrsReloadHandler
,但是他并没有实现接口里的任何一个方法,我测试了一下修改 srs.conf
的 srs_log_level
配置,如下:
srs_log_level info
修改为
srs_log_level error
然后执行 ./etc/init.d/srs reload
,发现这个 srs_log_level
的修改并没有生效,还是 SrsLogLevelInfo
。如下:
提示:_srs_log
是一个全局变量。
所以如果你想 日志相关的配置 能支持 reload
,需要自己往 ISrsReloadHandler
加函数,然后在 SrsFileLog
里实现它。
SrsFileLog
类里面的其他方法相对来说比较简单,读者执行阅读源码就行,他的注释也非常全。