Skip to content

Commit c031088

Browse files
committed
pkg/invoke: add OpenTelemetry trace context propagation
This enables distributed tracing support by passing span identifiers from the caller to CNI plugins through environment variables. When a valid span context exists, it is propagated using the TRACEPARENT, TRACESTATE, and BAGGAGE environment variables following the OpenTelemetry specification (OTEP 0258). This allows CNI plugins to participate in distributed traces, helping with performance analysis and debugging across the plugin execution lifecycle. Fixes #561
1 parent bab140e commit c031088

File tree

3 files changed

+55
-11
lines changed

3 files changed

+55
-11
lines changed

go.mod

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
module github.com/containernetworking/cni
22

3-
go 1.21
3+
go 1.23.0
44

55
require (
66
github.com/onsi/ginkgo/v2 v2.20.1
77
github.com/onsi/gomega v1.34.1
8+
github.com/spf13/cobra v1.9.1
89
github.com/vishvananda/netns v0.0.4
10+
go.opentelemetry.io/otel v1.38.0
11+
go.opentelemetry.io/otel/trace v1.38.0
912
)
1013

1114
require (
12-
github.com/go-logr/logr v1.4.2 // indirect
15+
github.com/go-logr/logr v1.4.3 // indirect
1316
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
14-
github.com/google/go-cmp v0.6.0 // indirect
17+
github.com/google/go-cmp v0.7.0 // indirect
1518
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect
1619
github.com/inconshreveable/mousetrap v1.1.0 // indirect
17-
github.com/spf13/cobra v1.9.1 // indirect
1820
github.com/spf13/pflag v1.0.6 // indirect
1921
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
2022
golang.org/x/net v0.28.0 // indirect

go.sum

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
22
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
33
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4-
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
5-
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
4+
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
5+
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
6+
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
7+
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
68
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
79
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
8-
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
9-
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
10+
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
11+
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
1012
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k=
1113
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
1214
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
@@ -22,10 +24,18 @@ github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
2224
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
2325
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
2426
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
25-
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
26-
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
27+
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
28+
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
2729
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
2830
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
31+
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
32+
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
33+
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
34+
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
35+
go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
36+
go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
37+
go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
38+
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
2939
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
3040
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
3141
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=

pkg/invoke/raw_exec.go

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ import (
2525
"time"
2626

2727
"github.com/containernetworking/cni/pkg/types"
28+
"go.opentelemetry.io/otel/baggage"
29+
"go.opentelemetry.io/otel/propagation"
30+
"go.opentelemetry.io/otel/trace"
2831
)
2932

3033
type RawExec struct {
@@ -35,7 +38,7 @@ func (e *RawExec) ExecPlugin(ctx context.Context, pluginPath string, stdinData [
3538
stdout := &bytes.Buffer{}
3639
stderr := &bytes.Buffer{}
3740
c := exec.CommandContext(ctx, pluginPath)
38-
c.Env = environ
41+
c.Env = injectTraceContext(ctx, environ)
3942
c.Stdin = bytes.NewBuffer(stdinData)
4043
c.Stdout = stdout
4144
c.Stderr = stderr
@@ -69,6 +72,35 @@ func (e *RawExec) ExecPlugin(ctx context.Context, pluginPath string, stdinData [
6972
return stdout.Bytes(), nil
7073
}
7174

75+
// injectTraceContext will add OpenTelemetry trace context to the environment variables based on
76+
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/oteps/0258-env-context-baggage-carriers.md
77+
func injectTraceContext(ctx context.Context, environ []string) []string {
78+
sc := trace.SpanContextFromContext(ctx)
79+
if !sc.IsValid() {
80+
return environ
81+
}
82+
83+
ctx = trace.ContextWithRemoteSpanContext(ctx, sc)
84+
mc := propagation.MapCarrier{}
85+
(propagation.TraceContext{}).Inject(ctx, mc)
86+
87+
// Currently, both traceparent and tracestate are not exported variables,
88+
// https://github.com/open-telemetry/opentelemetry-go/blob/bcf8234d0c9c48b626cad85367a3681f3fc0c0fd/propagation/trace_context.go#L18-L19
89+
// so we have to use the string literals here.
90+
if traceparent := mc.Get("traceparent"); traceparent != "" {
91+
environ = append(environ, "TRACEPARENT"+"="+traceparent)
92+
}
93+
94+
if tracestate := mc.Get("tracestate"); tracestate != "" {
95+
environ = append(environ, "TRACESTATE"+"="+tracestate)
96+
}
97+
98+
if envBaggage := baggage.FromContext(ctx).String(); envBaggage != "" {
99+
environ = append(environ, "BAGGAGE"+"="+envBaggage)
100+
}
101+
return environ
102+
}
103+
72104
func (e *RawExec) pluginErr(err error, stdout, stderr []byte) error {
73105
emsg := types.Error{}
74106
if len(stdout) == 0 {

0 commit comments

Comments
 (0)