先定事件名,别让 message 承担结构
【摘要】 一、先定事件名,别让 message 承担结构 最常见的问题是把动作塞进 message : "User 123 login failed from 10.0.0.1" 。这种日志一旦上了量,只能靠正则去捞。正确做法是固
一、先定事件名,别让 message 承担结构
最常见的问题是把动作塞进 message:"User 123 login failed from 10.0.0.1"。这种日志一旦上了量,只能靠正则去捞。正确做法是固定一个 event 字段,取值来自有限枚举,比如 user.login.failed、order.payment.timeout,用点号分层级方便前缀查询;message 只留给人读,机器永远查 event。字段名统一 snake_case,并且直接对齐 OpenTelemetry 语义约定(http.request.method、http.response.status_code、db.system),不要自创 method、httpMethod、verb 三套写法,否则后面写查询的人会很痛苦。
二、每条日志都要有的关联字段
这几个字段不是锦上添花,而是能完成检索和关联的最低要求:
timestamp:RFC3339 带毫秒和时区,不要用本地时间字符串,跨时区排查会直接错位。level:只允许debug/info/warn/error/fatal五个值,别写WARNING或ERR,否则告警规则永远漏。service、env、version:容器里version用镜像 tag 或 git sha,出问题第一眼就能确认是不是发版引起的。trace_id、span_id:从上下文透传,这是日志和链路互跳的唯一钥匙,缺了它日志就是孤岛。
三、业务字段:类型、单位、扁平化
结构化日志的价值在于能聚合,而聚合的前提是类型正确:
- 数值就是数值:
"duration_ms": 123,不要"cost": "123ms",否则算不了 P99。 - 单位写进字段名:
_ms、_bytes、_count,省掉"这个 timeout 是秒还是毫秒"的争论。 - 能扁平就别嵌套,
user.id就写user_id;嵌套超过两层,在 Kibana 里展开字段很麻烦。 - 布尔用
true,空值用null,不要"true"和""。
四、三类字段不要进日志
- 高基数键:把
user_id、order_id当索引字段会让 mapping 数量激增,ES 默认index.mapping.total_fields.limit是 1000,超了写入直接报错。这类字段设"index": false只存不索引;动态 key({"user_123": true})属于严格禁止的写法。 - 敏感信息:密码、token、身份证、完整手机号,统一在序列化层做脱敏,不要指望每个调用点都记得处理。
- 大对象:整个 request/response body 别直接打,超过 1KB 就截断,或者落到对象存储只留引用。
五、用代码约束字段,而不是靠自觉
用结构体或 DTO 定义日志事件,禁止 map[string]any 随手塞,字段名用常量集中管理,改名字时编译器会帮你找全。CI 里加一条低成本规则:解析样例日志,校验必填字段是否存在、level 是否在枚举内、duration_ms 是不是整数。采样按 trace 一致采样,同一条 trace 的日志要么都留要么都不留,error 级别全量保留,否则链路里永远缺一半,排障时最难受。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)