Tengo este código que funciona bien para mí.
import logging import logging.handlers logger = None def create_logger(): global logger logger = logging.getLogger('Logger') logger.setLevel(logging.DEBUG) handler = logging.handlers.RotatingFileHandler("C:/Users/user/Desktop/info.log", maxBytes=1000000, backupCount=20) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) logger.addHandler(handler) create_logger() logger.info("Text info") logger.debug("Text debug") logger.warning("Text warning") logger.error("Text error") logger.critical("Text critical")
Y la salida se ve muy bien:
2017-12-19 15: 06: 43,021 – Registrador – INFO – Información de texto
2017-12-19 15: 06: 43,021 – Registrador – DEBUG – Depuración de texto
2017-12-19 15: 06: 43,022 – Registrador – ADVERTENCIA – Advertencia de texto
2017-12-19 15: 06: 43,022 – Registrador – ERROR – Error de texto
2017-12-19 15: 06: 43,022 – Registrador – CRÍTICO – Texto crítico
Bueno, quiero agregar un nuevo nivel de registro como este:
logger.message("Text message")
Y la salida debería ser así.
2017-12-19 15: 06: 43,022 – Registrador – MENSAJE – Mensaje de texto
Gracias
De la documentación de registro (énfasis añadido):
Definir sus propios niveles es posible, pero no debería ser necesario , ya que los niveles existentes se han elegido sobre la base de la experiencia práctica. Sin embargo, si está convencido de que necesita niveles personalizados, debe tener mucho cuidado al hacer esto, y posiblemente sea una muy mala idea definir niveles personalizados si está desarrollando una biblioteca . Esto se debe a que si varios autores de bibliotecas definen sus propios niveles personalizados, existe la posibilidad de que el registro de salida de dichas bibliotecas múltiples utilizadas juntas sea difícil de controlar y / o interpretar por parte del desarrollador que usa, porque un valor numérico dado puede significar cosas diferentes Para diferentes bibliotecas.
Una visión general de los niveles de registro predeterminados:
Pero si aún así lo desea, puede crear su propio nivel de registro:
En el módulo de logging
, _levelToName
y _nameToLevel
son asignaciones entre los nombres y niveles de registro. En lugar de agregarlos manualmente, la función addLevelName()
hace esto por usted.
Aquí, se agrega un nuevo nivel de registro llamado MESSAGE con el nivel de registro 25 :
import logging # Define MESSAGE log level MESSAGE = 25 # "Register" new loggin level logging.addLevelName(MESSAGE, 'MESSAGE') # addLevelName(25, 'MESSAGE') # Verify assert logging.getLevelName(MESSAGE) == 'MESSAGE'
Si no desea crear su propia clase de registrador pero aún desea registrar otros niveles de registro, puede usar el Logger.log(level, msg)
en los registradores tradicionales:
logging.log(MESSAGE, 'This is a message')
def message(self, msg, *args, **kwargs): if self.isEnabledFor(MESSAGE): self._log(MESSAGE, msg, args, **kwargs)
Haga que el message()
funcione en el logging
:
logging.message = message # or setattr(logging, 'message', message)
Haga que el message()
funcione en el registrador:
logging.Logger.message = message # or setattr(logging.Logger, 'message', message)
Puede crear su propia clase de registrador para hacer un método de message(msg)
, que se usará de manera similar a los demás (por ejemplo, info(msg)
, warning(msg)
, etc.)
En el siguiente ejemplo, se crea un nuevo registrador con un método de message(msg)
para registrar MENSAJE :
class MyLogger(logging.Logger): def message(self, msg, *args, **kwargs): if self.isEnabledFor(MESSAGE): self._log(MESSAGE, msg, args, **kwargs)
No estoy seguro de cuál es la mejor manera de hacer que funcione con logging.getLogger(name)
, pero a continuación hay dos enfoques. Árbitro. Comentarios, creo que el primer enfoque es mejor:
O bien, haga que el nuevo registrador sea la clase de registro predeterminada, lo que significa que las nuevas instancias del registrador serán de la clase MyLogger
lugar de la clase de logging.Logger
predeterminado:
logging.setLoggerClass(MyLogger) logger = logging.getLogger('A new logger name') logger.message('This seems to work') assert isInstance(logger, MyLogger)
O simplemente loggerDict
una instancia del registrador y agréguela al loggerDict
en la instancia de logging.Manager
activo. logging.Manager
( EDIT : no se recomienda, vea los comentarios):
my_logger = MyLogger('Foo') logging.Logger.manager.loggerDict['Foo'] = my_logger logger = logging.getLogger('Foo') logger.message('This is the same instance as my_logger') assert logger is my_logger
# Use the new logger class logger.warning('Custom log levels might be a bad idea') logger.message('Here is a message') # Log with custom log level: logger.log(MESSAGE, 'This is a message')
Esto supone que MESSAGE
está predefinido como un valor numérico entero que representa el nivel de registro. (Por ejemplo, 25 como se mencionó anteriormente)