Django: Registro de archivos personalizados todos los días
Estoy ejecutando Django 3.1 en Docker y quiero registrar diferentes archivos todos los días. Tengo un par de crones corriendo y también tareas de apio. No quiero iniciar sesión en un archivo porque muchos procesos estarán escribiendo y depurando/leyendo el archivo será difícil.
Si tengo tareas de cron my_cron_1, my_cron_2,my_cron_3 Quiero poder conectarme a un archivo y anexar la fecha
MyCron1_2020-12-14.log
MyCron2_2020-12-14.log
MyCron3_2020-12-14.log
MyCron1_2020-12-15.log
MyCron2_2020-12-15.log
MyCron3_2020-12-15.log
MyCron1_2020-12-16.log
MyCron2_2020-12-16.log
MyCron3_2020-12-16.log
Básicamente, quiero ser capaz de pasar en un nombre a una función que escribirá a un archivo de registro.
Ahora mismo. Tengo una clase MyLogger
import logging
class MyLogger:
def __init__(self,filename):
# Gets or creates a logger
self._filename = filename
def log(self,message):
message = str(message)
print(message)
logger = logging.getLogger(__name__)
# set log level
logger.setLevel(logging.DEBUG)
# define file handler and set formatter
file_handler = logging.FileHandler('logs/'+self._filename+'.log')
#formatter = logging.Formatter('%(asctime)s : %(levelname)s: %(message)s')
formatter = logging.Formatter('%(asctime)s : %(message)s')
file_handler.setFormatter(formatter)
# add file handler to logger
logger.addHandler(file_handler)
# Logs
logger.info(message)
Llamo a la clase así.
logger = MyLogger("FirstLogFile_2020-12-14")
logger.log("ONE")
logger1 = MyLogger("SecondLogFile_2020-12-14")
logger1.log("TWO")
FirstLogFile_2020-12-14
tendrá uno dos, pero sólo debería tener unoSecondLogFile_2020-12-14
tendrá TWO
¿Por qué es esto? ¿Por qué los registros están siendo escritos al archivo incorrecto? ¿Qué tiene de malo mi código?
Pregunta hecha hace 3 años, 5 meses, 0 días - Por codechampion
2 Respuestas:
-
El problema en tu código está ocurriendo porque estás agregando un nuevo manejador de archivo cada vez que llamas al método
log
de la claseMyLogger
. Esto hace que los mensajes se escriban en todos los archivos de registro existentes, en lugar de sólo en el archivo asociado a esa instancia particular deMyLogger
.Para solucionar este problema, puedes realizar las siguientes modificaciones en tu clase
MyLogger
:- Mover la creación del logger y el manejador de archivo al método `__init__`, en vez de crearlos en el método `log`.
- Verificar si el manejador de archivo ya ha sido agregado antes de agregarlo nuevamente.
Aquí te dejo un ejemplo de cómo podrías modificar tu clase
MyLogger
:python import logging class MyLogger: def __init__(self, filename):
Gets or creates a logger
self._filename = filename self.logger = logging.getLogger(__name__) self.logger.setLevel(logging.DEBUG)define file handler and set formatter
file_handler = logging.FileHandler('logs/' + self._filename + '.log') formatter = logging.Formatter('%(asctime)s : %(message)s') file_handler.setFormatter(formatter)add file handler to logger if not already added
if not any(isinstance(handler, logging.FileHandler) for handler in self.logger.handlers): self.logger.addHandler(file_handler) def log(self, message): message = str(message) print(message) self.logger.info(message)Con estas modificaciones, cada instancia de
MyLogger
tendrá su propio manejador de archivo asociado y los mensajes se escribirán únicamente en el archivo correspondiente. Puedes seguir llamando a la clase de la misma manera que lo estabas haciendo:python logger = MyLogger("FirstLogFile_2020-12-14") logger.log("ONE") logger1 = MyLogger("SecondLogFile_2020-12-14") logger1.log("TWO")
De esta manera, cada archivo de registro contendrá sólo los mensajes asociados a esa instancia particular de
MyLogger
.Respondida el Dec 17, 2020 a las 20:38 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
El problema con tu código es que estás creando un nuevo FileHandler y agregándolo al registrador cada vez que llamas a
MyLogger
. Esto significa que cada instancia deMyLogger
tendrá su propio FileHandler, y todos ellos escribirán en el mismo archivo.Para solucionar este problema, debes crear un FileHandler una sola vez y compartirlo entre todas las instancias de
MyLogger
. Puedes hacer esto creando una variable de clase para el FileHandler:python class MyLogger:
Crea un FileHandler compartido para todas las instancias
file_handler = logging.FileHandler('logs/{}.log') file_handler.setFormatter(logging.Formatter('%(asctime)s : %(message)s')) def __init__(self, filename): self._filename = filename def log(self, message): message = str(message) print(message) logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG)Agrega el FileHandler compartido al registrador
logger.addHandler(self.file_handler)Logs
logger.info(message)Ahora, cuando llames a
MyLogger
, todas las instancias utilizarán el mismo FileHandler y escribirán en el archivo apropiado según el nombre de archivo especificado.Respondida el Dec 17, 2020 a las 20:47 - por Gemini
Votos positivos: 0 | Votos negativos: 0