Skip to content

PoC: bridge Go Auto SDK manual spans#2258

Draft
MrAlias wants to merge 2 commits into
open-telemetry:mainfrom
MrAlias:go-auto-sdk-interop
Draft

PoC: bridge Go Auto SDK manual spans#2258
MrAlias wants to merge 2 commits into
open-telemetry:mainfrom
MrAlias:go-auto-sdk-interop

Conversation

@MrAlias

@MrAlias MrAlias commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

What this is

This is a PoC / steel-thread implementation for making OBI interoperate with manually instrumented Go spans through the same basic mechanism used by go.opentelemetry.io/auto.

I am opening this as a draft because I want maintainers to review the shape of the approach before we split it into smaller production-ready pieces. The goal here is to prove that we can support the full Go OTel API path, including the Auto SDK Span_ended(buf []byte) JSON payload, while preserving OBI's existing fallback behavior when bpf_probe_write_user is not available.

What changed

This adds an opportunistic privileged path for Go manual spans:

  • When OBI has the same permissions required for context propagation / bpf_probe_write_user, it attaches additional Go OTel probes.
  • go.opentelemetry.io/otel/internal/global.(*tracer).newSpan flips the autoSpan flag so the global OTel API routes through go.opentelemetry.io/auto/sdk.
  • go.opentelemetry.io/auto/sdk.(*tracer).start writes parent span context, child span context, and sampled state into the Auto SDK output args.
  • go.opentelemetry.io/auto/sdk.(*span).ended emits the Auto SDK OTLP JSON span payload into a new OBI event.
  • Userspace decodes that OTLP JSON with Collector pdata and exports the decoded ScopeSpans under OBI's resource span.

The existing synthetic manual-span path remains the fallback. There is no user-facing config toggle in this PoC: if OBI has the needed permissions, the richer path should work; otherwise OBI keeps doing what it does today.

Upstream probe references

The BPF code in this PR is intentionally modeled after the go.opentelemetry.io/auto probes:

Why this shape

The important bit is the Auto SDK ended(buf []byte) path. That payload is already OTLP JSON-shaped, and it includes the manual span data we would otherwise have to reconstruct ourselves: attributes, events, links, status, dropped counts, trace state, IDs, kind, timestamps, and scope data.

Instead of hand-modeling all of that in OBI's fixed synthetic span event, this PR treats the Auto SDK payload as the source of truth and lets pdata decode it. That keeps the BPF event simple and gives us much better parity with the Go OTel API.

Fallback behavior

The privileged path is guarded by the same context-propagation capability checks OBI already uses. If the kernel or process permissions do not allow bpf_probe_write_user, OBI's existing integrity-mode override path should continue to fall back to the current synthetic manual span behavior.

This is intentionally not a new config option in this PoC. The model I want to test is: if the operator granted the privilege needed for this support, use it; if not, degrade gracefully.

Known gaps

This is not a final production split yet.

  • The Auto SDK JSON payload is bounded at 16 KiB in this PoC. Larger manual spans are dropped by the BPF event path.
  • OBI does not currently push its userspace sampler decision back into the Auto SDK before recording. We preserve parent sampled state when present and default new roots to sampled.
  • TraceState is not written into Go trace.SpanContext, matching the upstream Auto write_span_context helper behavior, but it is preserved from the Auto SDK JSON payload once emitted.
  • This needs integration coverage with a target app using the global OTel API and Auto SDK manual spans before it should be considered merge-ready.
  • The change should probably be split further after we agree on the shape: offset plumbing, privileged probes, payload event/parser, and exporter path can be separate PRs.

Validation

I validated the steel thread locally with:

make generate
go test ./pkg/ebpf/common ./pkg/export/otel/tracesgen ./pkg/internal/goexec ./pkg/internal/ebpf/gotracer ./cmd/obi

@codecov

codecov Bot commented Jun 5, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 73.07692% with 21 lines in your changes missing coverage. Please review.
✅ Project coverage is 69.74%. Comparing base (f334a82) to head (341a1c3).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
pkg/ebpf/common/go_otel_transform.go 63.04% 12 Missing and 5 partials ⚠️
pkg/export/otel/tracesgen/tracesgen.go 77.77% 3 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2258      +/-   ##
==========================================
- Coverage   69.97%   69.74%   -0.23%     
==========================================
  Files         301      301              
  Lines       38884    38962      +78     
==========================================
- Hits        27209    27174      -35     
- Misses      10152    10256     +104     
- Partials     1523     1532       +9     
Flag Coverage Δ
integration-test 52.14% <17.14%> (-0.03%) ⬇️
integration-test-arm 28.29% <15.38%> (-0.91%) ⬇️
integration-test-vm-5.15-lts 29.94% <17.14%> (+0.06%) ⬆️
integration-test-vm-6.18-lts 29.23% <17.14%> (-0.82%) ⬇️
k8s-integration-test 39.50% <17.14%> (-0.08%) ⬇️
oats-test 37.62% <81.42%> (+0.13%) ⬆️
unittests 62.47% <32.85%> (-0.07%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@grcevski grcevski left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, I like the direction!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants