Reputation: 146
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
i.e
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")
Upvotes: 3
Views: 3420
Reputation: 3053
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')
Upvotes: 3
Reputation: 4126
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
.
Upvotes: 0