昨天(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 爱好者】。
评论