当收到信号时,在 python3 中旋转(重新打开)文件
rotate (reopen) file in python3, when signal is received
我有一个简单的脚本,它记录到一个日志文件中。这是我脚本的核心:
with open('/var/log/mail/mail.log', 'a', buffering=1) as f:
for line in sys.stdin:
f.write(line)
正在写入的文件 /var/log/mail/mail.log
必须定期轮换 logrotate
。目前,当 logrotate
旋转文件时,我的脚本没有意识到这一点,并继续写入旧文件(现已重命名)。
logrotate
有可能在文件旋转后执行命令。通常,当 rsyslog
正在记录时,命令将是:
postrotate
invoke-rc.d rsyslog rotate > /dev/null
endscript
但就我而言,我需要向我的脚本发送一些信号,并在我的脚本中处理该信号。
此外,我事先并不知道 PID
我的脚本是 运行 as.
我怎样才能最好地实现它?
作为解决方案,您可以查看打开的日志文件的 inode 是否与路径相同。如果没有重新打开文件。这仅适用于 Unix。
import os, sys, stat
logfile = '/var/log/mail/mail.log'
while True:
with open(logfile, 'a', buffering=1) as f:
f_ino = os.stat(logfile)[stat.ST_INO]
f_dev = os.stat(logfile)[stat.ST_DEV]
for line in sys.stdin:
f.write(line)
try:
if os.stat(logfile)[stat.ST_INO] != f_ino or
os.stat(logfile)[stat.ST_DEV] != f_dev:
break
except OSError: # Was IOError with python < 3.4
pass
不需要关闭文件,因为它由 with
上下文管理器处理。
try..except
OSError
块用于捕获系统函数 os.stat
的任何错误。可能是在文件更改期间,函数 returns 和 OSError
(例如 FileNotFoundError
)。在这种情况下,它将传递异常并重试检查 inode 是否已更改。如果我们省略此 try..except
块,您可能会得到一个终止的程序。
我有一个简单的脚本,它记录到一个日志文件中。这是我脚本的核心:
with open('/var/log/mail/mail.log', 'a', buffering=1) as f:
for line in sys.stdin:
f.write(line)
正在写入的文件 /var/log/mail/mail.log
必须定期轮换 logrotate
。目前,当 logrotate
旋转文件时,我的脚本没有意识到这一点,并继续写入旧文件(现已重命名)。
logrotate
有可能在文件旋转后执行命令。通常,当 rsyslog
正在记录时,命令将是:
postrotate
invoke-rc.d rsyslog rotate > /dev/null
endscript
但就我而言,我需要向我的脚本发送一些信号,并在我的脚本中处理该信号。
此外,我事先并不知道 PID
我的脚本是 运行 as.
我怎样才能最好地实现它?
作为解决方案,您可以查看打开的日志文件的 inode 是否与路径相同。如果没有重新打开文件。这仅适用于 Unix。
import os, sys, stat
logfile = '/var/log/mail/mail.log'
while True:
with open(logfile, 'a', buffering=1) as f:
f_ino = os.stat(logfile)[stat.ST_INO]
f_dev = os.stat(logfile)[stat.ST_DEV]
for line in sys.stdin:
f.write(line)
try:
if os.stat(logfile)[stat.ST_INO] != f_ino or
os.stat(logfile)[stat.ST_DEV] != f_dev:
break
except OSError: # Was IOError with python < 3.4
pass
不需要关闭文件,因为它由 with
上下文管理器处理。
try..except
OSError
块用于捕获系统函数 os.stat
的任何错误。可能是在文件更改期间,函数 returns 和 OSError
(例如 FileNotFoundError
)。在这种情况下,它将传递异常并重试检查 inode 是否已更改。如果我们省略此 try..except
块,您可能会得到一个终止的程序。