日志设计要回答三个问题:记录由哪个进程产生、落到哪里、能保留多久。OpenVPN 可以写入文件、把消息交给系统日志器,或者留给服务管理器去捕获,而这并不是同一条流的三个副本。每一种选择都会改变轮转由谁负责、哪个用户能读到结果,以及启动期间会发生什么。请在事故之前把这些答案定下来,因为事后你只能继承既有的配置。

守护进程对指令的实际处理

这些指令并不是抽象概念;每一条都决定进程把消息写到哪里。log /path 打开该文件,log-append /path 以追加方式打开,syslog 则通过套接字把消息交给本机系统日志器。三者都不用,输出就进入标准输出,接下来发生什么由服务管理器决定。在断定守护进程忽略了你的配置之前,请把生效的 unit 与配置文件放在一起读。

最后那种情况在打包安装中很常见,这也解释了两名管理员为何对日志位置看法不一。一个人读的是 unit 日志,另一个人读的是守护进程从未写过的文件。

要查看运行中的配置,而不是磁盘上的文件。drop-in 形式的 unit 覆盖或环境文件都能改掉实际生效的指令,而不触碰你正在读的配置。

log 会截断,log-append 不会

log 在指令生效时会截断已有文件,所以一次重启就会抹掉此前的证据。log-append 保留原有内容并继续追加。两者都不做轮转,也不会自行重新打开文件,这正是轮转需要配合的原因。

如果轮转重命名了文件,而守护进程仍在往旧描述符写,那么新文件会一直是空的,磁盘占用则在改名后的文件里继续增长。要么给进程发信号让它重新打开,要么采用复制后截断的方式轮转并接受复制窗口。

目录、属主与权限都是设计的一部分。守护进程在启动后可能以非特权用户运行,而安装时由 root 创建的目录在那时未必可写。请通过打包或部署流程把它准备好,而不是在事故中临时修权限。

服务管理器还留着第二份副本

systemd 默认捕获标准输出与标准错误,因此没有显式重定向的 unit 本身就已经有一份日志。再加上文件指令,就得到两条数据流,它们的保留策略、读取者和时间戳都不同。

那并不一定是错的,但必须是一个决定。把启动阶段的记录留在 journal 里,因为配置文件存在之前的失败只在别处无迹可寻。然后让文件成为稳定期事件的权威来源,并在运行手册里写明。两条权威流意味着每个问题都有两个答案。

用一个故意失败的测试来确认这个选择。用一份无法读取的证书启动守护进程,看哪条流记录下这个错误。

详细程度不等于可用的细节

更高的 verb 级别会增加更多行,而超过某个点之后,增加的行没人会读。对大多数部署来说,级别 3 是合理的稳定状态,级别 4 及以上适合围绕一个明确问题做有边界的调查。重复抑制能降噪,但它不该掩盖某个事件重复发生的频率。设定你能维持的级别,只在有明确名称、有结束时间的调查中才调高。

记录里要保留实例标识与时间戳。当文件已经追加了几个月而实例名缺失时,一次重连看起来和首次连接一模一样。

要留意还有什么会落进这个文件。重定向的输出可能包含被调用脚本的文字,而一个回显自身环境的辅助程序会把凭据和密钥路径写进可读的日志。即使守护进程本身不打印敏感内容,也要把日志访问当作安全决策。

轮转、保留期与触发重载的信号

与拥有磁盘的人一起决定保留期,并在卷替你做决定之前设定好。重载信号不是日志维护命令:发错一个信号会重启隧道并断开所有用户。把重新打开文件的流程写在轮转规则旁边,这样两者就不会彼此走偏。

最终结果应当是一项运维人员能描述清楚的服务:一条权威数据流,每个事件都落在生命周期的相应位置,并且无需收集主机上每一个含密的文件就能取得记录。这个描述就是设计的验收测试,在下一次事故之前检查它成本很低。

相关文章