昨天(2022/9/21) opentelemetry-go metric v0.32.0 发布,这个版本改动颇大,基本按照 trace 的风格重构了整个 Provider,其 SDK 易用性大大增强,个人感觉以后的版本接口会以此为基础,慢慢固化下来。
v0.32.0 Provider 变化
v0.31.0 版本:
 c := controller.New(    processor.NewFactory(        simple.NewWithHistogramDistribution(            histogram.WithExplicitBoundaries([]float64{0.05, 0.1, 0.25, 0.5, 1, 2}),        ),        aggregation.CumulativeTemporalitySelector(),        processor.WithMemory(true),    ),    controller.WithExporter(ep),    controller.WithCollectPeriod(15*time.Second),)
global.SetMeterProvider(c)
   复制代码
 
这个版本依赖 sdk/metric/controller/basic、sdk/metric/processor/basic、sdk/metric/selector/simple 等包,且与 trace provider 风格差异太大,使用门槛高。
v0.32.0 版本:
 provider := metric.NewMeterProvider(    metric.WithReader(        metric.NewPeriodicReader(ep, metric.WithInterval(15*time.Second)),    ),    metric.WithReader(ep3),)global.SetMeterProvider(provider)
   复制代码
 
可以看到该版本不仅风格与 trace 相似,而且可以同时注入多个 exporter。
代码示例
opentelemetry-go 默认 metric exporter 有四种,它们分别为 otlpmetric/(http|gRPC)、stdoutmetric、prometheus。
下面我们以一段 go server 例子演示 otel provider 与多种 metric exporter 结合的使用教程。
 import (  "github.com/gin-gonic/gin"  "github.com/prometheus/client_golang/prometheus"  "github.com/prometheus/client_golang/prometheus/promhttp"
  "go.opentelemetry.io/otel/attribute"  "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp"  promexporter "go.opentelemetry.io/otel/exporters/prometheus"  "go.opentelemetry.io/otel/exporters/stdout/stdoutmetric"  "go.opentelemetry.io/otel/metric/global"  "go.opentelemetry.io/otel/metric/instrument"  "go.opentelemetry.io/otel/sdk/metric")
func initMeter() *metric.MeterProvider {  // init otlpmetrichttp exporter  ep, _ := otlpmetrichttp.New(    context.Background(),    otlpmetrichttp.WithEndpoint("mimir:8080"),    otlpmetrichttp.WithURLPath("/otlp/v1/metrics"),    otlpmetrichttp.WithInsecure(),    otlpmetrichttp.WithHeaders(map[string]string{      "X-Scope-OrgID": "demo",    }),  )
  // init stdoutmetric exporter  ep2, _ := stdoutmetric.New()
  // init prometheus exporter  ep3 := promexporter.New()  prometheus.Register(ep3.Collector)
  provider := metric.NewMeterProvider(    metric.WithReader(      metric.NewPeriodicReader(ep, metric.WithInterval(15*time.Second)),    ),    metric.WithReader(      metric.NewPeriodicReader(ep2, metric.WithInterval(15*time.Second)),    ),    metric.WithReader(ep3),  )  global.SetMeterProvider(provider)
  return provider}
func timeDuration() func(ctx *gin.Context) {  ....}
func main() {  provider := initMeter()  defer provider.Shutdown(context.Background())
  r := gin.New()  r.Use(timeDuration())
  .... // gin router
  // register prometheus handler  promHandler := promhttp.HandlerFor(    prometheus.DefaultGatherer,    promhttp.HandlerOpts{      EnableOpenMetrics: true,    },  )  r.GET("/metrics", func(ctx *gin.Context) {    promHandler.ServeHTTP(ctx.Writer, ctx.Request)  })
  r.Run(":8080")}
   复制代码
 
运行代码,在 console 中可以看到如下输出:
再执行 curl http://localhost:8080/metrics 也能看到类似 prometheus exporter 输出结果:
总结
伴随 opentelemetry-go Metric SDK (Alpha) v0.32.0 发布,其 metrics SDK 代码初于稳定,其支持多种 exporter,方便多种后端的集成。
但目前 Go SDK 还不支持 exemplar 的注入,不过社区已有相应 issue 跟进,相信很快,就能使用 opentelemetry-go SDK 完全替换掉 prometheus SDk 了。
更多文章,请关注我们公众号 【Grafana 爱好者】。
评论