Iniciar sesión en dos archivos con diferentes configuraciones

83

Ya estoy usando una configuración de registro básica donde todos los mensajes en todos los módulos se almacenan en un solo archivo. Sin embargo, necesito una solución más compleja ahora:

  • Dos archivos: el primero sigue siendo el mismo.
  • El segundo archivo debe tener algún formato personalizado.

He estado leyendo los documentos del módulo, pero son muy complejos para mí en este momento. Leñadores, manipuladores ...

Entonces, en resumen:

Cómo iniciar sesión en dos archivos en Python 3, es decir:

import logging
# ...
logging.file1.info('Write this to file 1')
logging.file2.info('Write this to file 2')
marw
fuente

Respuestas:

154

Puedes hacer algo como esto:

import logging
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')


def setup_logger(name, log_file, level=logging.INFO):
    """To setup as many loggers as you want"""

    handler = logging.FileHandler(log_file)        
    handler.setFormatter(formatter)

    logger = logging.getLogger(name)
    logger.setLevel(level)
    logger.addHandler(handler)

    return logger

# first file logger
logger = setup_logger('first_logger', 'first_logfile.log')
logger.info('This is just info message')

# second file logger
super_logger = setup_logger('second_logger', 'second_logfile.log')
super_logger.error('This is an error message')

def another_method():
   # using logger defined above also works here
   logger.info('Inside method')
eos87
fuente
1
El nivel de registro predeterminado es logging.WARNING, por lo que sería más claro si Logger.setLevel(logging.WARNING)se llama.
zeekvfu
1
¿Por qué mi logger_1no se envía al archivo de registro? Lo configuré logger_1.error('error foo'), pero aún no funciona
Gank
Combinando el comentario de @zeekvfu y la pregunta de @Gank ... Si desea ver la logger_1.info('message_1')línea simplefile_1.log, debe configurar el nivel para INFOusar logger_1.setLevel(logging.INFO)o usar logger_1.error('message_1')en su lugar. INFOAparentemente, un mensaje no se registrará cuando el nivel sea WARNING, que es el predeterminado.
dnlbrky
editó la respuesta. Establezca logger_1.info en logger_1.warning. De esta forma, no es necesario configurar el nivel.
user1812076
1
@ eos87 ¿Logger_1 y logger_2 son globales? Es decir, ¿puedo usarlos dentro de cualquier función? si no es así, ¿es una buena idea hacerlos globales en la función def main? si es así, ¿cómo lo harías?
Dnaiel
19
def setup_logger(logger_name, log_file, level=logging.INFO):
    l = logging.getLogger(logger_name)
    formatter = logging.Formatter('%(message)s')
    fileHandler = logging.FileHandler(log_file, mode='w')
    fileHandler.setFormatter(formatter)
    streamHandler = logging.StreamHandler()
    streamHandler.setFormatter(formatter)

    l.setLevel(level)
    l.addHandler(fileHandler)
    l.addHandler(streamHandler)    


setup_logger('log1', txtName+"txt")
setup_logger('log2', txtName+"small.txt")
logger_1 = logging.getLogger('log1')
logger_2 = logging.getLogger('log2')




logger_1.info('111messasage 1')
logger_2.info('222ersaror foo')
Gank
fuente
1
¿Logger_1 y logger_2 son globales? Es decir, ¿puedo usarlos dentro de cualquier función? si no es así, ¿es una buena idea hacerlos globales en la función def main? si es así, ¿cómo lo harías?
Dnaiel
usted no haría eso en la definición, haría eso dondequiera que defina sus registradores.
Alex R
1
¿No causaría esto salidas de consola duplicadas?
Erol