Go应用应输出结构化JSON日志至stdout,由Fluentd或Logstash采集并注入Kubernetes元数据后发往ES等后端;禁用文件轮转与敏感信息输出,统一格式与采集入口是关键。
Go 语言本身不直接处理日志收集或转发,但作为容器化服务(如微服务、CLI 工具、后台任务)的主力开发语言,它需要与日志采集系统(如 Fluentd、Logstash)良好协作。关键在于:让 Go 程序以结构化、可解析的方式输出日志,并适配标准输入/文件路径等采集入口。
避免使用 fmt.Println 或未格式化的 log.Printf。推荐使用支持 JSON 输出的日志库,便于 Fluentd/Logstash 解析。
level、time、service、trace_id(如有)、message
os.Stdout(而非文件),由容器运行时(Docker / containerd)捕获为 stdout/stderr 流示例(logrus + JSON):
log := logrus.New()
log.SetFormatter(&logrus.JSONFormatter{})
log.SetOutput(os.Stdout) // 关键:输出到 stdout
log.WithFields(logrus.Fields{"user_id": 123}).Info("user login succeeded")Fluentd 常以 DaemonSet 方式部署在 Kubernetes 节点,或作为独立容器监听 Docker 日志目录。
json-file,日志存于 /var/lib/docker/containers//-json.log
使用 tail 插件读取这些 JSON 文件parser 解析原始 JSON,并添加 Kubernetes 元信息(如 namespace、pod_name) 补充 service 标签、重命名字段、过滤 debug 日志等 将日志发往 Elasticsearch、Kafka 或 S3简化的 fluent.conf 片段:
@type tail path /var/lib/docker/containers/**/*-json.log pos_file /var/log/fluentd-containers.log.pos tag kubernetes.* format json time_key time time_format %Y-%m-%dT%H:%M:%S.%NZ
@type kubernetes_metadata
@type elasticsearch host elasticsearch port 9200 logstash_format true logstash_prefix myapp
若选择 Logstash,通常用 docker logs --since 或 file 输入插件读取容器日志文件,逻辑类似 Fluentd。
json 编解码器解析 Go 输出的 JSON 日志dissect 或 grok 处理非 JSON 日志(不推荐,应优先统一为 JSON)kubernetes 插件注入 Pod 元数据(需运行在集群内)
icsearch 时建议开启 pipeline 进行字段标准化(如统一时间字段名、level 映射)container_name 和 pod_name 替代硬编码服务名,方便关联追踪docker logs 确认输出是否为合法 JSON,无控制字符或换行截断基本上就这些。Go 日志本身轻量,难点在对接和一致性 —— 统一格式、统一采集入口、统一元数据补充,比选哪个工具更重要。