Skip to content

Commit 7dfe3e1

Browse files
committed
Instrument CNI interface with OpenTelemetry tracing
Creates a span for each interface function where context.Context is available and additional creates child spans for the critical attach functions for each network being created. Goes along with containernetworking/cni#1173 to provide end-to-end traces for setting up CNI. Signed-off-by: JP Phillips <[email protected]>
1 parent 784f94e commit 7dfe3e1

File tree

5 files changed

+142
-36
lines changed

5 files changed

+142
-36
lines changed

cni.go

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ import (
2828
"github.com/containernetworking/cni/pkg/types"
2929
types100 "github.com/containernetworking/cni/pkg/types/100"
3030
"github.com/containernetworking/cni/pkg/version"
31+
"go.opentelemetry.io/otel"
32+
"go.opentelemetry.io/otel/attribute"
33+
"go.opentelemetry.io/otel/codes"
34+
"go.opentelemetry.io/otel/trace"
3135
)
3236

3337
type CNI interface {
@@ -86,6 +90,10 @@ type libcni struct {
8690
RWMutex
8791
}
8892

93+
func tracer() trace.Tracer {
94+
return otel.Tracer("github.com/containerd/go-cni")
95+
}
96+
8997
func defaultCNIConfig() *libcni {
9098
return &libcni{
9199
config: config{
@@ -165,6 +173,14 @@ func (c *libcni) Networks() []*Network {
165173

166174
// Setup setups the network in the namespace and returns a Result
167175
func (c *libcni) Setup(ctx context.Context, id string, path string, opts ...NamespaceOpts) (*Result, error) {
176+
ctx, span := tracer().Start(ctx, "cni.Setup",
177+
trace.WithAttributes(
178+
attribute.String("cni.id", id),
179+
attribute.String("cni.path", path),
180+
),
181+
)
182+
defer span.End()
183+
168184
c.RLock()
169185
defer c.RUnlock()
170186
if err := c.ready(); err != nil {
@@ -183,6 +199,14 @@ func (c *libcni) Setup(ctx context.Context, id string, path string, opts ...Name
183199

184200
// SetupSerially setups the network in the namespace and returns a Result
185201
func (c *libcni) SetupSerially(ctx context.Context, id string, path string, opts ...NamespaceOpts) (*Result, error) {
202+
ctx, span := tracer().Start(ctx, "cni.SetupSerially",
203+
trace.WithAttributes(
204+
attribute.String("cni.id", id),
205+
attribute.String("cni.path", path),
206+
),
207+
)
208+
defer span.End()
209+
186210
c.RLock()
187211
defer c.RUnlock()
188212
if err := c.ready(); err != nil {
@@ -202,7 +226,22 @@ func (c *libcni) SetupSerially(ctx context.Context, id string, path string, opts
202226
func (c *libcni) attachNetworksSerially(ctx context.Context, ns *Namespace) ([]*types100.Result, error) {
203227
var results []*types100.Result
204228
for _, network := range c.networks {
205-
r, err := network.Attach(ctx, ns)
229+
r, err := func() (*types100.Result, error) {
230+
ctx, span := tracer().Start(ctx, "cni.attachNetworksSerially",
231+
trace.WithAttributes(
232+
attribute.String("cni.ifname", network.ifName),
233+
attribute.String("cni.name", network.config.Name),
234+
),
235+
)
236+
defer func() {
237+
span.End()
238+
}()
239+
r, err := network.Attach(ctx, ns)
240+
if err != nil {
241+
span.SetStatus(codes.Error, err.Error())
242+
}
243+
return r, err
244+
}()
206245
if err != nil {
207246
return nil, err
208247
}
@@ -218,8 +257,11 @@ type asynchAttachResult struct {
218257
}
219258

220259
func asynchAttach(ctx context.Context, index int, n *Network, ns *Namespace, wg *sync.WaitGroup, rc chan asynchAttachResult) {
221-
defer wg.Done()
260+
wg.Done()
222261
r, err := n.Attach(ctx, ns)
262+
if err != nil {
263+
trace.SpanFromContext(ctx).SetStatus(codes.Error, err.Error())
264+
}
223265
rc <- asynchAttachResult{index: index, res: r, err: err}
224266
}
225267

@@ -231,7 +273,17 @@ func (c *libcni) attachNetworks(ctx context.Context, ns *Namespace) ([]*types100
231273

232274
for i, network := range c.networks {
233275
wg.Add(1)
234-
go asynchAttach(ctx, i, network, ns, &wg, rc)
276+
go func() {
277+
ctx, span := tracer().Start(ctx, "cni.asynchAttach",
278+
trace.WithAttributes(
279+
attribute.Int("cni.index", i),
280+
attribute.String("cni.ifname", network.ifName),
281+
attribute.String("cni.name", network.config.Name),
282+
),
283+
)
284+
defer span.End()
285+
asynchAttach(ctx, i, network, ns, &wg, rc)
286+
}()
235287
}
236288

237289
for range c.networks {
@@ -248,6 +300,14 @@ func (c *libcni) attachNetworks(ctx context.Context, ns *Namespace) ([]*types100
248300

249301
// Remove removes the network config from the namespace
250302
func (c *libcni) Remove(ctx context.Context, id string, path string, opts ...NamespaceOpts) error {
303+
ctx, span := tracer().Start(ctx, "cni.Remove",
304+
trace.WithAttributes(
305+
attribute.String("cni.id", id),
306+
attribute.String("cni.path", path),
307+
),
308+
)
309+
defer span.End()
310+
251311
c.RLock()
252312
defer c.RUnlock()
253313
if err := c.ready(); err != nil {
@@ -278,6 +338,14 @@ func (c *libcni) Remove(ctx context.Context, id string, path string, opts ...Nam
278338

279339
// Check checks if the network is still in desired state
280340
func (c *libcni) Check(ctx context.Context, id string, path string, opts ...NamespaceOpts) error {
341+
ctx, span := tracer().Start(ctx, "cni.Check",
342+
trace.WithAttributes(
343+
attribute.String("cni.id", id),
344+
attribute.String("cni.path", path),
345+
),
346+
)
347+
defer span.End()
348+
281349
c.RLock()
282350
defer c.RUnlock()
283351
if err := c.ready(); err != nil {

go.mod

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
module github.com/containerd/go-cni
22

3-
go 1.21
3+
go 1.23.0
44

55
require (
66
github.com/containernetworking/cni v1.3.0
77
github.com/sasha-s/go-deadlock v0.3.5
8-
github.com/stretchr/testify v1.8.0
8+
github.com/stretchr/testify v1.11.1
9+
go.opentelemetry.io/otel v1.38.0
10+
go.opentelemetry.io/otel/trace v1.38.0
911
)
1012

1113
require (
1214
github.com/davecgh/go-spew v1.1.1 // indirect
15+
github.com/go-logr/logr v1.4.3 // indirect
16+
github.com/go-logr/stdr v1.2.2 // indirect
1317
github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // indirect
1418
github.com/pmezard/go-difflib v1.0.0 // indirect
15-
github.com/stretchr/objx v0.4.0 // indirect
19+
github.com/stretchr/objx v0.5.2 // indirect
20+
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
21+
go.opentelemetry.io/otel/metric v1.38.0 // indirect
1622
gopkg.in/yaml.v3 v3.0.1 // indirect
1723
)

go.sum

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
11
github.com/containernetworking/cni v1.3.0 h1:v6EpN8RznAZj9765HhXQrtXgX+ECGebEYEmnuFjskwo=
22
github.com/containernetworking/cni v1.3.0/go.mod h1:Bs8glZjjFfGPHMw6hQu82RUgEPNGEaBb9KS5KtNMnJ4=
3-
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
43
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
54
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
6-
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
7-
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
5+
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
6+
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
7+
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
8+
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
9+
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
810
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
911
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
10-
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
11-
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
12+
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
13+
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
1214
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k=
1315
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
16+
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
17+
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
18+
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
19+
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
1420
github.com/onsi/ginkgo/v2 v2.20.1 h1:YlVIbqct+ZmnEph770q9Q7NVAz4wwIiVNahee6JyUzo=
1521
github.com/onsi/ginkgo/v2 v2.20.1/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI=
1622
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
@@ -19,16 +25,24 @@ github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 h1:Dx7Ovyv/SFnMFw
1925
github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
2026
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
2127
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
28+
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
29+
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
2230
github.com/sasha-s/go-deadlock v0.3.5 h1:tNCOEEDG6tBqrNDOX35j/7hL5FcFViG6awUGROb2NsU=
2331
github.com/sasha-s/go-deadlock v0.3.5/go.mod h1:bugP6EGbdGYObIlx7pUZtWqlvo8k9H6vCBBsiChJQ5U=
24-
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
25-
github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
26-
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
27-
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
28-
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
29-
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
32+
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
33+
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
34+
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
35+
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
3036
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
3137
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
38+
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
39+
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
40+
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
41+
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
42+
go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
43+
go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
44+
go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
45+
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
3246
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
3347
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
3448
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
@@ -39,8 +53,8 @@ golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
3953
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
4054
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
4155
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
42-
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
4356
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
44-
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
57+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
58+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
4559
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
4660
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

integration/go.mod

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,27 @@
11
module github.com/containerd/go-cni/integration
22

3-
go 1.21
3+
go 1.23.0
44

55
require (
66
github.com/containerd/continuity v0.2.2
77
github.com/containerd/go-cni v0.0.0-00010101000000-000000000000
8-
github.com/stretchr/testify v1.8.0
8+
github.com/stretchr/testify v1.11.1
99
)
1010

1111
require (
1212
github.com/Microsoft/go-winio v0.5.1 // indirect
1313
github.com/containernetworking/cni v1.3.0 // indirect
1414
github.com/davecgh/go-spew v1.1.1 // indirect
15+
github.com/go-logr/logr v1.4.3 // indirect
16+
github.com/go-logr/stdr v1.2.2 // indirect
1517
github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // indirect
1618
github.com/pmezard/go-difflib v1.0.0 // indirect
1719
github.com/sasha-s/go-deadlock v0.3.5 // indirect
1820
github.com/sirupsen/logrus v1.7.0 // indirect
21+
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
22+
go.opentelemetry.io/otel v1.38.0 // indirect
23+
go.opentelemetry.io/otel/metric v1.38.0 // indirect
24+
go.opentelemetry.io/otel/trace v1.38.0 // indirect
1925
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a // indirect
2026
golang.org/x/sys v0.23.0 // indirect
2127
gopkg.in/yaml.v3 v3.0.1 // indirect

0 commit comments

Comments
 (0)