1
0
mirror of https://github.com/redis/go-redis.git synced 2025-07-31 05:04:23 +03:00

feat(redisotel): add WithCallerEnabled option (#3415)

* feat(redisotel): add WithCaller option

Allow the disabling the collection of the `code.function`, `code.filepath` and `code.lineno` tracing attributes.
When setting `WithCaller(false)` overall performance is increased as the "expensive" `runtime.Callers` and `runtime.(*Frames).Next` calls are no longer needed.

* chore(redisotel): improve docblock language

* chore(redisotel): rename `WithCaller` to `WithCallerEnabled`

---------

Co-authored-by: Nedyalko Dyakov <1547186+ndyakov@users.noreply.github.com>
This commit is contained in:
Warnar Boekkooi
2025-06-24 09:53:35 +02:00
committed by GitHub
parent 05f42e2327
commit fa475cbc99
3 changed files with 56 additions and 12 deletions

View File

@ -20,6 +20,7 @@ type config struct {
tracer trace.Tracer
dbStmtEnabled bool
callerEnabled bool
// Metrics options.
@ -57,6 +58,7 @@ func newConfig(opts ...baseOption) *config {
tp: otel.GetTracerProvider(),
mp: otel.GetMeterProvider(),
dbStmtEnabled: true,
callerEnabled: true,
}
for _, opt := range opts {
@ -106,13 +108,20 @@ func WithTracerProvider(provider trace.TracerProvider) TracingOption {
})
}
// WithDBStatement tells the tracing hook not to log raw redis commands.
// WithDBStatement tells the tracing hook to log raw redis commands.
func WithDBStatement(on bool) TracingOption {
return tracingOption(func(conf *config) {
conf.dbStmtEnabled = on
})
}
// WithCallerEnabled tells the tracing hook to log the calling function, file and line.
func WithCallerEnabled(on bool) TracingOption {
return tracingOption(func(conf *config) {
conf.callerEnabled = on
})
}
//------------------------------------------------------------------------------
type MetricsOption interface {

View File

@ -101,14 +101,16 @@ func (th *tracingHook) DialHook(hook redis.DialHook) redis.DialHook {
func (th *tracingHook) ProcessHook(hook redis.ProcessHook) redis.ProcessHook {
return func(ctx context.Context, cmd redis.Cmder) error {
fn, file, line := funcFileLine("github.com/redis/go-redis")
attrs := make([]attribute.KeyValue, 0, 8)
if th.conf.callerEnabled {
fn, file, line := funcFileLine("github.com/redis/go-redis")
attrs = append(attrs,
semconv.CodeFunction(fn),
semconv.CodeFilepath(file),
semconv.CodeLineNumber(line),
)
}
if th.conf.dbStmtEnabled {
cmdString := rediscmd.CmdString(cmd)
@ -133,15 +135,19 @@ func (th *tracingHook) ProcessPipelineHook(
hook redis.ProcessPipelineHook,
) redis.ProcessPipelineHook {
return func(ctx context.Context, cmds []redis.Cmder) error {
fn, file, line := funcFileLine("github.com/redis/go-redis")
attrs := make([]attribute.KeyValue, 0, 8)
attrs = append(attrs,
attribute.Int("db.redis.num_cmd", len(cmds)),
)
if th.conf.callerEnabled {
fn, file, line := funcFileLine("github.com/redis/go-redis")
attrs = append(attrs,
semconv.CodeFunction(fn),
semconv.CodeFilepath(file),
semconv.CodeLineNumber(line),
attribute.Int("db.redis.num_cmd", len(cmds)),
)
}
summary, cmdsString := rediscmd.CmdsString(cmds)
if th.conf.dbStmtEnabled {

View File

@ -66,6 +66,35 @@ func TestWithDBStatement(t *testing.T) {
}
}
func TestWithoutCaller(t *testing.T) {
provider := sdktrace.NewTracerProvider()
hook := newTracingHook(
"",
WithTracerProvider(provider),
WithCallerEnabled(false),
)
ctx, span := provider.Tracer("redis-test").Start(context.TODO(), "redis-test")
cmd := redis.NewCmd(ctx, "ping")
defer span.End()
processHook := hook.ProcessHook(func(ctx context.Context, cmd redis.Cmder) error {
attrs := trace.SpanFromContext(ctx).(sdktrace.ReadOnlySpan).Attributes()
for _, attr := range attrs {
switch attr.Key {
case semconv.CodeFunctionKey,
semconv.CodeFilepathKey,
semconv.CodeLineNumberKey:
t.Fatalf("Attribute with %s statement should not exist", attr.Key)
}
}
return nil
})
err := processHook(ctx, cmd)
if err != nil {
t.Fatal(err)
}
}
func TestTracingHook_DialHook(t *testing.T) {
imsb := tracetest.NewInMemoryExporter()
provider := sdktrace.NewTracerProvider(sdktrace.WithSyncer(imsb))