有一个 Java 进程会将日志记录到某个文件中,例如错误日志。我将其重命名(无需重新启动 Java 进程),例如“mv err.log err.log0“然后看到 java 进程继续记录到错误日志0。
为什么会这样?其背后的逻辑是什么?这在所有 unix/Linux 平台上都是通用的吗?
答案1
进程在启动时会打开日志文件并保持打开状态。它将使用打开文件时创建的文件描述符写入文件。一旦打开文件,文件的名称与文件描述符就没有任何关系,因此更改名称不会影响进程写入文件。这是正常且符合预期的。
如果您希望您的进程打开一个新的日志文件,那么就必须写入一个信号来告诉它关闭旧文件并打开一个新文件。
答案2
除此之外,您实际上可以打开文件而不使用任何文件名。假设您删除了该文件,进程将继续写入它,并且它将继续占用磁盘空间。当它关闭时,它将被删除。您还可以让同一个文件通过多个文件名访问,您可以使用“ln”命令创建这些文件名。打开并立即删除文件的目录条目是一种常见的方法,可以确保在进程退出时释放临时文件的空间,即使进程崩溃也是如此。“ls”的“-i”选项将包含 inode 编号,以便您可以知道哪些文件名属于同一个文件。
答案3
如果你想在不重新启动 Java 进程的情况下轮换日志文件,这里有一个可行的方法:
cp err.log err.log0
cat /dev/null > err.log
这实际上会复制日志,然后截断它(将其大小设置为零),因此您需要额外的磁盘空间,但应用程序随后应继续记录到 err.log。