一、使用printf函数
这是最基础的日志输出方式,使用printf、cout、cerr等函数,无需额外安装,适用于嵌入式裸机或快速调试场景。假设我们的程序叫server,要生成日志文件XXX.log,则可以执行:
./server > XXX.log 2>&1 &然后通过命令:
tail -f XXX.log或
tail -f XXX.log -n 200可以实时查看日志文件内容。
缺点:
1.类型不安全:格式符(如 %d、%s)与参数类型需手动匹配,错误可能导致崩溃或乱码。
2.无日志级别:无法区分 INFO/WARN/ERROR,需通过宏或条件编译手动控制。
3.线程不安全:多线程并发调用时输出会交错,需自行加锁。
4.功能单一:仅支持格式化输出,缺乏时间戳、文件名、滚动文件等生产需求。
二、使用systemctl
systemctl 是 Linux 系统管理服务的核心命令,用来启动、停止、重启服务以及设置开机自启,是 systemd 系统的主要管理工具。可以通过journalctl 工具来查看systemd服务的日志,具体可以参考:《Linux下使用systemctl启动服务失败》
三、使用日志库
比如使用spdlog库。相比 printf,spdlog 的优势主要不是“能打印文字”,而是提供完整的日志体系。
| 能力 | printf | spdlog |
| 日志级别 | 需要自行实现 | trace/debug/info/warn/error/critical |
| 运行时过滤 | 不支持 | 可动态调整级别 |
| 多线程 | 多次打印可能交错 | 多线程 logger 保证单条日志完整 |
| 时间、线程信息 | 手动拼接 | 自动格式化 |
| 文件和控制台 | 手动处理 | 支持多个 sink |
| 日志轮转 | 需要 logrotate或自研 | 支持按大小、日期轮转 |
| 异步写入 | 需要自研队列 | 内置异步模式 |
| 格式安全 | %d/%s 写错可能出问题 | 基于 fmt 的类型安全格式化 |
| flush 策略 | 手动 fflush | 可按级别或周期 flush |
| 模块管理 | 需要自行约定 | 可为 Routing、Conmon 等创建独立 logger |
例如:
printf("device=%s error=%d\n", name.c_str(), errorCode);
可以改为:
spdlog::error("device={} error={}", name, errorCode);
spdlog库的主要优势包括:
1.控制日志量
生产环境使用:INFO,排查关键问题时临时开启:DEBUG,无需删除或注释大量打印代码。
2.多线程日志更清楚
多个 printf 可能互相穿插,spdlog 可以把一条日志完整输出。
3.统一格式
比如:2026-08-04 10:15:32.123 ERROR [routing] [thread 1832] device=speaker1 code=-805
时间、级别、模块和线程 ID 不再由每个函数自行拼接。
4.减少业务线程阻塞
高频日志可以使用异步 logger,让后台线程负责输出。不过错误和崩溃前日志需要合理设置 flush 和队列溢出策略。更容易管理敏感信息。
四、日志使用技巧
1.日志可以设置为按200MB、14个历史文件轮转压缩,仅root可读,防止日志无限增长占满磁盘。每个日志文件每天检查一次,日志达到约200MB时进行轮转,当前日志改名保存,并创建新的日志文件继续记录,最多保留14份历史日志。较旧的历史日志压缩为.gz文件。超过14份后,最旧的一份会被自动删除。
2.一个服务器可以同时生成多份日志。比如,假设业务服务器名称为localserver,负责和流媒体服务器ZLMediaKit通讯,以及接收java端的控制指令,启动推流,控制设备等。则localserver可以同时生成三份日志:
/var/log/localserver/longrun-debug.log
/var/log/localserver/zlmediakit-longrun.log
/var/log/localserver/health.log
三份日志分别对应不同层次。
其中:/var/log/localserver/longrun-debug.log为localserver的应用日志,记录指令收发和publish/FFmpeg推流过程。
/var/log/localserver/zlmediakit-longrun.log为ZLMediaKit媒体服务日志,记录流注册/注销、RTSP 推流、WebRTC/HLS 播放、播放器连接、DTLS 握手和媒体会话断开等,用于判断“流已经推送成功,但网页播放失败”的媒体服务或播放端问题。
/var/log/localserver/health.log为每分钟一次的系统健康快照,记录localserver和ZLMediaKit的进程状态、CPU、内存、线程数、文件描述符、连接数及重启次数。用于判断长时间运行后是否出现资源泄漏、连接堆积或进程重启。
这样当发生推流失败等问题时,我们可以按照顺序进行排查:
在longrun-debug.log确认localserver是否成功建立并持续推流;
在zlmediakit-longrun.log确认流是否注册,以及网页播放器是否成功连接;
在health.log检查故障发生前后是否存在资源异常或服务重启。
3.如果是为了排查长时间运行崩溃的问题,则可以加入core dump、退出码记录和自动拉起脚本,再重启复现,以获取准确崩溃栈后修复。此时推荐使用追加方式写日志:
... >> /root/Test/gst-test/player.log 2>&1这样做的优点是不会清空旧日志。可以保留之前崩溃前后的现场。