Go OpenTelemetry 指标实战:Counter、Gauge、Histogram 一次讲透

在 Go 应用中用 OpenTelemetry 暴露业务与运行时指标:HTTP 服务器自动指标、Counter 计数、UpDownCounter 升降计数、Gauge 瞬时值、Histogram 分布统计,以及如何用 View 裁剪无用指标。指标最终导入观测云统一监控告警。

最佳实践
Go OpenTelemetry 指标实战:Counter、Gauge、Histogram 一次讲透封面

OpenTelemetry Go 指标 API 提供四种核心仪器——Counter、UpDownCounter、Gauge、Histogram,分别对应"只增计数、可增可减、瞬时快照、分布统计"四类场景——选对仪器是指标设计的第一步,选错了会导致数据语义混乱、无法正确聚合。

核心要点速览

  • otelhttp 自动产出 HTTP 服务器指标(请求数、耗时分布),零手工代码;
  • Counter 记总量、UpDownCounter 记当前在制品、Gauge 记瞬时值、Histogram 记分布;
  • 用 View 按名称丢弃无用指标,直接降低基数与成本;
  • OTLP 导出到观测云 DataKit,指标进观测云指标模块做看板与告警。

初始化 MeterProvider

import (
    "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc"
    sdkmetric "go.opentelemetry.io/otel/sdk/metric"
)

exporter, _ := otlpmetricgrpc.New(ctx,
    otlpmetricgrpc.WithEndpoint("datakit-host:4317"),
    otlpmetricgrpc.WithInsecure(),
)
mp := sdkmetric.NewMeterProvider(
    sdkmetric.WithReader(sdkmetric.NewPeriodicReader(exporter,
        sdkmetric.WithInterval(30*time.Second))),
    sdkmetric.WithResource(res),
)
otel.SetMeterProvider(mp)
meter := mp.Meter("order-service")

HTTP 服务器自动指标

otelhttp.NewHandler 包装后自动产出请求计数与耗时 Histogram,无需手写。但默认指标里可能有不关心的维度——用 View 丢弃:

mp := sdkmetric.NewMeterProvider(
    sdkmetric.WithView(sdkmetric.NewView(
        sdkmetric.Instrument{Name: "http.server.request.body.size"},
        sdkmetric.Stream{Aggregation: sdkmetric.AggregationDrop{}},
    )),
    ...
)

四种仪器的正确用法

Counter(只增)——请求总量、错误总数、订单创建数:

ordersCreated, _ := meter.Int64Counter("orders.created.total")
ordersCreated.Add(ctx, 1, metric.WithAttributes(attribute.String("channel", "app")))

UpDownCounter(可增可减)——当前处理中的请求数、队列积压:

inflight, _ := meter.Int64UpDownCounter("orders.inflight")
inflight.Add(ctx, 1)   // 进入处理
defer inflight.Add(ctx, -1)  // 处理完毕

Gauge(瞬时值)——温度、当前内存、在线人数。OTel Go SDK 用 Int64Gauge 直接上报采样时刻的值。

Histogram(分布)——响应耗时、订单金额:

latency, _ := meter.Float64Histogram("orders.process.duration",
    metric.WithUnit("s"), metric.WithExplicitBucketBoundaries(0.05, 0.1, 0.5, 1, 5))
latency.Record(ctx, elapsed.Seconds())

桶边界按业务延迟分布自定义——默认桶不适配你的 SLO 时,分位数统计会失真。

指标命名与属性规范

名称用点分小写(orders.created.total),单位用 WithUnit 显式声明(UCUM 标准,秒为 s、字节为 By);属性只放聚合维度(渠道、地区),绝不放请求级 ID——那是高基数问题的头号来源。

验证业务指标上报

让 Go exporter 的协议与观测云 DataKit 接收端一致后,触发固定次数的订单创建,核对 Counter 增量、单位与属性。再重启一个测试实例,检查所用查询怎样处理计数器归零。

需要按指标查同时间的链路时,先统一服务名和环境标签,并确认请求的 Span 已采集;单条聚合指标通常不能唯一指向一条 Trace。

常见问题(FAQ)

Q:Counter 重启归零怎么办? OTel 的 Cumulative 时间性包含起始时间信息;后端查询仍需正确处理重置。用测试实例重启验证速率结果,避免把归零误判为业务下跌。

Q:Histogram 和 Summary 选哪个? 优先 Histogram——可分桶跨实例聚合;Summary 的分位数在客户端算死,无法合并。

Q:指标上报间隔多久合适? 业务指标 30-60s;过短的间隔(<10s)增加开销且多数告警场景用不上。

Q:Go 运行时指标(GC、goroutine)怎么拿? 引入 go.opentelemetry.io/contrib/instrumentation/runtime,一行 Start 即自动采集。

系列阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台