From 3892986f01959e1e71aee8710d9719400e0b1205 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Tue, 6 Dec 2022 11:49:56 +0200 Subject: [PATCH] feat(redisotel): add code attributes --- example/otel/docker-compose.yml | 2 +- extra/redisotel/tracing.go | 62 ++++++++++++++++++++++++++++----- 2 files changed, 55 insertions(+), 9 deletions(-) diff --git a/example/otel/docker-compose.yml b/example/otel/docker-compose.yml index e607dd0..4c3dffb 100644 --- a/example/otel/docker-compose.yml +++ b/example/otel/docker-compose.yml @@ -18,7 +18,7 @@ services: - '9000:9000' uptrace: - image: 'uptrace/uptrace:1.2.2' + image: 'uptrace/uptrace:1.2.4' #image: 'uptrace/uptrace-dev:latest' restart: on-failure volumes: diff --git a/extra/redisotel/tracing.go b/extra/redisotel/tracing.go index 608d774..6a8f416 100644 --- a/extra/redisotel/tracing.go +++ b/extra/redisotel/tracing.go @@ -4,6 +4,8 @@ import ( "context" "fmt" "net" + "runtime" + "strings" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" @@ -107,13 +109,23 @@ func (th *tracingHook) ProcessHook(hook redis.ProcessHook) redis.ProcessHook { return hook(ctx, cmd) } - opts := th.spanOpts + fn, file, line := funcFileLine("github.com/go-redis/redis") + + attrs := make([]attribute.KeyValue, 0, 8) + attrs = append(attrs, + semconv.CodeFunctionKey.String(fn), + semconv.CodeFilepathKey.String(file), + semconv.CodeLineNumberKey.Int(line), + ) + if th.conf.dbStmtEnabled { - opts = append(opts, trace.WithAttributes( - semconv.DBStatementKey.String(rediscmd.CmdString(cmd))), - ) + cmdString := rediscmd.CmdString(cmd) + attrs = append(attrs, semconv.DBStatementKey.String(cmdString)) } + opts := th.spanOpts + opts = append(opts, trace.WithAttributes(attrs...)) + ctx, span := th.conf.tracer.Start(ctx, cmd.FullName(), opts...) defer span.End() @@ -133,16 +145,24 @@ func (th *tracingHook) ProcessPipelineHook( return hook(ctx, cmds) } - opts := th.spanOpts - opts = append(opts, trace.WithAttributes( + fn, file, line := funcFileLine("github.com/go-redis/redis") + + attrs := make([]attribute.KeyValue, 0, 8) + attrs = append(attrs, + semconv.CodeFunctionKey.String(fn), + semconv.CodeFilepathKey.String(file), + semconv.CodeLineNumberKey.Int(line), attribute.Int("db.redis.num_cmd", len(cmds)), - )) + ) summary, cmdsString := rediscmd.CmdsString(cmds) if th.conf.dbStmtEnabled { - opts = append(opts, trace.WithAttributes(semconv.DBStatementKey.String(cmdsString))) + attrs = append(attrs, semconv.DBStatementKey.String(cmdsString)) } + opts := th.spanOpts + opts = append(opts, trace.WithAttributes(attrs...)) + ctx, span := th.conf.tracer.Start(ctx, "redis.pipeline "+summary, opts...) defer span.End() @@ -167,3 +187,29 @@ func formatDBConnString(network, addr string) string { } return fmt.Sprintf("%s://%s", network, addr) } + +func funcFileLine(pkg string) (string, string, int) { + const depth = 16 + var pcs [depth]uintptr + n := runtime.Callers(3, pcs[:]) + ff := runtime.CallersFrames(pcs[:n]) + + var fn, file string + var line int + for { + f, ok := ff.Next() + if !ok { + break + } + fn, file, line = f.Function, f.File, f.Line + if !strings.Contains(fn, pkg) { + break + } + } + + if ind := strings.LastIndexByte(fn, '/'); ind != -1 { + fn = fn[ind+1:] + } + + return fn, file, line +}