我必须将 python 作业的日志输出为结构化 (json) 格式,以便我们的下游 datadog 代理获取它们。至关重要的是,我对特定日志字段的命名有要求,例如必须有一个无法调用的 timestamp
字段,例如asctime
。因此,所需的日志如下所示:
{"timestamp": "2022-11-10 00:28:58,557", "name": "__main__", "level": "INFO", "message": "my message"}
我可以使用以下代码得到非常接近的结果:
import logging.config
from pythonjsonlogger import jsonlogger
logging.config.fileConfig("logging_config.ini", disable_existing_loggers=False)
logger = logging.getLogger(__name__)
logger.info("my message")
引用以下logging_config.ini
文件:
[loggers]
keys = root
[handlers]
keys = consoleHandler
[formatters]
keys=json
[logger_root]
level=DEBUG
handlers=consoleHandler
[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=json
[formatter_json]
class = pythonjsonlogger.jsonlogger.JsonFormatter
format=%(asctime)s %(name)s - %(levelname)s:%(message)s
...但是,这不允许输出日志 json 对象中的键具有灵活性。例如我的时间戳对象称为“asctime”,如下所示:
{"asctime": "2022-11-10 00:28:58,557", "name": "__main__", "levelname": "INFO", "message": "my message"}
我仍然想要该 asctime
值(例如 2022-11-10 00:28:58,557),但需要通过名为“timestamp”而不是“asctime”的键引用它。如果可能的话,我强烈希望有一个解决方案能够使用相对最少的额外 python 代码来适应 logging.config.ini
文件(或者可能是 yaml 日志配置文件)。
我也尝试过this alternative python json logging library我认为它提供了非常简单和优雅的代码,但不幸的是,当我尝试使用它时,我根本没有得到我的日志语句输出......
最佳答案
您需要有少量的 Python 代码,例如
# in mymodule.py, say
class CustomJsonFormatter(jsonlogger.JsonFormatter):
def add_fields(self, log_record, record, message_dict):
super(CustomJsonFormatter, self).add_fields(log_record, record, message_dict)
log_record['timestamp'] = datetime.datetime.fromtimestamp(record.created).strftime('%Y-%m-%d %H:%M:%S') + f',{int(record.msecs)}'
然后更改配置以引用它:
[formatter_json]
class = mymodule.CustomJsonFormatter
format=%(timestamp)s %(name)s - %(levelname)s:%(message)s
然后会输出例如
{"timestamp": "2022-11-10 11:37:25,153", "name": "root", "levelname": "DEBUG", "message": "foo"}
关于python - 从配置文件自定义 python 结构化 (json) 日志记录中的键值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74385061/