[英]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.