Python 结构化日志入门:先让日志能被查,再谈好看

举报
yd_257841283 发表于 2026/11/01 06:10:59 2026/11/01
【摘要】 出问题时去翻日志,最怕的不是没有日志,而是日志只有人能看懂、机器很难查。一句“订单处理失败了”,既没说清是哪个订单,也没说清失败在哪一步,最后只能靠猜。结构化日志要解决的,就是把每条日志变成一条结构固定的记录:字段相同、含义相同,事后可以按字段过滤、统计和关联。先定字段,再写日志。一条可用的结构化日志,至少要有时间、级别、服务名、事件名和消息。时间建议用带时区的 ISO 格式,避免本地时间在...

出问题时去翻日志,最怕的不是没有日志,而是日志只有人能看懂、机器很难查。一句“订单处理失败了”,既没说清是哪个订单,也没说清失败在哪一步,最后只能靠猜。结构化日志要解决的,就是把每条日志变成一条结构固定的记录:字段相同、含义相同,事后可以按字段过滤、统计和关联。

先定字段,再写日志。

一条可用的结构化日志,至少要有时间、级别、服务名、事件名和消息。时间建议用带时区的 ISO 格式,避免本地时间在跨时区排查时产生歧义。级别不要滥用:INFO 记录正常的关键步骤,WARNING 记录可恢复的异常,ERROR 只留给需要人介入的失败。事件名要用固定动词,比如 order_created、payment_failed,而不是每次换一种说法。

再加两个能把一次请求串起来的字段:request_id 和 user_id。request_id 由入口生成并在调用链中透传,这样前端报错、网关日志和后端日志就能对上同一条链路。user_id 则方便确认影响范围,但要注意只记标识,不要把密码、令牌、完整手机号或身份证号写进日志。

在 Python 里,不需要一开始就引入重型框架。标准库 logging 加一个把记录转成 JSON 的 Formatter 就够入门:

import json, logging

class JsonFormatter(logging.Formatter):
    def format(self, record):
        return json.dumps({
            "time": self.formatTime(record),
            "level": record.levelname,
            "logger": record.name,
            "event": getattr(record, "event", ""),
            "message": record.getMessage(),
        }, ensure_ascii=False)

handler = logging.StreamHandler()
handler.setFormatter(JsonFormatter())
logger = logging.getLogger("order")
logger.addHandler(handler)
logger.setLevel(logging.INFO)
logger.info("订单已创建", extra={"event": "order_created"})

这样输出的每行都是一个 JSON 对象,可以直接被日志平台解析。排查时不再用肉眼逐行翻,而是直接查 event=payment_failed,再按 request_id 看同一请求的完整链路。

还有三个容易被忽略的细节。第一,不要在循环里打高频 DEBUG 日志,量一大就会把真正有用的信息淹没,也会拖慢服务。第二,日志要轮转和设上限,避免磁盘被打满;这是运维成本,不是可选项。第三,开发环境可以保留更易读的格式,但生产环境尽量统一为 JSON,不要让两种格式混在同一个采集链路里。

最后给自己一个自查清单:这条日志离开上下文还能看懂吗?能按一个字段过滤吗?能和上下游的日志关联吗?三个问题都答 yes,才算合格。结构化日志不是为了好看,而是为了在出问题时少猜一次、多快一步。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。