应避免go框架直连es同步日志,而用logrus/zap写本地json文件,再由filebeat或logstash采集;需规范时间格式、错误处理、字段命名及filebeat/logstash配置以确保日志准确入es并可追踪。

别用 Go 框架直连 Elasticsearch 同步日志和指标——这会让 HTTP 请求变慢、goroutine 积压、ES 集群抖动,而且一出错就丢数据。
logrus/zap 输出 JSON 到文件,不是发到网络
Go 进程只该做一件事:把结构化日志快速写进本地文件。所有“同步”动作都该交给 Filebeat 或 Logstash。
-
logrus.JSONFormatter必须显式设置TimestampFormat,否则毫秒精度丢失(如"2006-01-02T15:04:05Z"不够,得用"2006-01-02T15:04:05.000Z07:00") - 用
logrus.WithError(err),别写logrus.WithField("error", err)——err是接口,JSON 序列化后为空对象{} - zap 推荐用
zapcore.NewJSONEncoder自定义EncoderConfig,把level字段设为小写,和 Filebeat 默认解析习惯对齐 - 关键字段必须固定:至少含
service、env、level、ts(ISO8601)、trace_id(如有)、error.stack(错误时)
Filebeat 配置里三处不检查,日志就进不了 ES
路径权限、JSON 解析开关、输出目标端口,这三个地方错一个,filebeat logs --debug 看不到错误,但 Kibana 里永远空。
-
paths必须是绝对路径,且filebeat进程用户(常为root或filebeat)有读权限;./logs/*.log在 systemd 服务里常因工作目录不对而失效 - 启用 JSON 解析必须同时加:
json.keys_under_root: true和json.overwrite_keys: true,否则全部字段塞进message字符串里 -
output.elasticsearch.hosts写["http://localhost:9200"]前,确认 ES 的network.host允许该地址访问(默认只绑127.0.0.1),或改用output.logstash.hosts并确保 Logstash 的beatsinput 监听对应端口(如5044)
Logstash filter 中 json { source => "message" } 会吃掉 host/timestamp
这不是 bug,是设计:Logstash 默认把解析出的字段挂到顶层,但 host、@timestamp 这些元字段原本就在 event 根层,会被覆盖。
- 加
remove_field => ["message"]清掉原始字符串,避免冗余和字段冲突 - 如果需要保留原始
host或打上采集节点名,用mutate { add_field => { "ingest_host" => "%{host}" } }显式重命名 - 时间戳字段若名为
ts,用date { match => ["ts", "ISO8601"] target => "@timestamp" }覆盖默认时间,否则 Kibana 时间轴不准
真正难的不是配置项本身,而是让 Go 日志的 trace_id、HTTP 中间件的 request_id、Prometheus metrics 的 label 三者能跨系统对齐——这要求你在中间件生成 ID 时就注入日志上下文,而不是等 log 函数里临时拼。漏掉这一环,Kibana 查到的错误日志就永远没法下钻到对应请求的指标曲线。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











