我遇到了听起来很奇怪的情况。我有一个包含各种日志文件的目录的安装点。有时需要卸载该目录并将其重新安装到其他位置。 (您可以将其视为另一种做法logrotate
,尽管这不是主要意图。)
问题是这是一个实时系统,并且有总是日志文件打开。在进行卸载和重新安装之前,我可以尝试首先停止所有正在写入的进程,并在重新安装后重新启动它们,但在我的情况下,我不能总是保证这一点。可能正在记录的进程并不全部在我的控制之下,并且可能总是有一个我的安装切换例程没有听说过的新进程。或者有人可能已交互登录并更改为日志记录目录。 (此外,某些进程在没有潜在不稳定因素的情况下无法停止。)但是任何正在写入日志记录目录中的文件或将日志记录目录作为其当前目录的进程都会阻止卸载,从而阻止我的切换工作根本不。
所以我想做的是尝试使用假设的“动态挂载切换文件系统”。这基本上是一个简单的直通虚拟文件系统,它将所有文件系统操作映射到底层的真实文件系统,但能够动态地将映射重定向到不同的底层真实文件系统随时,即使文件打开。
切换期间自然会存在一些语义含义:
打开用于写入的文件必须被拆分,之前写入的部分留在旧的虚拟安装点上,而新写入的任何内容都将转到新的虚拟安装点上。这对于以 O_APPEND 模式打开的文件效果最好,实际上可能必须禁止对写入文件的查找。但对于顺序写入的日志文件来说,所有这些后果都完全没问题(这当然正是我的应用程序所涉及的)。
打开供读取的文件必须返回 EOF 或 EIO。
以日志目录作为当前目录的进程不应受到影响(尽管
ls
切换之前和之后可能会产生截然不同的结果)。日志目录的子目录可能需要更多考虑,但基本上遵循相同的规则。
希望到目前为止这一切都是有意义的(尽管你可能认为我这么想是疯了)。
所以我的问题是:
是否已经存在可以执行此操作的虚拟文件系统模块? (我知道“联合”文件系统 和
autofs
,它们在某些方面有点相似。)如果不存在这样的模块,那么如果我尝试编写一个模块,我是否会忽略任何无法克服的困难?
有更好的方法来做我想做的事情吗?请记住,我的要求是执行与卸载和重新安装文件系统相同的操作,但我的限制是很可能有文件打开。
(你们中的一些人仍然说,“这太疯狂了。您只需确保卸载时没有打开文件即可。”我想说的是,我根本无法保证这一点。识别所有可能的进程编写日志文件是一个开放式问题;任何需要提前识别所有日志文件的解决方案都完全无法适应未来的需要,这就是为什么我正在认真考虑这种疯狂的动态安装 VFS——我相信这实际上会减少工作量,并且增加工作量。稳定的。)
附录:有人建议我将所有日志记录切换到系统日志(或其他一些独特的中央服务),这样就可以轻松集中管理。但正如我所说,我无法控制所有正在进行或可能正在进行日志记录的进程。例如,其中之一是chrony
,它使用 fwrite 而不是 syslog 来记录跟踪信息等内容。 (我无法停止并重新启动 chrony,因为我不想破坏计时,所以现在我不得不放弃大多数 chrony 日志记录。)
答案1
一种可能的解决方案是将日志发送到非关系数据库。
您还可以尝试一些技巧,选择支持同时从多个源写入的文件系统。
这两种解决方案都有各自的问题,并且对我没有吸引力。
当您提出问题时,另一个可能的解决方案是通过 NFS 共享公共 /var/log/machine 目录。这也是一种令人讨厌的黑客行为,可能适用于几台服务器,但扩展性不佳。
我将创建一个中央系统日志服务器,并尽可能将所有日志指向它。这样,至少在那些日志中,同时存在的问题就解决了。
至于其他不适合直接进行系统日志记录的应用程序,甚至对于系统日志来说,我会考虑 filebeat 或graylog。
最终,我会尝试将不可 syslogable 日志处理到中央 syslog(我使用 Apache 和 Tomcat 日志进行后者)。
您还可以查看其他商业产品,例如 loggly、Scalyr。 New Relic 或 Splunk Enterprise。作为额外的好处,您可以向管理层展示非常好的统计数据并进行容量规划。
在支出并拥有明确定义的流程后,您可以建立内部规则,任何需要安装新解决方案的人都必须使用“官方”方法将日志发送到官方目的地。
PS 您正在尝试通过技术解决方案解决组织问题。通常情况不会太顺利。你必须让你的上级参与进来。