在云原生架构中,日志系统是 observability(可观测性)的三大支柱之一。日志采集不仅需要标准化,还需要结构化与易于接入采集链路(如 Fluent Bit、Loki、ELK)。Golang 原生支持高性能日志打印,是构建云原生日志模块的理想选择。
本篇将介绍如何用 Golang 构建结构化日志模块,并部署到 Kubernetes 中配合日志收集器进行集中处理。
1. 日志采集模式概述
在 Kubernetes 中,常见的日志采集流程为:
- 应用将日志输出到
stdout
/stderr
- 容器运行时将日志持久化到文件
- 日志代理(如 Fluent Bit)读取文件并转发至后端(如 Elasticsearch、Loki)
因此,日志应尽量打印至控制台并保持结构化(JSON 格式)以利采集与索引。
2. 结构化日志库选择
推荐使用以下结构化日志库:
uber-go/zap
(性能优异,生产可用)sirupsen/logrus
(语法友好,学习曲线低)
示例使用 zap
:
go get go.uber.org/zap
3. 日志模块实现
package logger
import (
"go.uber.org/zap"
)
var Log *zap.Logger
func InitLogger() {
cfg := zap.NewProductionConfig()
cfg.OutputPaths = []string{"stdout"}
cfg.ErrorOutputPaths = []string{"stderr"}
cfg.Encoding = "json"
logger, err := cfg.Build()
if err != nil {
panic(err)
}
Log = logger
}
在主程序中调用:
func main() {
logger.InitLogger()
logger.Log.Info("service starting", zap.String("version", "v1.0.0"))
}
4. 示例日志输出格式(JSON)
{
"level": "info",
"ts": 1718946000.123,
"msg": "service starting",
"version": "v1.0.0"
}
这类日志格式可被 Fluent Bit、Loki、Logstash 等组件自动识别为结构化字段,便于过滤与查询。
5. 在 Kubernetes 中采集日志
以 Fluent Bit 为例,可通过如下配置采集并过滤日志:
[INPUT]
Name tail
Path /var/log/containers/*.log
Parser docker
Tag kube.*
[FILTER]
Name kubernetes
Match kube.*
Merge_Log On
Keep_Log Off
K8S-Logging.Parser On
[OUTPUT]
Name stdout
Match *
6. 日志字段规范建议
- 添加
request_id
、trace_id
字段以便追踪请求链路 - 统一字段命名(如
level
、service
、component
、message
) - 禁止打印敏感信息到日志(如密码、token)
总结
结构化日志是云原生系统中高效排障与监控的重要基础设施。使用 Golang 构建统一的日志模块,并与 Kubernetes 日志采集系统集成,有助于打造可观测、易维护的微服务体系。推荐后续引入 traceID、日志等级控制、动态配置等能力以完善日志系统。