首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python日志记录-向自定义格式化程序添加附加的最终字段

Python日志记录-向自定义格式化程序添加附加的最终字段
EN

Stack Overflow用户
提问于 2022-06-29 08:44:12
回答 1查看 42关注 0票数 0

我为Logger提供了以下格式化程序类,用于我们公司的libary中:

代码语言:javascript
复制
import json
import logging
from typing import Optional


class CustomFormatter(logging.Formatter):

    def __init__(
        self,
        fmt: Optional[str] = "%(asctime)s",
        datefmt: Optional[str] = None,
        style: Optional[str] = "%",
        confidentiality: Optional[str] = "C3",
    ) -> None:
        self.confidentiality = confidentiality
        super().__init__(fmt=fmt, datefmt=datefmt, style=style)

    def formatMessage(self, record: logging.LogRecord, *args, **kwargs) -> str:
        super().formatMessage(record)
        return json.dumps(
            {
                "asctime": record.asctime,
                "level": record.levelname,
                "name": record.name,
                "message": record.message,
                "timeMillis": int(record.created * 1000),
                "pathName": record.pathname,
                "funcName": record.funcName,
                "lineNumber": record.lineno,
                "confidentiality": self.confidentiality,
            }
        )

我尝试添加这样的自定义字段:

代码语言:javascript
复制
old_factory = logging.getLogRecordFactory()

def record_factory(*args, **kwargs):
    record = old_factory(*args, **kwargs)
    record.custom_attribute = "my-attr"
    return record

logging.setLogRecordFactory(record_factory)

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logger_handler = logging.StreamHandler()
logger_handler.setFormatter(CustomFormatter())
logger.addHandler(logger_handler)

logger.info("Ich bin ein Test")

结果:

代码语言:javascript
复制
{"asctime": "2022-06-29 10:40:22,869", "level": "INFO", "name": "root", "message": "test", "timeMillis": 1656492022869, "pathName": "C:\\Users\\xcg5847\\Desktop\\loggingnew\\test.py", "funcName": "<module>", "lineNumber": 15, "
confidentiality": "C3"}

这是没有增加的。我猜问题在于,格式化程序总是返回相同的json对象,而这本身是不可扩展的,就其构建方式而言。

这就是我想要的:

代码语言:javascript
复制
{"asctime": "2022-06-29 10:40:22,869", "level": "INFO", "name": "root", "message": "test", "timeMillis": 1656492022869, "pathName": "C:\\Users\\xcg5847\\Desktop\\loggingnew\\test.py", "funcName": "<module>", "lineNumber": 15, "
confidentiality": "C3", "custom_attribute": "my-attr"}

的重要性:理想情况下,这样的工作方式是:

代码语言:javascript
复制
logger.info("test", extra={"custom_attribute": "my-attr"}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-06-29 09:12:06

您所面临的问题是,您成功地将属性添加到记录中,但是格式化程序却忽略了它。除了更改或替换正在使用的CustomFormatter之外,没有其他办法。可能的解决方案如下所示:

代码语言:javascript
复制
class CustomFormatterExtra(CustomFormatter):
    custom_name = 'custom_attribute'

    def formatMessage(self, record, *args, **kwargs):
        json_str = super().formatMessage(record, *args, **kwargs)
        if hasattr(record, self.custom_name):
            json_dict = json.loads(json_str)
            json_dict[self.custom_name] = getattr(record, self.custom_name)
            json_str = json.dumps(json_dict)
        return json_str


logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logger_handler = logging.StreamHandler()
logger_handler.setFormatter(CustomFormatterExtra())
logger.addHandler(logger_handler)

logger.info("Ich bin ein Test", extra={'custom_attribute':123})
CustomFormatterExtra.custom_name = 'different_attribute'
logger.info("Ich bin ein Test", extra={'different_attribute':123})

注意,这不需要定制的LogRecord工厂。extra param做的和你的一模一样。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72798390

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档