OpenVPN 的文本日志把日期、时间和一个us=值放在同一行,三者中最后这一部分最容易被读错。它是该时间戳的微秒部分,输出时不做补零。它不是会话标识、用户名或计数器,把它当成这些,就会把不足一秒的零头变成一个自信的错误结论。把它当作所显示秒数的小数部分来换算,行内其余内容依旧可读。

这一行的三个部分分别是什么

日期和整秒在前,us=则承载不足一秒的余数。数值 12345 是一万二千三百四十五微秒,也就是 0.012345 秒,因此当打印时间为 09:15:30 时,这一行描述的是 09:15:30.012345。计数器每进入新的一秒就重新开始,所以后一行可以打印更小的零头,而并不是时钟在倒退。只有完整的时间戳才能给事件排序。

2026-11-02 08:41:07 us=4820

单位是一秒的百万分之一,us=的六位数字覆盖从 0.000000 到 0.999999 的整个范围。五位数字描述的是几十毫秒,六位数字描述的则是几百毫秒,直到接近整整一秒。如果换算得到大于一的零头,说明小数点移动了,算术有误。手工换算就是把这个整数除以一百万,再加到整秒上。

补零正是陷阱。us=42是四十二微秒,写作.000042,而不是.42。换算前先把整数在左侧补到六位,这个值就不再像你看到的那几位数字的小数部分。

不用计算器换算一行日志

以打印出的秒为基准,把us=当作小数部分。对于 09:15:30 和us=12345,小数形式是 09:15:30.012345;对于us=900000,则是 09:15:30.900000。小数点后的数字是补零后的整数,绝不是把整数除以一千。先写出六位形式,可以避免大多数错误。

如果你把日志解析成时间戳,就要把日期、整秒和小数部分一起解析。假设单位是毫秒的解析器会把事件顺序排错一千倍,而输出看上去仍然合理。

日志中缺少这个字段时

微秒部分属于文本日志格式,只有在启用详细时间戳时才会出现。在 OpenVPN 2.6 的时间戳格式化器中,只有该输出开启且存储值不为零时,它才会被追加。因此,没有us=的日志并不能说明时钟或构建有问题;通常只是所配置的详细级别太低。在归咎于时间同步之前,先检查配置。

从服务器配置里很容易确认这项设置。运行下面的命令,读取它返回的数字。详细时间戳输出出现在详细级别 4,所以更低的数值就能解释字段缺失,而无需其他故障。用--verb 4运行同一份配置,守护进程以该级别重启后就会显示这个字段。

grep -nE '^[[:space:]]*verb[[:space:]]+[0-9]' /etc/openvpn/server.conf

提高详细级别只会给日志增加细节,并不会改善时钟。重启之后,把新的一行与旧的一行对比,确认格式已经改变;问题解决后再把级别调低。

六位数字不能证明什么

六位数字说明的是分辨率,而分辨率并不能说明两台主机的时间是否一致。客户端和服务器都可以打印微秒,而它们的时钟可能相差好几秒。跨机器关联事件时,要记录时区和任何已知偏移,并优先选择标出对端或会话的字段,而不是任何时间戳。两行的零头相同,并不一定是同一条连接。

采集器可能会在每行到达时打上时间戳,于是又多出一个属于采集器而非 OpenVPN 的时间戳。比较之前先弄清你在读哪一个,并保留原始行,以便重新比较。

新的us=值并不能证明有新客户端登录,重复的值也不能证明事件重复。对端和连接字段才能回答这些问题。

相关文章