简体   繁体   中英

Custom log level not working with structlog

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM