повернуть (повторно открыть) файл в python3, когда сигнал получен - PullRequest
2 голосов
/ 27 мая 2020

У меня есть простой скрипт, который ведет журнал в файл журнала. Это ядро ​​моего скрипта:

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 мой скрипт работает как.

Как мне лучше всего это реализовать?

1 Ответ

1 голос
/ 30 мая 2020

В качестве решения этой проблемы вы можете посмотреть, совпадает ли индексный дескриптор открытого файла журнала с путем. Если нет, откройте файл заново. Это работает только на 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 IOError:
                pass

Закрытие файла не требуется, так как он обрабатывается with диспетчером контекста.

...