I am working with python custom log - TRACE is custom log level in below code.
With default logger, its working fine
But when I change it for structlog it is giving error.
structlog not able to identify TRACE in below code.
It seems that structlog doesn't support custom log levels ?
Already tried workaround mentioned https://github.com/hynek/structlog/issues/47
ie
structlog.stdlib.TRACE = TRACE = 5
structlog.stdlib._NAME_TO_LEVEL['trace'] = TRACE
But it is not working
TRACE = 19
logging.addLevelName(TRACE, "TRACE")
logging.basicConfig(
level=os.environ.get("LOGLEVEL", "TRACE"),
format=os.environ.get("LOGFORMAT", '%(levelname)-8s= %(asctime)-15s = %(message)s'))
structlog.configure(
processors=[
structlog.stdlib.filter_by_level,
structlog.stdlib.add_logger_name,
structlog.stdlib.add_log_level,
structlog.stdlib.PositionalArgumentsFormatter(),
structlog.processors.StackInfoRenderer(),
structlog.processors.format_exc_info,
structlog.processors.UnicodeDecoder(),
structlog.stdlib.render_to_log_kwargs,
],
context_class=dict,
logger_factory=structlog.stdlib.LoggerFactory(),
wrapper_class=structlog.stdlib.BoundLogger,
cache_logger_on_first_use=True,
)
#LOG = logging.getLogger() ->> Working fine
LOG = structlog.getLogger()
LOG.log(TRACE, "hello") ->> error on this line
LOG.info("testing")
Currently there is no official way currently as you probably have gathered from the related issue that you commented on .
You should be able to circumvent that for now by monkeypatching structlog.stdlib._NAME_TO_LEVEL
.
It is possible to create a custom level, but not very easy.
You need to remember to not only change structlog.stdlib._NAME_TO_LEVEL
, but also structlog.stdlib._LEVEL_TO_NAME
.
Then, you need to add a trace
method to at least structlog.stdlib._FixedFindCallerLogger
(if you add a trace
method to structlog.stdlib.BoundLogger
as well you can then call LOG.trace
, which is nice).
This code should work:
import logging
import os
import structlog
TRACE = 19
structlog.stdlib.TRACE = TRACE = 5 # this overrides the 19 above with a 5, is that right?
structlog.stdlib._NAME_TO_LEVEL['trace'] = TRACE
structlog.stdlib._LEVEL_TO_NAME[TRACE] = 'trace'
def trace(self, msg, *args, **kw):
return self.log(TRACE, msg, *args, **kw)
structlog.stdlib._FixedFindCallerLogger.trace = trace
structlog.stdlib.BoundLogger.trace = trace
logging.basicConfig(
level=int(os.environ.get("LOGLEVEL", TRACE)),
format=os.environ.get("LOGFORMAT", '%(levelname)-8s= %(asctime)-15s = %(message)s'))
structlog.configure(
processors=[
structlog.stdlib.filter_by_level,
structlog.stdlib.add_logger_name,
structlog.stdlib.add_log_level,
structlog.stdlib.PositionalArgumentsFormatter(),
structlog.processors.StackInfoRenderer(),
structlog.processors.format_exc_info,
structlog.processors.UnicodeDecoder(),
structlog.stdlib.render_to_log_kwargs,
],
context_class=dict,
logger_factory=structlog.stdlib.LoggerFactory(),
wrapper_class=structlog.stdlib.BoundLogger,
cache_logger_on_first_use=True,
)
logging.addLevelName(TRACE, "TRACE")
LOG = structlog.getLogger()
LOG.trace('test')
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.