Skip to content

Commit c8c1ae8

Browse files
authored
Merge pull request #5 from runloopai/dines/add-tracing-from-caller
Add tracing from caller
2 parents 09b2766 + 5be56a2 commit c8c1ae8

16 files changed

Lines changed: 683 additions & 50 deletions

cmd/overlaybd-snapshotter/main.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,12 @@ var pconfig *overlaybd.BootConfig
4848
var commitID string = "unknown"
4949

5050
func requestIDInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
51-
requestID := mylog.GenerateRequestID()
51+
requestID := tracing.GetRequestID(ctx)
52+
if requestID == "" {
53+
requestID = mylog.GenerateRequestID()
54+
}
55+
5256
ctx = mylog.WithRequestID(ctx, requestID)
53-
54-
// Add to containerd's logger context
5557
ctx = log.WithLogger(ctx, log.G(ctx).WithField("req_id", requestID))
5658

5759
return handler(ctx, req)
@@ -136,8 +138,12 @@ func main() {
136138
// Initialize random seed for request ID generation
137139
rand.Seed(time.Now().UnixNano())
138140

139-
srv := grpc.NewServer(grpc.UnaryInterceptor(requestIDInterceptor))
140-
snapshotsapi.RegisterSnapshotsServer(srv, tracing.WithTracing(snapshotservice.FromSnapshotter(sn)))
141+
// Use simplified tracing with request ID interceptor
142+
srv := grpc.NewServer(
143+
tracing.WithServerTracing(),
144+
grpc.UnaryInterceptor(requestIDInterceptor),
145+
)
146+
snapshotsapi.RegisterSnapshotsServer(srv, snapshotservice.FromSnapshotter(sn))
141147

142148
address := strings.TrimSpace(pconfig.Address)
143149

go.mod

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,20 @@ require (
2525
github.com/sirupsen/logrus v1.9.3
2626
github.com/spf13/cobra v1.8.1
2727
github.com/urfave/cli/v2 v2.27.6
28-
go.opentelemetry.io/otel v1.35.0
28+
go.opentelemetry.io/otel v1.37.0
2929
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0
3030
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0
31-
go.opentelemetry.io/otel/sdk v1.35.0
32-
go.opentelemetry.io/otel/trace v1.35.0
31+
go.opentelemetry.io/otel/sdk v1.37.0
32+
go.opentelemetry.io/otel/trace v1.37.0
3333
golang.org/x/sync v0.15.0
3434
golang.org/x/sys v0.33.0
35-
google.golang.org/grpc v1.72.2
35+
google.golang.org/grpc v1.73.0
3636
gotest.tools/gotestsum v1.12.3
3737
oras.land/oras-go/v2 v2.5.0
3838
)
3939

40+
require go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect
41+
4042
require (
4143
filippo.io/edwards25519 v1.1.0 // indirect
4244
github.com/Microsoft/go-winio v0.6.2 // indirect
@@ -65,7 +67,7 @@ require (
6567
github.com/felixge/httpsnoop v1.0.4 // indirect
6668
github.com/fsnotify/fsnotify v1.9.0 // indirect
6769
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
68-
github.com/go-logr/logr v1.4.2 // indirect
70+
github.com/go-logr/logr v1.4.3 // indirect
6971
github.com/go-logr/stdr v1.2.2 // indirect
7072
github.com/godbus/dbus/v5 v5.1.0 // indirect
7173
github.com/gogo/protobuf v1.3.2 // indirect
@@ -105,17 +107,18 @@ require (
105107
go.etcd.io/bbolt v1.4.0 // indirect
106108
go.opencensus.io v0.24.0 // indirect
107109
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
110+
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.62.0 // indirect
108111
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect
109-
go.opentelemetry.io/otel/metric v1.35.0 // indirect
112+
go.opentelemetry.io/otel/metric v1.37.0 // indirect
110113
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
111114
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f // indirect
112115
golang.org/x/mod v0.25.0 // indirect
113116
golang.org/x/net v0.41.0 // indirect
114117
golang.org/x/term v0.32.0 // indirect
115118
golang.org/x/text v0.26.0 // indirect
116119
golang.org/x/tools v0.34.0 // indirect
117-
google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a // indirect
118-
google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a // indirect
120+
google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463 // indirect
121+
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
119122
google.golang.org/protobuf v1.36.6 // indirect
120123
gopkg.in/inf.v0 v0.9.1 // indirect
121124
gopkg.in/yaml.v3 v3.0.1 // indirect

go.sum

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8
8787
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
8888
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
8989
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
90-
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
91-
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
90+
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
91+
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
9292
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
9393
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
9494
github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI=
@@ -277,22 +277,24 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
277277
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
278278
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
279279
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
280+
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.62.0 h1:rbRJ8BBoVMsQShESYZ0FkvcITu8X8QNwJogcLUmDNNw=
281+
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.62.0/go.mod h1:ru6KHrNtNHxM4nD/vd6QrLVWgKhxPYgblq4VAtNawTQ=
280282
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU=
281283
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ=
282-
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
283-
go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
284+
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
285+
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
284286
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 h1:1fTNlAIJZGWLP5FVu0fikVry1IsiUnXjf7QFvoNN3Xw=
285287
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0/go.mod h1:zjPK58DtkqQFn+YUMbx0M2XV3QgKU0gS9LeGohREyK4=
286288
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 h1:m639+BofXTvcY1q8CGs4ItwQarYtJPOWmVobfM1HpVI=
287289
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0/go.mod h1:LjReUci/F4BUyv+y4dwnq3h/26iNOeC3wAIqgvTIZVo=
288-
go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
289-
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
290-
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
291-
go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
292-
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
293-
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
294-
go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=
295-
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
290+
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
291+
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
292+
go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
293+
go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg=
294+
go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc=
295+
go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
296+
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
297+
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
296298
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
297299
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
298300
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
@@ -368,17 +370,17 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
368370
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
369371
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
370372
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
371-
google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a h1:nwKuGPlUAt+aR+pcrkfFRrTU1BVrSmYyYMxYbUIVHr0=
372-
google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a/go.mod h1:3kWAYMk1I75K4vykHtKt2ycnOgpA6974V7bREqbsenU=
373-
google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a h1:51aaUVRocpvUOSQKM6Q7VuoaktNIaMCLuhZB6DKksq4=
374-
google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a/go.mod h1:uRxBH1mhmO8PGhU89cMcHaXKZqO+OfakD8QQO0oYwlQ=
373+
google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463 h1:hE3bRWtU6uceqlh4fhrSnUyjKHMKB9KrTLLG+bc0ddM=
374+
google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463/go.mod h1:U90ffi8eUL9MwPcrJylN5+Mk2v3vuPDptd5yyNUiRR8=
375+
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE=
376+
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
375377
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
376378
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
377379
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
378380
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
379381
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
380-
google.golang.org/grpc v1.72.2 h1:TdbGzwb82ty4OusHWepvFWGLgIbNo1/SUynEN0ssqv8=
381-
google.golang.org/grpc v1.72.2/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
382+
google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok=
383+
google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc=
382384
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
383385
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
384386
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=

pkg/tracing/README.md

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
# gRPC Tracing Integration
2+
3+
This package provides OpenTelemetry tracing integration for gRPC calls in the accelerated-container-image project.
4+
5+
## Features
6+
7+
- **Automatic trace propagation**: Trace contexts are automatically propagated between client and server calls
8+
- **Comprehensive tracing**: Both client and server interceptors capture request/response metadata
9+
- **OpenTelemetry integration**: Uses standard OpenTelemetry libraries for compatibility
10+
- **Error handling**: Automatically records errors and sets appropriate span status
11+
12+
## Usage
13+
14+
### Server Setup
15+
16+
The main snapshotter service already includes tracing interceptors:
17+
18+
```go
19+
// Chain interceptors: tracing first, then request ID
20+
interceptors := grpc.ChainUnaryInterceptor(
21+
tracing.UnaryServerInterceptor(),
22+
requestIDInterceptor,
23+
)
24+
srv := grpc.NewServer(interceptors)
25+
```
26+
27+
Or use the convenience function:
28+
29+
```go
30+
srv := grpc.NewServer(tracing.WithServerTracing())
31+
```
32+
33+
### Client Setup
34+
35+
For gRPC clients, add the tracing interceptor:
36+
37+
```go
38+
conn, err := grpc.DialContext(ctx, target,
39+
grpc.WithUnaryInterceptor(tracing.UnaryClientInterceptor()),
40+
// other options...
41+
)
42+
```
43+
44+
Or use the convenience function:
45+
46+
```go
47+
conn, err := grpc.DialContext(ctx, target,
48+
tracing.WithClientTracing(),
49+
// other options...
50+
)
51+
```
52+
53+
### Trace Propagation
54+
55+
Trace IDs automatically propagate from:
56+
1. **Incoming requests** → Server-side processing
57+
2. **Server-side processing** → Outgoing client calls
58+
3. **Client calls** → Downstream services
59+
60+
Example flow:
61+
```
62+
Client Request [trace-id: abc123]
63+
64+
gRPC Server Interceptor [trace-id: abc123]
65+
66+
Snapshotter Service [trace-id: abc123]
67+
68+
Outgoing Client Call [trace-id: abc123]
69+
```
70+
71+
## Trace Attributes
72+
73+
The interceptors automatically add these attributes to spans:
74+
75+
### Common Attributes
76+
- `rpc.system`: "grpc"
77+
- `rpc.service`: Service name (e.g., "containerd.services.snapshots.v1.Snapshots")
78+
- `rpc.method`: Method name (e.g., "Prepare")
79+
- `rpc.grpc.status_code`: gRPC status code
80+
- `rpc.grpc.duration_ms`: Request duration in milliseconds
81+
82+
### Error Handling
83+
- Span status set to ERROR for failed requests
84+
- Error details recorded in span
85+
- gRPC status code captured
86+
87+
## Configuration
88+
89+
Set these environment variables for tracing:
90+
91+
```bash
92+
# Service name for traces
93+
export OTEL_SERVICE_NAME="accelerated-container-image"
94+
95+
# OTLP endpoint (e.g., Jaeger collector)
96+
export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4317"
97+
98+
# Environment tag
99+
export ENVIRONMENT="production"
100+
```
101+
102+
## Baggage API Usage
103+
104+
The implementation includes full support for OpenTelemetry Baggage, allowing you to propagate key-value pairs across service boundaries.
105+
106+
### Setting Baggage Values
107+
108+
```go
109+
import "github.com/containerd/accelerated-container-image/pkg/tracing"
110+
111+
// Set individual values
112+
ctx = tracing.SetRequestID(ctx, "req-12345")
113+
ctx = tracing.SetUserID(ctx, "user-67890")
114+
ctx = tracing.SetOperation(ctx, "prepare-snapshot")
115+
116+
// Set image information
117+
ctx = tracing.SetImageInfo(ctx, "alpine", "3.18")
118+
119+
// Set multiple values at once
120+
baggageMap := map[string]string{
121+
"environment": "production",
122+
"namespace": "default",
123+
"container.id": "container-123",
124+
}
125+
ctx = tracing.SetBaggageFromMap(ctx, baggageMap)
126+
```
127+
128+
### Getting Baggage Values
129+
130+
```go
131+
// Get individual values
132+
requestID := tracing.GetRequestID(ctx)
133+
userID := tracing.GetUserID(ctx)
134+
operation := tracing.GetOperation(ctx)
135+
136+
// Get image information
137+
imageName, imageTag := tracing.GetImageInfo(ctx)
138+
139+
// Get all baggage as a map
140+
allBaggage := tracing.GetBaggageAsMap(ctx)
141+
```
142+
143+
### Automatic Baggage Propagation
144+
145+
Baggage values are automatically:
146+
1. **Extracted** from incoming gRPC metadata
147+
2. **Injected** into outgoing gRPC metadata
148+
3. **Added as span attributes** with `baggage.` prefix
149+
4. **Propagated** through the entire request chain
150+
151+
### Common Baggage Keys
152+
153+
The package defines standard baggage keys:
154+
- `request.id` - Request identifier
155+
- `user.id` - User identifier
156+
- `session.id` - Session identifier
157+
- `operation` - Operation name
158+
- `image.name` - Container image name
159+
- `image.tag` - Container image tag
160+
- `snapshot.key` - Snapshot key
161+
- `container.id` - Container identifier
162+
- `namespace` - Kubernetes namespace
163+
- `environment` - Environment (prod, staging, etc.)
164+
165+
## Integration with Request ID
166+
167+
The request ID interceptor now uses baggage for propagation:
168+
169+
```go
170+
// Check if request ID exists in baggage (from upstream)
171+
requestID := tracing.GetRequestID(ctx)
172+
if requestID == "" {
173+
// Generate new ID if not present
174+
requestID = generateRequestID()
175+
ctx = tracing.SetRequestID(ctx, requestID)
176+
}
177+
```
178+
179+
This ensures request IDs propagate across service boundaries while maintaining backward compatibility.
180+
181+
## Integration with Existing Code
182+
183+
The tracing is integrated with the existing snapshotter service:
184+
185+
1. **Initialization**: `tracing.InitTracer()` sets up OpenTelemetry with baggage propagation
186+
2. **Server interceptor**: Added to gRPC server chain, extracts baggage from metadata
187+
3. **Service wrapper**: `tracing.WithTracing()` wraps the snapshotter service
188+
4. **Client interceptor**: Added to any outgoing gRPC clients, injects baggage into metadata
189+
5. **Baggage utilities**: Helper functions for common baggage operations
190+
191+
This provides comprehensive tracing coverage at both the transport (gRPC) and application (snapshotter operations) levels, with full context propagation via baggage.

pkg/tracing/baggage.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
Copyright The Accelerated Container Image Authors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package tracing
18+
19+
import (
20+
"context"
21+
22+
"go.opentelemetry.io/otel/baggage"
23+
)
24+
25+
// SetRequestID sets the request ID in baggage
26+
func SetRequestID(ctx context.Context, requestID string) context.Context {
27+
member, _ := baggage.NewMember("request.id", requestID)
28+
bag, _ := baggage.FromContext(ctx).SetMember(member)
29+
return baggage.ContextWithBaggage(ctx, bag)
30+
}
31+
32+
// GetRequestID gets the request ID from baggage
33+
func GetRequestID(ctx context.Context) string {
34+
return baggage.FromContext(ctx).Member("request.id").Value()
35+
}

0 commit comments

Comments
 (0)