Go微服务中需用zap+OpenTelemetry在中间件提取trace_id/span_id并作为结构化字段注入日志,确保单行JSON输出、Filebeat启用keys_under_root、ES中trace_id映射为keyword类型。
Go 微服务里怎么让日志带上 trace_id 和 span_id
不加 trace 上下文,ELK 里查日志就是一堆散点,根本串不起来。Go 标准库
不带上下文,必须用支持 OpenTracing 或 OpenTelemetry 的日志库,或者手动把 trace 信息塞进日志字段。
推荐用
(OTel 日志提案已进入实验阶段)或更现实的方案:用
+
注入 context
在 HTTP 中间件或 gRPC UnaryInterceptor 里从
提取
,拿到
和
把这两个 ID 作为结构化字段传给
,比如
别用字符串拼接日志(如
),会丢结构、难过滤、占空间
Logstash 或 Filebeat 怎么识别 Go 服务输出的 JSON 日志
Go 服务输出的 JSON 日志如果没对齐 Logstash / Filebeat 的期待格式,就会被当纯文本吞掉,
乱、
变成嵌套字符串、甚至整条日志进
字段里出不来。
确保 Go 日志库输出的是「单行 JSON」——每条日志严格一个 JSON object,不能换行、不能有前导空格,否则 Filebeat 的
解码器会失败
Logstash 里用
,但前提是
字段确实是合法 JSON;如果原始日志已经由 Filebeat 解析过,就别重复解析,直接用
提取字段
Filebeat 配置中必须启用
和
,否则 trace_id 会藏在
下,Kibana 里搜不到
测试方法:用
+
看实际发出去的 event 结构是否含平级
字段
ELK 里 trace_id 搜不到?检查这三个地方
Kibana 里输入
没结果,大概率不是 Go 发得不对,而是索引映射或查询方式卡住了。
go语言参考手册 中文CHM版
Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。本文给大家带来Go参考手册,需要的可以来下载! Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本。现在Go的开发已经是完全开放的,并且拥有一个活跃的社区。 Go 语言特色 简洁、快速、安全 并行、有趣、开源 内存管理、v数组安全、编译
下载
Elasticsearch 索引模板里,
字段类型必须是
,不是
—— 否则会被分词,精确匹配失效
Kibana 查询语言默认走全文检索,要查精确值得加引号,或改用
(如果字段映射没设
就没这个子字段)
Logstash 如果用了
filter 做时间解析,但 Go 日志里时间字段名不是
或
,会导致事件时间戳为 0,被 ES 丢进
索引或拒收
为什么 Span 之间的时间差在 Kibana 里对不上
同一个 trace 下不同服务的日志时间戳差几秒,不是网络延迟问题,而是各服务本地时钟没同步,或者日志时间字段没统一用 trace 开始时间做基准。
立即学习
“
go语言免费学习笔记(深入)
”;
Go 服务里别用
打日志时间,要用 span 的
记录起点,再基于它算相对时间(如
)
所有服务必须 NTP 同步,误差控制在 50ms 内,否则 span.duration 在 UI 上错位严重
ES 索引的
字段应来自日志中的
字段(ISO8601 格式),而不是 Logstash 接收到事件的时间 —— 后者反映的是日志落地延迟,不是业务发生时刻
事情说清了就结束。最常漏的是 Filebeat 的
和 ES 字段 mapping 类型,调通前先抓一条原始日志,从 Filebeat 输出一直看到 Kibana Discover 里的字段层级,比看文档快得多。
loggo.opentelemetry.io/otel/logzapopentelemetry-gocontext.Contexttrace.SpanFromContext(ctx)span.SpanContext().TraceID()span.SpanContext().SpanID()zap.Logger.With()logger.With(zap.String("trace_id", tid.String()), zap.String("span_id", sid.String()))fmt.Sprintf("trace:%s %s", tid, msg)@timestamptrace_idmessagejsonfilter { json { source => "message" } }messageprocessorsjson.keys_under_root: truejson.overwrite_keys: truejson.trace_idfilebeat test outputfilebeat -e -d "publish"trace_idtrace_id: "0123456789abcdef0123456789abcdef"trace_idkeywordtexttrace_id.keyword: "..."fields: { keyword: { type: keyword } }date@timestamptime.kibanatime.Now()StartSpanOptions{StartTime: ...}elapsed_ms@timestamptimejson.keys_under_root