轮换日志文件的解决方案

Mar*_*tus 10 logs logrotate

我正在运行一个守护进程,它必须无限期地运行(可以说是“服务”)并希望记录其输出。一个简单的解决方案,如:

./long-running-process > log.out &
Run Code Online (Sandbox Code Playgroud)

...作为文件失败log.out

  • 一旦超过大小,我可以很容易地像一个文本编辑器处理emacsvi
  • 存在耗尽可用文件系统空间的风险。

为了保持日志文件的大小可管理,我可以使用splitbash 命令:

./long-running-process | split -l 30000
Run Code Online (Sandbox Code Playgroud)

此解决方案使它创建的日志文件的大小保持在可管理的范围内,但是它可能会用完后缀 ( split: output file suffixes exhausted),或者,如果后缀空间很大,它也可能会耗尽文件系统空间。

因此,我正在寻找一种解决方案,该解决方案将生成许多日志文件,每个日志文件的大小都可以管理,并且还将在它们之间轮换,以便对总磁盘空间进行声明。

是否有这样的解决方案可用,或者我必须在应用程序级别实现它吗?

X T*_*ian 8

切割原木

Apache 项目有一个有用的命令,rotatelogs旨在旋转通过输入管道接收到的输入 阅读有关 rotatelogs 的信息

然后还有cronolog更好的时间处理。Cronolog 网站

但是,如果您也在旋转,那么值得考虑 logrotate,但 logrotate 需要一种机制来触发新的日志文件,(发送信号,重新启动程序,...)。如果您正在记录标准输出并且不想重新启动该过程,那么这可能是 rotatelogs/cronolog 的用武之地。


slm*_*slm 6

大多数现代 Linux 发行版都包含一个工具logrotate,操作系统会使用该工具来维护/var/log目录。你也可以使用它。它是通过 启动的cron,因此如果您希望日志以特定频率旋转,那么您需要设置一个至少运行频率如此之高的 cronjob。

例子

这将旋转 2 个文件access.log& error.log,最多保留 5 个(当前 + 4 个旋转)。重定位当前日志文件后,killall -HUP httpd向正在运行的守护进程发送“挂断”信号以触发新日志文件的创建,以从此时开始记录到原始命名access.logerror.log文件。如果日志文件的大小超过 100k,这也将旋转日志文件。

   "/var/log/httpd/access.log" /var/log/httpd/error.log {
       rotate 5
       mail www@my.org
       size 100k
       sharedscripts
       postrotate
           /usr/bin/killall -HUP httpd
       endscript
   }
Run Code Online (Sandbox Code Playgroud)

这将在/var/log/news/*montly目录下轮换日志文件,保持 2(当前 + 1)。这组规则将使日志保持其原始状态,而不是将它们压缩 ( .gz),这是默认行为。

   /var/log/news/* {
       monthly
       rotate 2
       olddir /var/log/news/old
       missingok
       postrotate
           kill -HUP `cat /var/run/inn.pid`
       endscript
       nocompress
   }
Run Code Online (Sandbox Code Playgroud)

我必须发送 kill -HUP 吗?

不,这不是强制性的,仅当您的应用程序需要时。这是触发您的应用程序停止写入当前日志文件(在从 say access.logto重命名后access.log.1)并再次开始记录到原始名称access.log.

/var/log/atop/atop.log {
    missingok
    weekly
    rotate 4 
    notifempty
    create 0600 root root
}
Run Code Online (Sandbox Code Playgroud)

参考


uml*_*ute 5

为了完整起见,我还想提及以下copytruncate选项logrotate

   copytruncate
          Truncate the original log file to zero size in place after
          creating a copy, instead of moving the old log file and
          optionally creating a new one.  It can be used when some program
          cannot be told to close its logfile and thus might continue
          writing (appending) to the previous log file forever.
         Note that there  is  a  very small  time  slice  between  copying
          the  file  and truncating it, so some logging data might be lost.
          When this option is used, the *create* option will have no effect,
          as the old log file stays in place.
Run Code Online (Sandbox Code Playgroud)

  • copytruncate 确实解决了打开新 fd 的守护进程信号问题,但引入了竞争条件,在轮换过程中日志数据可能会“丢失”(即从未记录)。您无法在单个原子 POSIX 操作中复制所有数据并截断文件。通常,对于在写入文件时需要日志数据一致性的任何人来说,这将是一个交易破坏者。 (2认同)