如何通过Golang日志监控系统健康
导读:用结构化日志与集中平台联动,配合指标与告警,形成从发现到定位的闭环。 一、整体架构与关键原则 在应用内使用结构化日志(如 logrus、zap、zerolog),统一包含 timestamp、level、msg、trace_id、span...
用结构化日志与集中平台联动,配合指标与告警,形成从发现到定位的闭环。
一、整体架构与关键原则
- 在应用内使用结构化日志(如 logrus、zap、zerolog),统一包含 timestamp、level、msg、trace_id、span_id、service、instance 等字段,便于检索与聚合。
- 容器与主机环境优先输出到 stdout/stderr,由 Filebeat/Fluent Bit 采集并发送到 ELK(Elasticsearch、Logstash、Kibana) 或 Grafana Loki,实现解耦与统一治理。
- 指标与日志并行:暴露 /metrics 供 Prometheus 抓取,用 Grafana 可视化;日志侧用 Loki+LogQL 或 Kibana 做检索与可视化。
- 告警分层:日志侧用 Prometheus Alertmanager 或 ELK Watcher 对错误激增、延迟异常等触发通知(邮件、钉钉、Slack、PagerDuty)。
二、落地步骤
- 日志采集与输出
- 选择库与格式:生产推荐 zap(高性能)或 logrus(生态丰富),统一 JSON 格式;为每条日志附加 trace_id/span_id 以便与链路追踪关联。
- 输出策略:容器化场景只写 stdout/stderr;虚拟机/物理机可用 lumberjack 做本地轮转(避免磁盘被打满)。
- 集中收集与存储
- Kubernetes:以 DaemonSet 部署 Filebeat/Fluent Bit,采集容器日志并发送到 ELK 或 Loki。
- 虚拟机/物理机:Filebeat 直采日志文件并送入 ELK。
- 检索、可视化与告警
- ELK:Logstash 解析与清洗,Elasticsearch 存储与检索,Kibana 构建健康大盘与探索。
- Loki:用 LogQL 快速查询与聚合,Grafana 统一展示日志与指标。
- 告警:Prometheus 采集业务/系统指标,Alertmanager 分组、抑制、静默并发送通知;或在 ELK 配置阈值/异常模式告警。
三、最小可用代码示例
- 结构化日志 + 标准输出(适合容器)
package main
import (
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"os"
"time"
)
func main() {
cfg := zap.NewProductionEncoderConfig()
cfg.EncodeTime = zapcore.ISO8601TimeEncoder
core := zapcore.NewCore(
zapcore.NewJSONEncoder(cfg),
zapcore.AddSync(os.Stdout),
zapcore.InfoLevel,
)
logger := zap.New(core, zap.AddCaller(), zap.AddStacktrace(zapcore.ErrorLevel))
defer logger.Sync()
logger.Info("service started",
zap.String("service", "order"),
zap.String("version", "v1.2.3"),
zap.String("env", "prod"),
)
// 模拟业务处理
start := time.Now()
err := process()
duration := time.Since(start)
if err != nil {
logger.Error("process failed",
zap.Error(err),
zap.Duration("duration", duration),
zap.String("trace_id", "abc-123-def"),
)
}
else {
logger.Info("process succeeded",
zap.Duration("duration", duration),
zap.Int("count", 42),
)
}
}
func process() error {
// TODO: 业务逻辑
return nil
}
- 指标暴露 + 健康检查(与日志互补)
package main
import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"net/http"
)
var (
requestsTotal = prometheus.NewCounter(prometheus.CounterOpts{
Name: "http_requests_total",
Help: "Total number of HTTP requests.",
}
)
requestDuration = prometheus.NewSummary(prometheus.SummaryOpts{
Name: "http_request_duration_seconds",
Help: "Duration of HTTP requests.",
}
)
)
func init() {
prometheus.MustRegister(requestsTotal, requestDuration)
}
func main() {
http.Handle("/metrics", promhttp.Handler())
http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte(`{
"status":"ok"}
`))
}
)
go http.ListenAndServe(":8080", nil)
select {
}
}
- 本地文件轮转(仅非容器场景)
import (
"gopkg.in/natefinch/lumberjack.v2"
"github.com/sirupsen/logrus"
)
logrus.SetOutput(&
lumberjack.Logger{
Filename: "/var/log/myapp.log",
MaxSize: 10, // MB
MaxBackups: 3, // 保留文件数
MaxAge: 28, // 天
Compress: true, // 压缩
}
)
- 容器采集建议
- 应用只输出 JSON 到 stdout/stderr;在 Kubernetes 以 DaemonSet 部署 Filebeat/Fluent Bit,将日志送入 ELK 或 Loki。
四、告警规则与SLO示例
- 日志侧异常检测
- 错误突发:在 Loki/ELK 中对日志级别为 ERROR 的速率做阈值告警(如 5 分钟内 > 10 次)。
- 关键业务失败:对 “order.failed”“payment.rejected” 等业务关键字计数突增告警。
- 延迟异常:对处理耗时超过 p95 > 1s 的日志聚合告警。
- 指标侧健康判断
- 服务可用性:对 /healthz 的 5xx 比例设 SLO(如 99.9%),持续低于阈值触发告警。
- 请求成功率与延迟:基于 Prometheus 的 http_requests_total 与 http_request_duration_seconds 设置告警规则。
- 通知与升级
- 使用 Alertmanager 或 ELK Watcher 配置分组、抑制、静默与升级策略,通知渠道包含 邮件、钉钉、Slack、PagerDuty 等。
五、运维与治理要点
- 日志轮转与保留:容器侧依赖平台日志采集与保留策略;主机侧用 lumberjack 控制单文件大小与保留天数,避免磁盘被占满。
- 敏感信息与合规:日志中避免记录 密码、密钥、信用卡号 等敏感数据,必要时脱敏或哈希。
- 性能与开销:生产环境优先 zap/zerolog 等高性能库;避免同步写磁盘与过度打点。
- 可观测性三支柱协同:用 日志 还原现场、用 指标 判断健康、用 追踪 定位瓶颈,统一 trace_id 贯穿全链路。
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: 如何通过Golang日志监控系统健康
本文地址: https://pptw.com/jishu/771304.html
