From 2cc75b04f40037dc648668b4864d33377af66e69 Mon Sep 17 00:00:00 2001 From: Tyler Yahn Date: Tue, 10 Dec 2024 14:17:50 -0800 Subject: [PATCH] [PoC] Enable auto/sdk in otel global --- internal/pkg/inject/offset_results.json | 21 ++++++++----- .../otel/traceglobal/bpf/probe.bpf.c | 30 +++++++++++++++++++ .../otel/traceglobal/bpf_arm64_bpfel.go | 3 ++ .../otel/traceglobal/bpf_x86_bpfel.go | 3 ++ .../otel/traceglobal/probe.go | 4 +++ internal/test/e2e/autosdk/go.mod | 11 +++++-- internal/test/e2e/autosdk/go.sum | 9 ++++++ internal/test/e2e/autosdk/main.go | 5 ++-- 8 files changed, 74 insertions(+), 12 deletions(-) diff --git a/internal/pkg/inject/offset_results.json b/internal/pkg/inject/offset_results.json index 5547c9a21..496e880c1 100644 --- a/internal/pkg/inject/offset_results.json +++ b/internal/pkg/inject/offset_results.json @@ -941,7 +941,8 @@ "1.29.0", "1.30.0", "1.31.0", - "1.32.0" + "1.32.0", + "1.32.1-0.20241210212144-ac386f383cdf" ] } ] @@ -1039,7 +1040,8 @@ "1.29.0", "1.30.0", "1.31.0", - "1.32.0" + "1.32.0", + "1.32.1-0.20241210212144-ac386f383cdf" ] } ] @@ -1137,7 +1139,8 @@ "1.29.0", "1.30.0", "1.31.0", - "1.32.0" + "1.32.0", + "1.32.1-0.20241210212144-ac386f383cdf" ] } ] @@ -1240,7 +1243,8 @@ "1.29.0", "1.30.0", "1.31.0", - "1.32.0" + "1.32.0", + "1.32.1-0.20241210212144-ac386f383cdf" ] } ] @@ -1343,7 +1347,8 @@ "1.29.0", "1.30.0", "1.31.0", - "1.32.0" + "1.32.0", + "1.32.1-0.20241210212144-ac386f383cdf" ] } ] @@ -1436,7 +1441,8 @@ "1.29.0", "1.30.0", "1.31.0", - "1.32.0" + "1.32.0", + "1.32.1-0.20241210212144-ac386f383cdf" ] } ] @@ -1529,7 +1535,8 @@ "1.29.0", "1.30.0", "1.31.0", - "1.32.0" + "1.32.0", + "1.32.1-0.20241210212144-ac386f383cdf" ] } ] diff --git a/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/bpf/probe.bpf.c b/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/bpf/probe.bpf.c index 5b0178f98..0d719521f 100644 --- a/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/bpf/probe.bpf.c +++ b/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/bpf/probe.bpf.c @@ -23,6 +23,9 @@ char __license[] SEC("license") = "Dual MIT/GPL"; #define MAX_BUCKETS 8 #define MAX_TRACERS 64 +// Records state of our write to auto-instrumentation flag. +bool wrote_flag = false; + struct span_description_t { char buf[MAX_STATUS_DESCRIPTION_LEN]; }; @@ -388,6 +391,33 @@ static __always_inline long fill_tracer_id(tracer_id_t *tracer_id, go_tracer_ptr return 0; } +// This instrumentation attaches uprobe to the following function: +// func (t *tracer) newSpan(ctx context.Context, autoSpan *bool, name string, opts []trace.SpanStartOption) (context.Context, trace.Span) { +// https://github.com/open-telemetry/opentelemetry-go/blob/ac386f383cdfc14f546b4e55e8726a0a45e8a409/internal/global/trace.go#L161 +SEC("uprobe/newSpan") +int uprobe_newStart(struct pt_regs *ctx) { + if (wrote_flag) { + // Already wrote flag value. + return 0; + } + + void *flag_ptr = get_argument(ctx, 4); + if (flag_ptr == NULL) { + bpf_printk("invalid flag_ptr: NULL"); + return -1; + } + + bool true_value = true; + long res = bpf_probe_write_user(flag_ptr, &true_value, sizeof(bool)); + if (res != 0) { + bpf_printk("failed to write bool flag value: %ld", res); + return -2; + } + + wrote_flag = true; + return 0; +} + // This instrumentation attaches uprobe to the following function: // func (t *tracer) Start(ctx context.Context, name string, opts ...trace.SpanStartOption) (context.Context, trace.Span) // https://github.com/open-telemetry/opentelemetry-go/blob/98b32a6c3a87fbee5d34c063b9096f416b250897/internal/global/trace.go#L149 diff --git a/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/bpf_arm64_bpfel.go b/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/bpf_arm64_bpfel.go index 6e4abfd2c..cd3f37e18 100644 --- a/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/bpf_arm64_bpfel.go +++ b/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/bpf_arm64_bpfel.go @@ -100,6 +100,7 @@ type bpfProgramSpecs struct { UprobeSetStatus *ebpf.ProgramSpec `ebpf:"uprobe_SetStatus"` UprobeStart *ebpf.ProgramSpec `ebpf:"uprobe_Start"` UprobeStartReturns *ebpf.ProgramSpec `ebpf:"uprobe_Start_Returns"` + UprobeNewStart *ebpf.ProgramSpec `ebpf:"uprobe_newStart"` } // bpfMapSpecs contains maps before they are loaded into the kernel. @@ -186,6 +187,7 @@ type bpfPrograms struct { UprobeSetStatus *ebpf.Program `ebpf:"uprobe_SetStatus"` UprobeStart *ebpf.Program `ebpf:"uprobe_Start"` UprobeStartReturns *ebpf.Program `ebpf:"uprobe_Start_Returns"` + UprobeNewStart *ebpf.Program `ebpf:"uprobe_newStart"` } func (p *bpfPrograms) Close() error { @@ -196,6 +198,7 @@ func (p *bpfPrograms) Close() error { p.UprobeSetStatus, p.UprobeStart, p.UprobeStartReturns, + p.UprobeNewStart, ) } diff --git a/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/bpf_x86_bpfel.go b/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/bpf_x86_bpfel.go index 84cefc779..314a89931 100644 --- a/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/bpf_x86_bpfel.go +++ b/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/bpf_x86_bpfel.go @@ -100,6 +100,7 @@ type bpfProgramSpecs struct { UprobeSetStatus *ebpf.ProgramSpec `ebpf:"uprobe_SetStatus"` UprobeStart *ebpf.ProgramSpec `ebpf:"uprobe_Start"` UprobeStartReturns *ebpf.ProgramSpec `ebpf:"uprobe_Start_Returns"` + UprobeNewStart *ebpf.ProgramSpec `ebpf:"uprobe_newStart"` } // bpfMapSpecs contains maps before they are loaded into the kernel. @@ -186,6 +187,7 @@ type bpfPrograms struct { UprobeSetStatus *ebpf.Program `ebpf:"uprobe_SetStatus"` UprobeStart *ebpf.Program `ebpf:"uprobe_Start"` UprobeStartReturns *ebpf.Program `ebpf:"uprobe_Start_Returns"` + UprobeNewStart *ebpf.Program `ebpf:"uprobe_newStart"` } func (p *bpfPrograms) Close() error { @@ -196,6 +198,7 @@ func (p *bpfPrograms) Close() error { p.UprobeSetStatus, p.UprobeStart, p.UprobeStartReturns, + p.UprobeNewStart, ) } diff --git a/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/probe.go b/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/probe.go index b8d8ef1f5..040b7ec9a 100644 --- a/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/probe.go +++ b/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/probe.go @@ -108,6 +108,10 @@ func New(logger *slog.Logger) probe.Probe { tracerIDContainsScopeAttributes{}, }, Uprobes: []probe.Uprobe{ + { + Sym: "go.opentelemetry.io/otel/internal/global.(*tracer).newSpan", + EntryProbe: "uprobe_newStart", + }, { Sym: "go.opentelemetry.io/otel/internal/global.(*tracer).Start", EntryProbe: "uprobe_Start", diff --git a/internal/test/e2e/autosdk/go.mod b/internal/test/e2e/autosdk/go.mod index 5e60cd997..509ba9467 100644 --- a/internal/test/e2e/autosdk/go.mod +++ b/internal/test/e2e/autosdk/go.mod @@ -3,9 +3,16 @@ module go.opentelemetry.io/auto/internal/test/e2e/autosdk go 1.22.0 require ( - go.opentelemetry.io/auto/sdk v1.1.0 - go.opentelemetry.io/otel v1.32.0 + go.opentelemetry.io/otel v1.32.1-0.20241210212144-ac386f383cdf go.opentelemetry.io/otel/trace v1.32.0 ) +require ( + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/stretchr/testify v1.10.0 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/otel/metric v1.32.0 // indirect +) + replace go.opentelemetry.io/auto/sdk => ../../../../sdk/ diff --git a/internal/test/e2e/autosdk/go.sum b/internal/test/e2e/autosdk/go.sum index 3a023267a..f5566ff5c 100644 --- a/internal/test/e2e/autosdk/go.sum +++ b/internal/test/e2e/autosdk/go.sum @@ -1,5 +1,10 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -8,6 +13,10 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U= go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg= +go.opentelemetry.io/otel v1.32.1-0.20241210212144-ac386f383cdf h1:UdjRouPHKYAwmq0PNPIR+XH1gtolmJTBhkvufgwQS/g= +go.opentelemetry.io/otel v1.32.1-0.20241210212144-ac386f383cdf/go.mod h1:TV/DhW5+BLw6Z88V8qkXPPjIrjOYagH9a6HmSRrnNP0= +go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M= +go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8= go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM= go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/internal/test/e2e/autosdk/main.go b/internal/test/e2e/autosdk/main.go index 31dd02886..10d8b1ba8 100644 --- a/internal/test/e2e/autosdk/main.go +++ b/internal/test/e2e/autosdk/main.go @@ -10,11 +10,10 @@ import ( "os/signal" "time" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/trace" - - "go.opentelemetry.io/auto/sdk" ) const ( @@ -79,7 +78,7 @@ func main() { // give time for auto-instrumentation to start up time.Sleep(5 * time.Second) - provider := sdk.TracerProvider() + provider := otel.GetTracerProvider() tracer := provider.Tracer( pkgName, trace.WithInstrumentationVersion(pkgVer),