Redirigir la salida ''print'' de Python al registrador
print python 3 (5)
Por supuesto, puede imprimir en la salida estándar y adjuntar a un archivo de registro, como este:
# Uncomment the line below for python 2.x
#from __future__ import print_function
import logging
logging.basicConfig(level=logging.INFO, format=''%(message)s'')
logger = logging.getLogger()
logger.addHandler(logging.FileHandler(''test.log'', ''a''))
print = logger.info
print(''yo!'')
Tengo una secuencia de comandos de Python que utiliza ''Imprimir'' para imprimir en la salida estándar. Recientemente he agregado el registro a través de Python Logger y me gustaría hacerlo para que estas declaraciones de impresión vayan al registrador si el registro está habilitado. No quiero modificar o eliminar estas declaraciones de impresión.
Puedo iniciar sesión haciendo ''log.info ("some info msg")''. Quiero poder hacer algo como esto:
if logging_enabled:
sys.stdout=log.info
print("test")
Si el registro está habilitado, "prueba" se debe registrar como si lo hiciera log.info ("prueba"). Si el registro no está habilitado, la "prueba" debería imprimirse en la pantalla.
es posible? Sé que puedo dirigir stdout a un archivo de una manera similar (ver: redirigir las impresiones al archivo de registro )
Realmente debería hacerlo de la otra manera: ajustando su configuración de registro para usar sentencias de print
u otra cosa, dependiendo de la configuración. No sobrescriba el comportamiento de print
, ya que algunas de las configuraciones que pueden introducirse en el futuro (p. Ej., Usted o alguien que use su módulo) pueden enviarlo a la salida stdout
y tendrá problemas.
Hay un controlador que se supone que redirige los mensajes de registro a la secuencia adecuada (archivo, stdout
o cualquier otra cosa similar a un archivo). Se llama StreamHandler
y se incluye con el módulo de logging
.
Básicamente, en mi opinión, debería hacer lo que dijo que no quiere hacer: reemplazar print
declaraciones de print
con el registro real.
Tienes dos opciones:
Abra un archivo de registro y reemplace sys.stdout con él, no con una función:
log = open("myprog.log", "a") sys.stdout = log >>> print("Hello") >>> # nothing is printed because it goes to the log file instead.
Reemplace la impresión con su función de registro:
# If you''re using python 2.x, uncomment the next line #from __future__ import print_function print = log.info >>> print("Hello!") >>> # nothing is printed because log.info is called instead of print
Un método más es envolver el registrador en un objeto que traduce las llamadas para write
en el método de log
del log
.
Ferry Boender hace precisamente esto, proporcionado bajo la licencia GPL en una publicación en su sitio web :
import logging
import sys
class StreamToLogger(object):
"""
Fake file-like stream object that redirects writes to a logger instance.
"""
def __init__(self, logger, log_level=logging.INFO):
self.logger = logger
self.log_level = log_level
self.linebuf = ''''
def write(self, buf):
for line in buf.rstrip().splitlines():
self.logger.log(self.log_level, line.rstrip())
logging.basicConfig(
level=logging.DEBUG,
format=''%(asctime)s:%(levelname)s:%(name)s:%(message)s'',
filename="out.log",
filemode=''a''
)
stdout_logger = logging.getLogger(''STDOUT'')
sl = StreamToLogger(stdout_logger, logging.INFO)
sys.stdout = sl
stderr_logger = logging.getLogger(''STDERR'')
sl = StreamToLogger(stderr_logger, logging.ERROR)
sys.stderr = sl
Esto le permite enrutar fácilmente toda la salida a un registrador de su elección. Si es necesario, puede guardar sys.stdout
y / o sys.stderr
como lo mencionaron otros en este hilo antes de reemplazarlo si necesita restaurarlo más tarde.
Una opción mucho más simple,
import logging, sys
logging.basicConfig(filename=''path/to/logfile'', level=logging.DEBUG)
logger = logging.getLogger()
sys.stderr.write = logger.error
sys.stdout.write = logger.info