我有一个程序每秒生成多个日志,我想使用日志实时跟踪这些日志,但日志似乎在从源收集/读取日志时存在延迟。我试图找到是否有选项来控制此延迟,但似乎没有。该选项不是SyncIntervalSec
我想要的——它只是定义日志将其日志写入文件的频率,我不认为日志只显示已写入文件的日志,因为延迟肯定短于默认值(5 分钟)。
日志多久从其来源收集/读取一次日志?此外,日志如何从来源收集/读取日志?
我有一个程序每秒生成多个日志,我想使用日志实时跟踪这些日志,但日志似乎在从源收集/读取日志时存在延迟。我试图找到是否有选项来控制此延迟,但似乎没有。该选项不是SyncIntervalSec
我想要的——它只是定义日志将其日志写入文件的频率,我不认为日志只显示已写入文件的日志,因为延迟肯定短于默认值(5 分钟)。
日志多久从其来源收集/读取一次日志?此外,日志如何从来源收集/读取日志?
大多数情况下,它不从源收集日志。日志实时 (大约)到达journald守护进程,就像它们过去实时提供给syslogd一样——每当程序调用syslog()时,它们都会将消息写入守护进程正在侦听的Unix套接字,并且操作系统立即唤醒守护进程,指示数据可用。
同样,每当为“stdout 日志记录”设置的 systemd 服务将 write() 写入其 stdout 管道时,操作系统都会立即将该数据传递到journald(位于管道的另一端)。
至于写入其自身日志文件的程序 - journald 根本不收集这些文件。(内核日志可能是唯一的例外,但即使这些日志也是实时从 /dev/kmsg 流式传输的 - 仍然没有收集它们的间隔。)
如果服务的标准输出日志记录未到达日志,则最常见的问题是服务内的缓冲;例如,C 中的 fwrite() 或 Python 中的 print() 通常会由 libc 进行缓冲,直到收集到大约 4-8 kB 的消息,然后才通过管道一次性将其写出。如果 write() 根本没有完成,那么日志就无法收集任何内容。 (在终端中以交互方式运行程序时,您不会注意到这一点,因为运行时会特别对待 tty。)
在这种情况下,假设您是程序的作者,您可以让它在每条消息后刷新输出,或者将其 stdout 层设置为行缓冲模式(如果 stdout 是终端,它将使用该模式),或者将您的消息写入 stderr,默认情况下通常保持行缓冲...或者切换到真正的 syslog() 接口,它也允许您指定消息优先级。
如果您使用 Python 编写,则可以执行以下任一操作:
如果您使用 libc stdio 用 C 编写,您也有相同的选择:
如果您使用的是其他人编写的程序并且没有源代码,请首先检查它是否可以切换到系统日志模式(从不缓冲)。
通常,可以通过预加载库来“修复”将日志写入 stdout 的程序
libstdbuf.so
;这仅适用于使用 libc stdio 缓冲的程序:这里没有定期的“检查”;
journalctl
只是等待新数据可用并立即处理(它使用epoll
内核机制,该机制告诉内核一个线程想要休眠直到数据可用,并在数据可用时尽快唤醒 - 这里最多只用个位数毫秒)。您看到的延迟可能是由您用来查看
journalctl
输出的寻呼机引起的。尝试以下操作:其中,运行一个无限循环(直到你ctrlc杀死它,或者发生错误)来记录当前时间。
请注意,我不知道你的程序如何记录。该方法本身可能会被缓冲,或者它可能会做坏事,例如尝试连接到每个系统日志守护进程。单身的。 ,这将需要超过 3 毫秒才能失败。