Hacer que los loggers de Python emitan todos los mensajes a stdout además del registro


¿Hay una manera de hacer que el registro de Python use el módulo logging automáticamente genere cosas a stdout además al archivo de registro donde se supone que deben ir? Por ejemplo, me gustaría que todas las llamadas logger.warning, logger.critical, logger.error para ir a sus lugares previstos, pero además siempre se copian a stdout. Esto es para evitar la duplicación de mensajes como:

mylogger.critical("something failed")
print "something failed"
Author: Martijn Pieters, 2012-12-27

5 answers

Toda la salida del registro es manejada por los manejadores; simplemente agregue un logging.StreamHandler() al registrador raíz.

Aquí hay un ejemplo configurando un controlador de flujo (usando stdout en lugar del predeterminado stderr) y agregándolo al registrador raíz:

import logging
import sys

root = logging.getLogger()
root.setLevel(logging.DEBUG)

ch = logging.StreamHandler(sys.stdout)
ch.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
root.addHandler(ch)
 435
Author: Martijn Pieters,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-07 10:13:25

La forma más sencilla:

import logging
import sys
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
 337
Author: Eyal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-18 03:56:17

Es posible usar múltiples controladores.

import logging
import auxiliary_module

# create logger with 'spam_application'
log = logging.getLogger('spam_application')
log.setLevel(logging.DEBUG)

# create formatter and add it to the handlers
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# create file handler which logs even debug messages
fh = logging.FileHandler('spam.log')
fh.setLevel(logging.DEBUG)
fh.setFormatter(formatter)
log.addHandler(fh)

# create console handler with a higher log level
ch = logging.StreamHandler()
ch.setLevel(logging.ERROR)
ch.setFormatter(formatter)
log.addHandler(ch)

log.info('creating an instance of auxiliary_module.Auxiliary')
a = auxiliary_module.Auxiliary()
log.info('created an instance of auxiliary_module.Auxiliary')

log.info('calling auxiliary_module.Auxiliary.do_something')
a.do_something()
log.info('finished auxiliary_module.Auxiliary.do_something')

log.info('calling auxiliary_module.some_function()')
auxiliary_module.some_function()
log.info('done with auxiliary_module.some_function()')

# remember to close the handlers
for handler in log.handlers:
    handler.close()
    log.removeFilter(handler)

Por favor ver: https://docs.python.org/2/howto/logging-cookbook.html

 46
Author: Alok Singh Mahor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-05 13:03:21

La forma más sencilla de iniciar sesión en file y en stderr:

  import logging
  logging.basicConfig(filename="logfile.txt")
  stderrLogger=logging.StreamHandler()
  stderrLogger.setFormatter(logging.Formatter(logging.BASIC_FORMAT))
  logging.getLogger().addHandler(stderrLogger)
 28
Author: Weidenrinde,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-22 08:25:00

Puede crear dos controladores para file y stdout y luego crear un registrador con el argumento handlers para basicConfig. Podría ser útil si tiene la misma salida log_level y format para ambos controladores:

import logging
import sys

file_handler = logging.FileHandler(filename='tmp.log')
stdout_handler = logging.StreamHandler(sys.stdout)
handlers = [file_handler, stdout_handler]

logging.basicConfig(
    level=logging.DEBUG, 
    format='[%(asctime)s] {%(filename)s:%(lineno)d} %(levelname)s - %(message)s',
    handlers=handlers
)

logger = logging.getLogger('LOGGER_NAME')
 24
Author: Anton Protopopov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-05 05:08:01