用 structlog 包装 "py.warnings" 记录器以添加处理器
Wrap "py.warnings" logger with structlog to add processors
我有一个自定义记录器,包括处理器、处理程序等。我想包装警告使用的“py.warnings”记录器,以便我的处理器是 'injected'。但是,运行 以下代码不会对打印到控制台的警告进行任何更改。
import logging
import structlog
import warnings
structlog.wrap_logger(
logging.getLogger("py.warnings"),
# processors etc. ...
)
warnings.warn("abc")
这是行不通的。 structlog.wrap_logger()
是专门制作的,因此它 没有 副作用,您必须使用它的 return 值进行日志记录,才能使用 structlog。
您将必须配置日志记录以使用记录在案的 structlog here。简而言之,structlog 带有一个日志样式格式化程序,允许您使用 structlog 格式化所有具有专用处理器链的日志条目。
我也有同样的要求,就这样做了,享受吧!
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)
main.py
if __name__ == "__main__":
my_warnings.set_deprecation_warnings()
#... your code
我有一个自定义记录器,包括处理器、处理程序等。我想包装警告使用的“py.warnings”记录器,以便我的处理器是 'injected'。但是,运行 以下代码不会对打印到控制台的警告进行任何更改。
import logging
import structlog
import warnings
structlog.wrap_logger(
logging.getLogger("py.warnings"),
# processors etc. ...
)
warnings.warn("abc")
这是行不通的。 structlog.wrap_logger()
是专门制作的,因此它 没有 副作用,您必须使用它的 return 值进行日志记录,才能使用 structlog。
您将必须配置日志记录以使用记录在案的 structlog here。简而言之,structlog 带有一个日志样式格式化程序,允许您使用 structlog 格式化所有具有专用处理器链的日志条目。
我也有同样的要求,就这样做了,享受吧!
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)
main.py
if __name__ == "__main__":
my_warnings.set_deprecation_warnings()
#... your code