在 OpenTelemetry 中,Float64ObservableCounter 代表可以被观察的 float64 类型的计数器,其值随着时间变化而变化。使用 Float64ObservableCounter 要注意以下几点:
- Float64ObservableCounter 是只读的,不能直接修改它的值。
- 可以通过调用该计数器对象上的 Bind() 方法来创建一个可写入的 Counter 对象,并对其进行累加操作。
下面是一个示例代码,演示如何自动累加 Float64ObservableCounter:
package main
import (
"context"
"fmt"
"time"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel/api/metric/number"
controller "go.opentelemetry.io/otel/sdk/metric/controller/basic"
exporter "go.opentelemetry.io/otel/sdk/export/metric/stdout"
"go.opentelemetry.io/otel/sdk/metric/batcher/simple"
)
func main() {
ctx := context.Background()
// 创建 stdout 导出器
exporter, err := exporter.NewExporter(exporter.WithPrettyPrint())
if err != nil {
panic(err)
}
// 创建批处理程序
batcher := simple.NewWithInexpensiveDistribution()
pusher := controller.New(
batcher,
exporter,
// 确定 PushInterval 时间间隔
controller.WithPusherPeriod(time.Second),
)
meter := pusher.MeterProvider().Meter("example")
counter := metric.Must(meter).NewFloat64ObservableCounter("example.counter")
callback := func(_ context.Context, result metric.Float64ObserverResult) {
// 模拟累加器每秒自动加一次
result.Observe(float64(time.Now().Second()), metric.WithLabels())
}
// 绑定计数器对象并启动批处理程序
counter.Bind(&callback)
if err := pusher.Start(ctx); err != nil {
panic(err)
}
defer pusher.Stop(ctx)
for i := 0; i < 5; i++ {
// 每隔1秒输出累加结果
time.Sleep(time.Second)
fmt.Printf("counter: %v\n", batcher.CheckpointSet().Counters()["example.counter"].Value())
}
}
在上面的示例代码中,我们创建了一个 Float64ObservableCounter 对象 counter,然后通过调用 Bind() 方法来将其绑定到一个回调函数 callback 上。该回调函数会在每个时刻被触发,并传入当前的浮点数值。
在回调函数中,我们使用 result.Observe() 方法来观察当前的浮点数值,并进行累加操作。由于我们使用了默认的参数 (即不带任何标签),因此所有记录都将共享同一个计数器实例。
最后,在主函数中,我们每隔一秒钟就输出一次累加结果。可以看到,计数器的值会随着时间变化而自动增长。




