python3: problema de rotação de log timedrotatingfilehandler com o mesmo arquivo de log com vários scripts

Sep 11 2020

Por favor, ajude na solução de problemas de log do python3 de vários processos no mesmo arquivo de log. Eu tenho o script principal dameon, que é executado em segundo plano e chama alguns outros scripts pythons a cada 15 segundos, e cada script python é escrito com os mesmos atributos TimedRotatingFileHandler e todos os logs são gravados no mesmo arquivo de log.

tudo funciona bem, exceto a rotação do log.

lib/
├── __init__.py
├── FIRST.py
└── SECOND.py
└── THIRD.py
main_daemon.py

arquivo daemon python principal parece

t1 = t2 = t3 = Thread()
my_thread = MYthreads(t1, t2, t3)
################# Daemon Class #################
class Daemon(Daemon):
        def run(self):
             while True:
                my_thread.start_my_class()
                time.sleep(15)

ProcessManager = Daemon('daemon.pid')
ProcessManager.start()

lib/__init__.py arquivo parece pouco

class MYthreads:
    def __init__(self, t1, t2, t3):
        self.t1 = t1
        self.t2 = t2
        self.t3 = t3

    def start_my_class(self):
            for file in List_files(path1):
                self.t1 = Thread(target=FIRSTprocess, args=(file,))
                self.t1.start()
                self.t1.join()
            for file in List_files(path2):
                self.t2 = Thread(target=SECONDprocess, args=(file,))
                self.t2.start()
                self.t2.join()
            for file in List_files(path3):
                self.t3 = Thread(target=THIRDprocess, args=(file,))
                self.t3.start()
                self.t3.join()

aqui, os alvos são funções importadas de arquivos Python separados no diretório lib /. cada arquivo python grava logs no mesmo arquivo de log.

registro definido em cada arquivo python dentro do diretório lib / ..

logger = logging.getLogger('mylogger')
#TimedRoatingFile handler definition
Timed_formatter = logging.Formatter('%(message)s')
Timed_handler = logging.handlers.TimedRotatingFileHandler('my_log', 'midnight', 1, 90)
Timed_handler.setFormatter(Timed_formatter)
logger.addHandler(Timed_handler)
#syslog handler definition
if syslog_streaming and curr_os != 'Windows':
    log_formatter = logging.Formatter('%(name)s: %(message)s')
    Sys_handler = logging.handlers.SysLogHandler(address = '/dev/log')
    Sys_handler.setFormatter(log_formatter)
    logger.addHandler(Sys_handler)
    logger.handlers = [logger.handlers[0], logger.handlers[1]]
else:
    logger.handlers = [logger.handlers[0], ]
# Set lev to DEBUG, applied to both
logger.setLevel(logging.DEBUG)

Portanto, defini os mesmos atributos de registro em todos os arquivos Python, e os gravei no mesmo arquivo de registro, importei todas essas funções __init__.pye chamei a classe a cada 15 segundos por meio do loop while.

O registro e a gravação de registros estão funcionando bem ... e até mesmo o syslog também está funcionando bem.

Problema: a rotação do log não está funcionando bem. Devo usar o manipulador rotativo de tempo, já que minha exigência é fazer rollover às 12h todas as noites. Quando eu verifico o arquivo de log após as 12h, o arquivo de backup é criado, mas os logs gravados no dia inteiro antes das 00hs são perdidos, eu pude apenas algumas linhas de logs gerados às 00h horas na nova data, e os logs de data mais antigos são todos PERDIDOS.

-rw-r--r--. 1 usertony usertony    1097 Sep  7 01:15 my_log.2020-09-06
-rw-r--r--. 1 usertony usertony    1097 Sep  8 00:00 my_log.2020-09-07
-rw-r--r--. 1 usertony usertony      96 Sep  9 00:00 my_log.2020-09-08

Respostas

4 pygeek Sep 15 2020 at 00:11

Problema

Seus processos estão competindo para gravar no mesmo arquivo, resultando em uma condição de corrida, causando problemas durante o rollover.

Solução

Você precisa definir seu registrador fora desses threads:

https://docs.python.org/3/howto/logging-cookbook.html#logging-to-a-single-file-from-multiple-processes

Nota

Eu não recomendaria substituir a classe Daemon pela sua classe. Se herança for o objetivo, nomeie sua classe como algo contextual (ou seja:) FileLoggingDeamon.

Referências

Registrando em um único arquivo de vários processos: https://docs.python.org/3/howto/logging-cookbook.html#logging-to-a-single-file-from-multiple-processes

https://stackoverflow.com/a/9993857/806876