删除输出文件后捕获新输出

删除输出文件后捕获新输出

我使用以下命令在 Debian 上运行 java 服务器:

  java -jar myapp.jar [args] >> log.txt

一旦我压缩日志文件以发送它,然后我意识到原始文件已经消失,只剩下 .gzip。

尽管我手动创建了该文件(并且还尝试解压缩原始文件),但应用程序不再记录到该文件。所以我的问题是:该日志之后去了哪里?有没有办法在不重新启动应用程序的情况下重新路由输出日志文件(因为它是服务器,我不想终止该进程)。

答案1

gziplog.txt当 Java 进程仍打开该文件时,将其删除。删除文件实际上意味着删除该文件的名称。 (当一个文件有多个名称时,就说它有多个硬链接.) 仅当所有文件名均已删除并且文件未被任何进程打开时,文件数据才会被删除。所以文件消失后,它还在磁盘上;仅当 Java 进程退出或关闭文件时,该文件才被实际删除。

请注意,Java 进程仍在写入现已删除的文件。如果您创建一个具有相同名称的新文件并不重要:那是一个不同的文件。

如果文件没有留下任何名称,则在大多数 unice 上,您无法重新创建指向该文件的硬链接,即使该文件仍处于打开状态。有一个提议的补丁引入一个flink系统调用来在 Linux 上执行此操作,但它是击落

您仍然可以读取该文件的内容(在 Linux 上很方便,但在大多数 unice 上可能不太方便)。/proc/1234/fd1234 是 Java 进程的 PID 的目录包含指向该进程已打开的文件的符号链接。如果这些文件之一被删除,符号链接将悬空,但仍然可以打开进行阅读。

这将允许您从进程中提取所有日志行。跑步

tail -c +$(($(zcat log.txt.gz | wc -c) + 1)) -f </proc/1234/fd >more-log.txt

直到Java进程死亡。

答案2

man gzip

 -k, --keep        Keep (don't delete) input files during compression or
                   decompression.

所以gzip -k log.txt应该这样做。

(但一般来说,一个真实的日志记录解决方案,即一些syslog守护进程,可能使用log4j,可能更可取。)

相关内容