Skip to content

Commit 20fc9dc

Browse files
authored
Merge pull request #2 from runloopai/dines/adding-tracing
Add OTEL tracing
2 parents fb3362a + c758d9c commit 20fc9dc

File tree

15 files changed

+1399
-17
lines changed

15 files changed

+1399
-17
lines changed

README.md

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,49 @@ docker run overlaybd-convertor -r registry.hub.docker.com/library/redis -i 6.2.1
9898

9999
* See how to use TurboOCIv1 at [TurboOCIv1](docs/TURBO_OCI.md).
100100

101-
* Welcome to contribute! [CONTRIBUTING](docs/CONTRIBUTING.md)
101+
* See how to use OpenTelemetry tracing at [TRACING](docs/TRACING.md).
102+
103+
## Testing
104+
105+
The project uses Go's standard testing framework. To run the tests:
106+
107+
```bash
108+
# Run all tests
109+
go test ./...
110+
111+
# Run tests for a specific package
112+
go test ./pkg/tracing/...
113+
114+
# Run tests with verbose output
115+
go test -v ./...
116+
117+
# Run tests and show code coverage
118+
go test -cover ./...
119+
120+
# Run tests and generate coverage report
121+
go test -coverprofile=coverage.out ./...
122+
go tool cover -html=coverage.out # View coverage in browser
123+
```
124+
125+
### Test Requirements
126+
127+
Some tests require specific setup:
128+
129+
- **Tracing Tests**: No external setup needed. Tests use in-memory tracing.
130+
- **Integration Tests**: Uses in-memory gRPC server, no external setup needed.
131+
- **Snapshotter Tests**: Requires root privileges for some tests. Run with `sudo` if needed.
132+
133+
### Writing Tests
134+
135+
When contributing new code:
136+
137+
1. Add unit tests for new packages in `*_test.go` files
138+
2. Add integration tests for new features
139+
3. Follow existing test patterns in the codebase
140+
4. Use table-driven tests where appropriate
141+
5. Ensure tests are deterministic and don't depend on external services
142+
143+
For more details on contributing, see [CONTRIBUTING](docs/CONTRIBUTING.md).
102144

103145
## Release Version Support
104146

cmd/convertor/main.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525

2626
"github.com/containerd/accelerated-container-image/cmd/convertor/builder"
2727
"github.com/containerd/accelerated-container-image/cmd/convertor/database"
28+
"github.com/containerd/accelerated-container-image/pkg/tracing"
2829
"github.com/containerd/containerd/v2/core/remotes"
2930
_ "github.com/go-sql-driver/mysql"
3031
"github.com/sirupsen/logrus"
@@ -359,11 +360,28 @@ func init() {
359360
}
360361

