1

我有一个自定义记录器,包括处理器、处理程序等。我想包装我理解的警告使用的“py.warnings”记录器,以便我的处理器被“注入”。但是,运行以下代码不会更改打印到控制台的警告。


import logging
import structlog
import warnings

structlog.wrap_logger(
    logging.getLogger("py.warnings"),
    # processors etc. ...
)

warnings.warn("abc")
4

2 回答 2

1

这不会像这样工作。structlog.wrap_logger()是专门制作的,因此它没有副作用,您必须使用它的返回值进行日志记录,才能使用 structlog。

您必须配置日志记录以使用此处记录的 structlog 。简而言之,structlog 带有一个日志样式格式化程序,它允许您使用 structlog 通过专用处理器链格式化所有日志条目。

于 2021-05-19T10:46:56.033 回答
1

我有同样的要求,就这样做了,享受吧!

my_warnings.py

import logging
import warnings
from typing import Final, Union, Type

import structlog

from structlog.stdlib import _SENTINEL

WARNINGS_LOGGER_NAME: Final = "py.warnings"
FORMATTER: Final = structlog.stdlib.ProcessorFormatter(processor=YourProcessor(), foreign_pre_chain=[your_chain...])
FORMATTER.logger = logging.getLogger(WARNINGS_LOGGER_NAME)
old_format_warning = warnings.formatwarning


class MyPendingDeprecationWarning(UserWarning):
    pass



MY_WARNING_CATEGORIES = [MyPendingDeprecationWarning]


def _format_warnings(message, category, filename, lineno, line=None):
    if category not in MY_WARNING_CATEGORIES:
        return old_format_warning(message, category, filename, lineno, line)
    new_message = f"{category.__name__}: {message}"
    record = logging.LogRecord(
        FORMATTER.logger.name,
        pathname=filename,
        lineno=lineno,
        msg=new_message,
        args=(),
        exc_info=(category, category(), None),
        level=logging.WARNING,
    )
    record._logger = _SENTINEL
    record._name = _SENTINEL

    return FORMATTER.format(record)


def set_deprecation_warnings():
    warnings.formatwarning = _format_warnings
    logging.captureWarnings(True)

主文件

if __name__ == "__main__":
    my_warnings.set_deprecation_warnings()
    #... your code
于 2021-10-31T16:41:39.150 回答