3、slog2info高级应用:slog2info与sloginfo区别、二进制日志解析、日志回放、性能分析

好,咱们接着聊。前面几章我们把 slog2info 的基本用法过了一遍,现在该上点硬菜了。这一章我打算重点讲讲 slog2info 的几个高级玩法,包括它和老牌工具 sloginfo 到底差在哪、怎么解析二进制日志、如何做日志回放,以及怎么用这些工具做性能分析。

说实话,我在 QNX 项目上摸爬滚打这么多年,slog2info 是我用得最顺手的工具之一。它不光是看日志那么简单,用好了,能帮你省下大把调试时间。

3.1 slog2info 与 sloginfo 的区别

很多刚接触 QNX 的朋友会问:既然有了 sloginfo,为什么还要搞个 slog2info?这两个工具到底有啥区别?

嗯,这个问题问得好。我简单梳理一下:

对比项 sloginfo slog2info
日志格式 文本格式 二进制格式(更高效)
性能开销 较高,字符串格式化耗时 低,直接写二进制缓冲区
过滤能力 有限,基本靠 grep 强大,支持多维度过滤
时间戳精度 毫秒级 微秒级
日志回放 不支持 支持(-r 选项)
多线程安全 一般 优秀

说白了,slog2info 就是 sloginfo 的升级版。我记得早期做某个车载项目时,系统里跑着几十个进程,日志量特别大。用 sloginfo 抓日志,CPU 占用率直接飙到 30% 以上,严重影响实时性。换成 slog2info 后,这个问题就解决了。

核心区别一句话总结:slog2info 采用二进制日志格式,写入时几乎零开销,读取时按需解析。而 sloginfo 是文本格式,写入时就要做字符串格式化,性能差了一个数量级。

3.2 二进制日志解析

二进制日志,说白了就是把日志数据以结构化的二进制形式存起来。你想想看,如果每条日志都要转成字符串再写进去,那得多慢?

slog2info 的二进制日志格式大致长这样:

struct slog2_buffer {
    uint32_t    magic;          // 魔数,用于校验
    uint32_t    version;        // 版本号
    uint64_t    timestamp;      // 时间戳(微秒)
    uint16_t    pid;            // 进程ID
    uint16_t    tid;            // 线程ID
    uint8_t     severity;       // 严重级别
    uint8_t     verbosity;      // 详细级别
    uint16_t    msg_len;        // 消息长度
    char        msg[0];         // 变长消息
};

解析的时候,slog2info 会按这个结构体逐个字段读取。我习惯用 -b 选项来查看原始二进制内容:

# 查看原始二进制日志
slog2info -b /var/log/slog2/slog2.0

# 输出示例(十六进制)
00000000: 534c 4f47 0001 0000 5a3b 8c2e 0000 0000  SLOG....Z;......
00000010: 01f4 01f4 0302 0014 0000 0048 656c 6c6f  ...........Hello

为什么要懂这个?因为有时候日志文件损坏了,或者你想写个脚本做自动化分析,就得直接操作二进制数据。我在一个工控项目里就遇到过这种情况——日志文件被意外截断,slog2info 读不出来,最后我写了个小工具按结构体硬解析,才把关键信息抢救回来。

小技巧:如果你需要批量解析二进制日志,可以用 slog2info -o raw 输出原始格式,然后配合 awk 或 Python 做二次处理。我个人更推荐 Python 的 struct 模块,解析效率很高。

3.3 日志回放

日志回放这个功能,说实话,我第一次用的时候觉得挺惊艳的。它能让你像看录像一样,把系统过去发生的事件按时间顺序重放一遍。

用法很简单:

# 实时回放日志
slog2info -r

# 指定回放速度(2倍速)
slog2info -r -s 2

# 从指定时间点开始回放
slog2info -r -t "2024-01-15 10:30:00"

回放模式下,slog2info 会按照日志原始的时间戳顺序输出,每条日志之间会保持实际的时间间隔。你想想看,这在调试时序相关的问题时有多好用。

我曾经遇到过一个诡异的死锁问题,系统跑着跑着就卡死了,但看静态日志又看不出端倪。后来我用 slog2info -r 以 0.5 倍速回放,终于发现是某个中断处理函数里调用了 printf,导致日志系统自己把自己锁住了。嗯,这种问题,不看回放还真难定位。

注意:回放功能依赖日志文件中的时间戳。如果系统时间在运行过程中被修改过(比如 NTP 同步),回放出来的顺序可能会乱。我建议在生产环境中启用 PPS 或使用单调时钟来记录时间戳。

3.4 性能分析

slog2info 在性能分析方面,其实是个被低估的工具。很多人只知道用它看日志,却不知道它还能帮你做性能诊断。

我常用的几个性能分析场景:

  • 日志写入延迟分析:-v 选项查看每条日志的写入耗时
  • 日志频率统计:-c 选项统计每个进程/线程的日志输出频率
  • 日志大小监控:-S 选项查看日志缓冲区使用情况

举个例子,你想知道哪个进程最"话痨":

# 统计各进程日志条数
slog2info -c | sort -rn | head -10

# 输出示例
  5432  io-pkt
  3210  devb-sdmmc
  2100  screen
  1890  pci-server

看到 io-pkt 占了将近一半的日志量,你就该想想了——是不是网络驱动层有什么异常在疯狂打日志?

再比如,你想分析日志写入的延迟分布:

# 查看日志写入延迟(微秒)
slog2info -v | awk '{print $NF}' | sort -n | uniq -c

# 输出示例
  100  1-10
  50   11-100
  5    101-1000
  1    1001+

如果发现有大量日志写入延迟超过 100 微秒,那就要检查一下存储子系统是不是有瓶颈了。我在一个存储项目中就发现,日志写入延迟突然飙升到毫秒级,最后定位到是 SD 卡进入了垃圾回收状态。

性能分析要点:

  • 日志写入延迟 < 10μs:正常
  • 日志写入延迟 10-100μs:需要关注
  • 日志写入延迟 > 100μs:必须优化

好了,这一章的内容就这些。slog2info 的高级功能其实还有很多,比如远程日志收集、日志加密传输等,但那些属于更进阶的内容,咱们后面再聊。下一章我会讲讲怎么用 slog2info 配合其他工具做系统级调试,到时候见。