通过 FIFO 登录,然后重定向到文件?

chr*_*ock 8 linux logging

我有一个必须记录每笔交易的应用程序。每条日志消息都会被刷新,因为我们需要记录导致崩溃的情况。我和我的同事很好奇如何在保证日志消息离开进程的同时实现缓冲的性能效果。

我们想到的是:

  • 制作一个应用程序可以写入的 FIFO,以及
  • 将该 FIFO 的内容通过cat.

也就是说,通常情况下:

app --logfile logfile.txt
Run Code Online (Sandbox Code Playgroud)

就是现在:

mkfifo logfifo
cat logfifo &> logfile.txt &
app --logfile logfifo
Run Code Online (Sandbox Code Playgroud)

这种方法有什么问题吗?它在我们测试时有效,但我们希望绝对确保即使原始应用程序崩溃,消息也会找到重定向文件的方式。

(我们没有应用程序的源代码,所以编程解决方案是不可能的。此外,应用程序不会写入stdout,因此直接管道到不同的命令syslog是不可能的。所以不可能.)


更新:我添加了赏金。接受的答案将不会涉及logger的原因很简单,logger不是我所问。正如原始问题所述,我只是在寻找使用 FIFO 的问题。

Mat*_*Ife 6

请注意,在写入量可能超过读出量的编程中,通常需要先入先出。

因此,fifo 不会像您预期的那样完全顺利地工作,但会在引入另一个问题的同时解决您的主要问题。

存在三种可能的警告。

  1. 如果在初始化时没有任何内容读取另一端,则写入 fifo 将被无限期阻止。
  2. fifo 有一个固定的 64K 宽度,如果缓冲区在那个点被填满,进一步的写入将被阻塞,直到读取器赶上。
  3. 如果读取器死亡或退出,管道写入器将被 SIGPIPE 杀死。

这意味着您的问题(在非缓冲写入上模拟缓冲 I/O)将得到解决。那是因为 FIFO 上的新“限制”实际上将成为任何实用程序将管道中的内容写入磁盘(可能是缓冲 I/O)的速度。

然而,作者变得依赖于您的日志阅读器来运行。如果读者突然停止阅读,作者就会阻塞。如果读取器突然退出(假设您的目标磁盘空间不足),写入器将发出 SIGPIPE 信号并可能退出。

另一点要提到的是,如果服务器出现混乱并且内核停止响应,您可能会丢失该缓冲区中多达 64k 的数据。

解决此问题的另一种方法是将日志写入 tmpfs(Linux 上的 /dev/shm)并将输出拖尾到固定磁盘位置。这样做的内存分配限制较少(不是 64K,通常是 2G!),但如果作者没有动态方式重新打开日志文件(您必须定期从 tmpfs 中清除日志),则可能对您不起作用。如果服务器在此方法中出现混乱,您可能会丢失更多数据。