redis / go-redis

Redis Go client
https://redis.uptrace.dev
BSD 2-Clause "Simplified" License
19.81k stars 2.34k forks source link

[bug] redisotel repeatedly opening span #2842

Closed AtlanCI closed 8 months ago

AtlanCI commented 8 months ago

Issue tracker is used for reporting bugs and discussing new features. Please use stackoverflow for supporting issues.

Summary

I am using OTEL Redis, which has been repeatedly enabled multiple times when using Redis v9.1.0 client Guess it's because hook was called multiple times in v9.1.0 version

Expected Behavior

There should only be one span

Current Behavior

A Redis operation will generate 7 spans with causal relationships image

Steps to Reproduce

  1. use go redi v9.1.0
  2. use otelredis
  3. Any operation

Context (Environment)

redis version: 6.0.0 (cluster module) go-redis: v9.1.0 go version: v1.21.4

rfyiamcool commented 8 months ago

Otel recorder is implemented by go-redis hook ? the hook of go-redis is safe, only call once for one command, script and pipeline.

Can you provider test example ?

AtlanCI commented 8 months ago

Otel recorder is implemented by go-redis hook ? the hook of go-redis is safe, only call once for one command, script and pipeline.

Can you provider test example ?

thanks, I found my problem. I'm adding a hook to clusterclient on OnNewNode. I should actually be adding a hook to redis.

my example

    c := redis.NewClusterClient(opts)

    // trace powerfully by otel
    c.AddHook(traceredis.BuilderRedisTracerHook(redis.Version(), nil))

    c.OnNewNode(func(rdb *redis.Client) {
        opt := rdb.Options()
               # this is problem
        c.AddHook(traceredis.BuilderRedisTracerHook(redis.Version(), opt))
    })

otelredis example

rdb.AddHook(newTracingHook("", opts...))

        rdb.OnNewNode(func(rdb *redis.Client) {
            opt := rdb.Options()
            connString := formatDBConnString(opt.Network, opt.Addr)
            rdb.AddHook(newTracingHook(connString, opts...))
        })
AtlanCI commented 8 months ago

Otel recorder is implemented by go-redis hook ? the hook of go-redis is safe, only call once for one command, script and pipeline.

Can you provider test example ?

thanks. I will close this issue