AAA
社区对 格式化字符串的又一次尝试, /index/ 中呈现内核中的格式化字符串。
原文
By May 27, 2021,
当内核开发人员想要获取正在运行的内核的状态的信息时,倾向于使用 (),会产生一条日志(人类可读的)。然而,这些日志信息的消费者通常不是人类,而是自动监控系统。当日志信息格式不匹配时,监控系统通常会丢失重要信息。() patch set 是解决如上场景的最新的尝试。
管理员安装监控系统是为了及时感知系统出现问题。如果 “CPU on fire” ,而管理员恰好没有目睹这一事件,他们至少希望收到警报。为此,监控系统将监视内核日志中内核中相关代码打印的 “CPU on fire” 消息,如果一切顺利,消息会在 CPU melt 之前产生。
一个小补丁贡献者将消息改为 “CPU in ” ,生成的补丁由维护者正式合并,并在稳定的内核更新中发布。不幸的是,监控系统仍在监控旧的 “CPU on fire” 消息,完全忽略新格式的信息。
问题是:虽然通过 () 产生的消息被用户空间工具使用,但这些消息从未真正被认为是内核 ABI 的一部分,所以内核开发人员可以随时更改(或删除)它们。这给任何创建正则表达式以检测感兴趣日志的人带来了麻烦,还阻碍了将消息翻译成其他语言。
多年来,已经有许多尝试来解决这个问题。2011 年内核峰会围绕向每条内核消息添加 128 位二进制标签的提议展开了一场讨论,与之前和之后的所有其他想法一样,这个想法未能合入主线。内核社区从来不认为需要对 () 输出的日志信息强加任何结构。
Chris Down 发布的最新提案并未试图强加任何此类结构,只是收集内核中每个 () 格式字符串,并通过 呈现。具体来说, () 变成了一个宏:
struct pi_entry {
const char *fmt;
const char *func;
const char *file;
unsigned int line;
const char *level;
const char *pre_fmt;
const char *post_fmt;
};
此结构保存 () 使用的信息:格式化字符串、日志级别、所在源码位置以及添加的 “pre” 和 “post” 格式化数据(例如 ()函数)。这个结构存放在内核 (.) 中,新的 () 宏会调用原始的 ()(现在称为 ())来输出消息。
构建内核时,所有这些 结构都放在 . 中。挂载 后,可以查看 /index/ 文件,此文件包含内核整个格式化数据。在 /index 目录下,对于每个可加载模块也有相应的文件。监控系统可以使用 中的格式化数据,来确保它们的所有测试仍然与内核实际产生的消息格式匹配。如果 “CPU on fire” 测试不通过,则说明 “CPU on fire” 消息格式已更改。
有几个有趣的问题,第一个:为什么需要将这些信息内置到内核中?它可以放在一个单独的文件中(运行中上不需要内存)。答案或许是:这种机制使得在跨系统部署时可以轻松地将正确的格式化字符串保留在内核中。
另一个: 明确不适用于生产系统,但此功能看起来像是用于生产内核。如果这种机制被主线接受,它必须找一个更稳定的地方,例如 /sys。
不过,是否会被接受还有待观察。由于此机制不需要内核开发人员的任何额外工作,并且由于它在关闭时不会产生任何成本,与之前所做的努力相比,它可能遇到的阻力较小。如果是这样,监控系统将不会受到内核日志消息更改的影响,但至少会知道他们的测试何时需要更新。
版权声明:本文为「L 」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
———END———
限 时 特 惠: 本站每日持续更新海量各大内部创业教程,永久会员只需109元,全站资源免费下载 点击查看详情
站 长 微 信: nanadh666