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——那是高基数问题的头号来源。

观测云落地:指标进统一监控

exporter 端点指向观测云 DataKit 的 OTLP 地址(4317/4318),指标自动进入观测云指标模块:用 DQL 写查询、用内置图表搭业务看板、用监控器对"订单创建速率骤降"这类业务异常配告警,通知直达钉钉/企微/飞书。与同一服务的链路(《Go 链路追踪》)联动,指标异常可直接下钻到具体 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 即自动采集。

系列阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

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

立即开始

选择观测云版本

代码托管平台