fix(redisotel): fix buggy append in reportPoolStats

The current append twice to `conf.attrs` approach in `reportPoolStats` may result in unexpected idleAttrs,
due to `append` [can mutate](https://github.com/golang/go/issues/29115#issuecomment-444669036) the underlying array of the original slice,
as demonstrated at <https://go.dev/play/p/jwRMofH91eQ?v=goprev>.

Also, I replaced `metric.WithAttributes` in `reportPoolStats` with `metric.WithAttributeSet`,
since `WithAttributes` is just `WithAttributeSet` with some extra works that are not needed here,
see <https://pkg.go.dev/go.opentelemetry.io/otel/metric@v1.22.0#WithAttributes>.
This commit is contained in:
Cattī Crūdēlēs 2024-09-15 18:26:16 +08:00
parent 233f97accd
commit fc5be74fe9
No known key found for this signature in database
GPG Key ID: ECBFEAFB10491A3A
1 changed files with 9 additions and 9 deletions

View File

@ -83,9 +83,9 @@ func InstrumentMetrics(rdb redis.UniversalClient, opts ...MetricsOption) error {
} }
func reportPoolStats(rdb *redis.Client, conf *config) error { func reportPoolStats(rdb *redis.Client, conf *config) error {
labels := conf.attrs poolAttrs := attribute.NewSet(conf.attrs...)
idleAttrs := append(labels, attribute.String("state", "idle")) idleAttrs := attribute.NewSet(append(poolAttrs.ToSlice(), attribute.String("state", "idle"))...)
usedAttrs := append(labels, attribute.String("state", "used")) usedAttrs := attribute.NewSet(append(poolAttrs.ToSlice(), attribute.String("state", "used"))...)
idleMax, err := conf.meter.Int64ObservableUpDownCounter( idleMax, err := conf.meter.Int64ObservableUpDownCounter(
"db.client.connections.idle.max", "db.client.connections.idle.max",
@ -132,14 +132,14 @@ func reportPoolStats(rdb *redis.Client, conf *config) error {
func(ctx context.Context, o metric.Observer) error { func(ctx context.Context, o metric.Observer) error {
stats := rdb.PoolStats() stats := rdb.PoolStats()
o.ObserveInt64(idleMax, int64(redisConf.MaxIdleConns), metric.WithAttributes(labels...)) o.ObserveInt64(idleMax, int64(redisConf.MaxIdleConns), metric.WithAttributeSet(poolAttrs))
o.ObserveInt64(idleMin, int64(redisConf.MinIdleConns), metric.WithAttributes(labels...)) o.ObserveInt64(idleMin, int64(redisConf.MinIdleConns), metric.WithAttributeSet(poolAttrs))
o.ObserveInt64(connsMax, int64(redisConf.PoolSize), metric.WithAttributes(labels...)) o.ObserveInt64(connsMax, int64(redisConf.PoolSize), metric.WithAttributeSet(poolAttrs))
o.ObserveInt64(usage, int64(stats.IdleConns), metric.WithAttributes(idleAttrs...)) o.ObserveInt64(usage, int64(stats.IdleConns), metric.WithAttributeSet(idleAttrs))
o.ObserveInt64(usage, int64(stats.TotalConns-stats.IdleConns), metric.WithAttributes(usedAttrs...)) o.ObserveInt64(usage, int64(stats.TotalConns-stats.IdleConns), metric.WithAttributeSet(usedAttrs))
o.ObserveInt64(timeouts, int64(stats.Timeouts), metric.WithAttributes(labels...)) o.ObserveInt64(timeouts, int64(stats.Timeouts), metric.WithAttributeSet(poolAttrs))
return nil return nil
}, },
idleMax, idleMax,