Пользовательский уровень журнала не работает с structlog - PullRequest
0 голосов
/ 03 февраля 2019

Я работаю с настраиваемым журналом Python - TRACE - это настраиваемый уровень журнала в приведенном ниже коде.

С регистратором по умолчанию, он работает нормально

Но когда я изменяю его на structlog, он выдает ошибку.

structlog не может идентифицировать TRACE в приведенном ниже коде.

Похоже, что structlog не поддерживает настраиваемые уровни журнала?

Уже упомянутый обходной путь упоминается https://github.com/hynek/structlog/issues/47

т.е.

    structlog.stdlib.TRACE = TRACE = 5
    structlog.stdlib._NAME_TO_LEVEL['trace'] = TRACE

Но этоне работает

    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")

Ответы [ 2 ]

0 голосов
/ 06 июня 2019

Можно создать пользовательский уровень, но не очень просто.

Вам нужно помнить, чтобы не только изменить structlog.stdlib._NAME_TO_LEVEL, но и structlog.stdlib._LEVEL_TO_NAME.

Тогда вынужно добавить метод trace как минимум к structlog.stdlib._FixedFindCallerLogger (если вы добавите метод trace к structlog.stdlib.BoundLogger, вы также можете вызвать LOG.trace, что неплохо).

Этот код должен работать:

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')
0 голосов
/ 04 февраля 2019

В настоящее время не существует официального способа, так как вы, вероятно, поняли из связанной проблемы, что вы прокомментировали .

Вы должны быть в состоянии обойти это сейчас, используя monkeypatching structlog.stdlib._NAME_TO_LEVEL.

...