python - 从配置文件自定义 python 结构化 (json) 日志记录中的键值

标签 python json python-3.x logging

我必须将 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/

相关文章:

python - 如何将输入值与mysql数据库进行比较,没有匹配数据时自动添加 '0'和 '1'

python - 有没有办法在 PyCharm 调试器中查看变量内的最后 100 个元素?

javascript - 如何在 react 中进行双json外部调用

c# - 反序列化 JSON 时需要忽略 NULL 值

python - 对列表中的第一项进行优先排序(随机和概率分布)

ruby - 为什么我的 ruby​​ 类没有转换为 json?

python - 使用元类时出现 Pylint 错误

python-3.x - Pandas中基于groupby的数据透视表

python - 以 unicode 字符串为名称的 namedtuple

python - 如何在迭代 pandas 数据框时提高性能?