361362
func main() {
363+
ctx := context.Background()
364+
365+
// Initialize OpenTelemetry
366+
shutdown, err := tracing.InitTracer(ctx)
367+
if err != nil {
368+
logrus.Errorf("Failed to initialize tracer: %v", err)
369+
os.Exit(1)
370+
}
371+
defer func() {
372+
if err := shutdown(ctx); err != nil {
373+
logrus.Errorf("Failed to shutdown tracer: %v", err)
374+
}
375+
}()
376+
362377
sigChan := make(chan os.Signal, 1)
363378
signal.Notify(sigChan, os.Interrupt)
364379

365380
go func() {
366381
<-sigChan
382+
if err := shutdown(context.Background()); err != nil {
383+
logrus.Errorf("Failed to shutdown tracer: %v", err)
384+
}
367385
os.Exit(0)
368386
}()
369387

cmd/overlaybd-snapshotter/main.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
mylog "github.com/containerd/accelerated-container-image/internal/log"
3232
"github.com/containerd/accelerated-container-image/pkg/metrics"
3333
overlaybd "github.com/containerd/accelerated-container-image/pkg/snapshot"
34+
"github.com/containerd/accelerated-container-image/pkg/tracing"
3435

3536
snapshotsapi "github.com/containerd/containerd/api/services/snapshots/v1"
3637
"github.com/containerd/containerd/v2/contrib/snapshotservice"
@@ -72,6 +73,20 @@ func parseConfig(fpath string) error {
7273

7374
// TODO: use github.com/urfave/cli/v2
7475
func main() {
76+
ctx := context.Background()
77+
78+
// Initialize OpenTelemetry
79+
shutdown, err := tracing.InitTracer(ctx)
80+
if err != nil {
81+
logrus.Errorf("Failed to initialize tracer: %v", err)
82+
os.Exit(1)
83+
}
84+
defer func() {
85+
if err := shutdown(ctx); err != nil {
86+
logrus.Errorf("Failed to shutdown tracer: %v", err)
87+
}
88+
}()
89+
7590
pconfig = overlaybd.DefaultBootConfig()
7691
fnConfig := defaultConfigPath
7792
if len(os.Args) == 2 {
@@ -122,7 +137,7 @@ func main() {
122137
rand.Seed(time.Now().UnixNano())
123138

124139
srv := grpc.NewServer(grpc.UnaryInterceptor(requestIDInterceptor))
125-
snapshotsapi.RegisterSnapshotsServer(srv, snapshotservice.FromSnapshotter(sn))
140+
snapshotsapi.RegisterSnapshotsServer(srv, tracing.WithTracing(snapshotservice.FromSnapshotter(sn)))
126141

127142
address := strings.TrimSpace(pconfig.Address)
128143

docs/TRACING.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# OpenTelemetry Tracing Support
2+
3+
The accelerated-container-image project includes OpenTelemetry (OTEL) tracing support to help monitor and debug image conversion operations. This document describes how to use and configure tracing in the project.
4+
5+
## Overview
6+
7+
Tracing is implemented using OpenTelemetry, which provides detailed insights into the image conversion process. Key operations that are traced include:
8+
9+
- Overall image conversion process
10+
- Layer conversion operations
11+
- Individual layer application and processing
12+
- Remote layer operations (when using remote storage)
13+
14+
## Configuration
15+
16+
Tracing can be configured using standard OpenTelemetry environment variables:
17+
18+
- `OTEL_SERVICE_NAME`: Sets the service name for traces (default: "accelerated-container-image")
19+
- `OTEL_EXPORTER_OTLP_ENDPOINT`: The endpoint where traces should be sent (e.g., "http://localhost:4317")
20+
- `OTEL_EXPORTER_OTLP_PROTOCOL`: The protocol to use (default: "grpc")
21+
- `ENVIRONMENT`: The environment name to be included in traces (e.g., "production", "staging")
22+
23+
## Key Spans and Attributes
24+
25+
The following spans are created during image conversion:
26+
27+
### Convert Operation
28+
- Name: `Convert`
29+
- Attributes:
30+
- `fsType`: The filesystem type being used
31+
- `layerCount`: Number of layers in the source image
32+
33+
### Layer Conversion
34+
- Name: `convertLayers`
35+
- Attributes:
36+
- `fsType`: The filesystem type being used
37+
- `layerCount`: Number of layers to convert
38+
39+
### Layer Application
40+
- Name: `applyOCIV1LayerInObd`
41+
- Attributes:
42+
- `layerDigest`: The digest of the layer being applied
43+
- `layerSize`: Size of the layer in bytes
44+
- `parentID`: ID of the parent snapshot
45+
46+
## Example Usage
47+
48+
1. Start your OpenTelemetry collector:
49+
```bash
50+
docker run -d --name otel-collector \
51+
-p 4317:4317 \
52+
-p 4318:4318 \
53+
otel/opentelemetry-collector-contrib
54+
```
55+
56+
2. Set the required environment variables:
57+
```bash
58+
export OTEL_SERVICE_NAME="accelerated-container-image"
59+
export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4317"
60+
export ENVIRONMENT="development"
61+
```
62+
63+
3. Run the image conversion as normal. Traces will be automatically collected and sent to your configured endpoint.
64+
65+
## Viewing Traces
66+
67+
Traces can be viewed in any OpenTelemetry-compatible tracing backend, such as:
68+
- Jaeger
69+
- Zipkin
70+
- Grafana Tempo
71+
- Cloud provider tracing services (e.g., AWS X-Ray, Google Cloud Trace)
72+
73+
## Troubleshooting
74+
75+
If you're not seeing traces:
76+
77+
1. Verify your OpenTelemetry collector is running and accessible
78+
2. Check that the `OTEL_EXPORTER_OTLP_ENDPOINT` is correctly configured
79+
3. Enable debug logging with the `--verbose` flag to see more detailed output
80+
4. Check your collector's logs for any connection or configuration issues

go.mod

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ require (
3636
github.com/Microsoft/go-winio v0.6.2 // indirect
3737
github.com/Microsoft/hcsshim v0.13.0 // indirect
3838
github.com/beorn7/perks v1.0.1 // indirect
39+
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
3940
github.com/cespare/xxhash/v2 v2.3.0 // indirect
4041
github.com/cilium/ebpf v0.16.0 // indirect
4142
github.com/containerd/cgroups/v3 v3.0.5 // indirect
@@ -61,6 +62,8 @@ require (
6162
github.com/gogo/protobuf v1.3.2 // indirect
6263
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
6364
github.com/google/go-cmp v0.7.0 // indirect
65+
github.com/google/uuid v1.6.0 // indirect
66+
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 // indirect
6467
github.com/inconshreveable/mousetrap v1.1.0 // indirect
6568
github.com/intel/goresctrl v0.8.0 // indirect
6669
github.com/klauspost/compress v1.18.0 // indirect
@@ -92,12 +95,17 @@ require (
9295
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
9396
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect
9497
go.opentelemetry.io/otel v1.35.0 // indirect
98+
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 // indirect
99+
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 // indirect
95100
go.opentelemetry.io/otel/metric v1.35.0 // indirect
101+
go.opentelemetry.io/otel/sdk v1.35.0 // indirect
96102
go.opentelemetry.io/otel/trace v1.35.0 // indirect
103+
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
97104
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f // indirect
98105
golang.org/x/mod v0.24.0 // indirect
99106
golang.org/x/net v0.38.0 // indirect
100107
golang.org/x/text v0.23.0 // indirect
108+
google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a // indirect
101109
google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a // indirect
102110
google.golang.org/protobuf v1.36.6 // indirect
103111
gopkg.in/inf.v0 v0.9.1 // indirect

go.sum

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
1212
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
1313
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
1414
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
15+
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
16+
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
1517
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
1618
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
1719
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
@@ -127,6 +129,8 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
127129
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
128130
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
129131
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
132+
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 h1:e9Rjr40Z98/clHv5Yg79Is0NtosR5LXRvdr7o/6NwbA=
133+
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1/go.mod h1:tIxuGz/9mpox++sgp9fJjHO0+q1X9/UOWd798aAm22M=
130134
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
131135
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
132136
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
@@ -264,6 +268,10 @@ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRND
264268
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ=
265269
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
266270
go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
271+
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 h1:1fTNlAIJZGWLP5FVu0fikVry1IsiUnXjf7QFvoNN3Xw=
272+
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0/go.mod h1:zjPK58DtkqQFn+YUMbx0M2XV3QgKU0gS9LeGohREyK4=
273+
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 h1:m639+BofXTvcY1q8CGs4ItwQarYtJPOWmVobfM1HpVI=
274+
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0/go.mod h1:LjReUci/F4BUyv+y4dwnq3h/26iNOeC3wAIqgvTIZVo=
267275
go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
268276
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
269277
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
@@ -272,6 +280,8 @@ go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5J
272280
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
273281
go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=
274282
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
283+
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
284+
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
275285
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
276286
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
277287
go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA=
@@ -341,6 +351,9 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
341351
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
342352
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
343353
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
354+
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY=
355+
google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a h1:nwKuGPlUAt+aR+pcrkfFRrTU1BVrSmYyYMxYbUIVHr0=
356+
google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a/go.mod h1:3kWAYMk1I75K4vykHtKt2ycnOgpA6974V7bREqbsenU=
344357
google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a h1:51aaUVRocpvUOSQKM6Q7VuoaktNIaMCLuhZB6DKksq4=
345358
google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a/go.mod h1:uRxBH1mhmO8PGhU89cMcHaXKZqO+OfakD8QQO0oYwlQ=
346359
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=

0 commit comments

Comments
 (0)