簡體   English   中英

Python 日志記錄 - 將 addifinal 字段添加到自定義格式化程序

[英]Python Logging - Add addifinal fields to Custom Formatter

我有以下用於 Logger 的格式化程序類,用於我們公司的庫中:

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,
            }
        )

我試圖添加這樣的自定義字段:

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

結果:

{"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 對象,並且這本身就無法擴展它的構建方式。

這就是我想要的:

{"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"}

重要提示:理想情況下,這將像這樣工作:

logger.info("test", extra={"custom_attribute": "my-attr"}

您面臨的問題是,您成功地將屬性添加到記錄中,但您的格式化程序只是忽略了它。 沒有辦法解決這個問題,只能更改或替換您正在使用的 CustomFormatter。 一個可能的解決方案可能如下所示:

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參數完全符合您的要求。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM