Skip to content

feat: migrate from OpenTracing to native OpenTelemetry APIs#20

Merged
ankurs merged 4 commits intomainfrom
feat/otel-migration
Mar 28, 2026
Merged

feat: migrate from OpenTracing to native OpenTelemetry APIs#20
ankurs merged 4 commits intomainfrom
feat/otel-migration

Conversation

@ankurs
Copy link
Copy Markdown
Member

@ankurs ankurs commented Mar 28, 2026

Summary

Replace all OpenTracing usage with native OpenTelemetry APIs. This removes the deprecated opentracing-go dependency entirely.

What changed

  • tracingSpan now wraps trace.Span (OTEL) instead of opentracing.Span
  • Span creation uses otel.Tracer().Start() instead of opentracing.StartSpanFromContext()
  • SetTag uses span.SetAttributes(attribute.String()) instead of span.SetTag()
  • SetError uses span.SetStatus(codes.Error) + RecordError() instead of tag-based errors
  • Propagation uses otel.GetTextMapPropagator() instead of opentracing.GlobalTracer().Inject/Extract
  • metadataReaderWriter replaced with metadataCarrier implementing propagation.TextMapCarrier
  • ClientSpan returns trace.Span instead of opentracing.Span (breaking for direct callers)

What stays the same

  • Public Span interface (End, Finish, SetTag, SetQuery, SetError) — unchanged
  • NewInternalSpan, NewDatastoreSpan, NewExternalSpan, NewHTTPExternalSpan — same signatures
  • NewRelic dual-reporting preserved alongside OTEL spans
  • Context helpers (CloneContextValues, MergeContextValues) — unchanged

Breaking changes

  • ClientSpan returns (context.Context, trace.Span) instead of (context.Context, opentracing.Span) — only used by interceptors package internally
  • opentracing-go dependency removed — callers importing it transitively via this package will need their own dependency

Dependencies

  • Added: go.opentelemetry.io/otel, otel/trace, otel/attribute, otel/codes, otel/propagation
  • Removed: github.com/opentracing/opentracing-go

Test plan

  • go test -race ./... — all pass
  • make lint — 0 issues, 0 vulnerabilities
  • make doc — READMEs regenerated

Next steps (separate PRs)

  • Phase 2: Update errors/notifier to use OTEL span context
  • Phase 3: Update interceptors to use otelgrpc middleware
  • Phase 4: Update core to flip bridge default to false

Summary by CodeRabbit

  • Refactor
    • Migrated tracing from OpenTracing to OpenTelemetry: spans, attributes, error signaling, and trace propagation updated; HTTP and gRPC propagation now use OpenTelemetry mechanisms.
  • Documentation
    • Updated docs and examples to describe OpenTelemetry-based tracing and backend-agnostic span usage; adjusted indexes and descriptions for clarity.
  • Tests
    • Updated and added tests to align with OpenTelemetry behaviors and propagation carriers.

Replace all OpenTracing usage with native OTEL APIs:
- tracingSpan.openSpan (opentracing.Span) → otelSpan (trace.Span)
- opentracing.StartSpanFromContext → otel.Tracer().Start()
- span.SetTag → span.SetAttributes(attribute.String())
- span.SetError tags → span.SetStatus(codes.Error) + RecordError()
- opentracing.GlobalTracer().Inject/Extract → otel.GetTextMapPropagator()
- metadataReaderWriter → metadataCarrier (propagation.TextMapCarrier)
- ClientSpan returns trace.Span instead of opentracing.Span

Remove opentracing-go dependency entirely. Add OTEL dependencies:
go.opentelemetry.io/otel, trace, attribute, codes, propagation.

Public API preserved: Span interface, NewInternalSpan, NewDatastoreSpan,
NewExternalSpan, NewHTTPExternalSpan, context helpers all unchanged.
NewRelic dual-reporting preserved alongside OTEL spans.
Copilot AI review requested due to automatic review settings March 28, 2026 01:12
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 28, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e12faf98-bc2b-46c7-995b-c7deb7524120

📥 Commits

Reviewing files that changed from the base of the PR and between 483fbf1 and d116038.

📒 Files selected for processing (1)
  • tracing.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • tracing.go

📝 Walkthrough

Walkthrough

Replaces OpenTracing with OpenTelemetry across docs, implementation, tests, and dependency manifest: spans now use oteltrace.Span with End(), tags become OTEL attributes/status/error recordings, and HTTP/gRPC propagation uses OpenTelemetry propagators.

Changes

Cohort / File(s) Summary
Documentation
README.md, doc.go
Replaced OpenTracing wording and examples with OpenTelemetry; updated signatures/anchors to return oteltrace.Span and adjusted section text/line references.
Dependencies
go.mod
Removed github.com/opentracing/opentracing-go; added go.opentelemetry.io/otel, go.opentelemetry.io/otel/trace and related OTel indirect deps.
Core Implementation
tracing.go
Reworked spans to use oteltrace.Span and otel.Tracer(...).Start(...)/End(), converted tags to OTEL attributes (toAttributeSetAttributes), use SetStatus/RecordError, set datastore/external attributes, replaced OpenTracing propagation/inject/extract with OpenTelemetry propagators, added tracerName const and metadata carrier adaptations.
gRPC Propagation
tracing.go (GRPCTracingSpan, metadataCarrier)
Extracts context from incoming gRPC metadata via OTEL propagator, starts server span with SpanKindServer, and injects context back into outgoing metadata using the same carrier.
HTTP Propagation
tracing.go (NewHTTPExternalSpan)
Replaced OpenTracing header injection with otel.GetTextMapPropagator().Inject(...) into provided http.Header when non-nil.
Tests
tracing_test.go
Updated tests to use End() instead of Finish(), added TestNewHTTPExternalSpan, replaced MetadataReaderWriter test with metadataCarrier tests (narrowed coverage), and adjusted comments/assertions for noop tracer behavior.

Sequence Diagram(s)

sequenceDiagram
    participant Client as "Application Handler"
    participant gRPC_Server as "gRPC Server"
    participant metadataCarrier as "metadataCarrier"
    participant Propagator as "OTel Propagator"
    participant Tracer as "otel.Tracer"

    Client->>gRPC_Server: incoming RPC with metadata
    gRPC_Server->>metadataCarrier: wrap incoming metadata
    metadataCarrier->>Propagator: Extract trace context
    Propagator->>Tracer: provide context for Start
    Tracer->>gRPC_Server: return server span + context (SpanKindServer)
    gRPC_Server->>Propagator: prepare outgoing metadata
    Propagator->>metadataCarrier: Inject trace context
    metadataCarrier->>Client: outgoing metadata with trace context
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 I hopped from opentrace to OTel light,
Attributes gleam and spans end right.
Propagators carry the thread so thin,
Metadata whispers — trace flows in.
A rabbit bows, End() — and we win!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately and concisely describes the main objective of the changeset: migrating the entire codebase from OpenTracing to native OpenTelemetry APIs, which is the central theme of all modifications across README.md, go.mod, tracing.go, tracing_test.go, and doc.go.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/otel-migration

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Migrates the tracing package off deprecated OpenTracing usage and onto native OpenTelemetry APIs while preserving the existing public Span abstraction and New Relic dual-reporting.

Changes:

  • Replaced OpenTracing spans/propagation with OpenTelemetry trace.Span and otel.GetTextMapPropagator().
  • Updated gRPC metadata propagation to use an OTEL TextMapCarrier adapter.
  • Updated tests, docs, and module dependencies to remove opentracing-go and add OTEL modules.

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tracing.go Swaps the underlying span implementation to OTEL, updates span creation/attributes/status, and updates HTTP + gRPC propagation.
tracing_test.go Updates unit tests for OTEL spans and new metadata carrier; adds HTTP external span test.
go.mod Removes opentracing-go and adds OTEL requirements.
go.sum Updates dependency checksums to reflect OTEL + indirect deps.
README.md Regenerated docs reflecting signature changes (e.g., ClientSpan return type).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
tracing_test.go (1)

21-24: These new OTEL tests are still effectively no-ops.

TestNewInternalSpan never asserts on the IsValid branch, and TestNewHTTPExternalSpan only checks for non-nil returns. With the default noop tracer provider/propagator, both pass even if context attachment or header injection breaks. Please install a test tracer provider plus propagation.TraceContext{} and assert a valid span context / traceparent round-trip.

Also applies to: 134-145

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tracing_test.go` around lines 21 - 24, Tests TestNewInternalSpan and
TestNewHTTPExternalSpan are no-ops because they rely on the default noop
tracer/propagator; install a test tracer provider (e.g., the oteltest or sdk
trace test provider) and set propagation.TraceContext{} as the global propagator
before running the tests, then in TestNewInternalSpan assert
oteltrace.SpanFromContext(newCtx).SpanContext().IsValid() is true, and in
TestNewHTTPExternalSpan assert that the injected header (e.g., "traceparent")
round-trips by extracting it back with the same TraceContext propagator and
confirming the extracted span context is valid; update the test setup/teardown
to restore global tracer/provider and propagator after the tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tracing.go`:
- Around line 249-252: The change to have ClientSpan return oteltrace.Span (via
clientSpanOTEL) is a compile-time breaking API change; either bump the module
major version in go.mod to v2 (update the module path to include /v2) or
increment the support package version constant (e.g., change
SupportPackageIsVersion1 to the next sentinel) so consumers fail fast; update
module versioning and any relevant documentation/release notes to indicate this
explicit compatibility break and ensure ClientSpan and clientSpanOTEL signatures
are reflected consistently across the package.
- Around line 74-79: In tracingSpan.SetTag, avoid stringifying every tag before
calling span.otelSpan.SetAttributes: inspect the runtime type of value and call
the matching OTEL attribute constructor (attribute.Int64, attribute.Bool,
attribute.Float64, etc.), falling back to attribute.String(fmt.Sprint(value))
only for unsupported types; keep the existing AWS/AddAttribute calls unchanged
so datastore/segment behavior remains the same and ensure the attribute passed
into span.otelSpan.SetAttributes uses the typed attribute you constructed.
- Around line 257-277: GRPCTracingSpan currently copies the full incoming
metadata (md.Copy()) and reuses it as the outgoing carrier, which can leak
sensitive headers; change it to extract the trace context from the incoming
metadata using metadataCarrier(md) but create a fresh outgoing metadata.MD{}
(e.g. mdOut := metadata.MD{}) and call prop.Inject(ctx, metadataCarrier(mdOut)),
then set ctx = metadata.NewOutgoingContext(ctx, mdOut) instead of reusing the
copied incoming md; keep the Start call and use metadataCarrier for extraction
only (references: function GRPCTracingSpan, metadataCarrier, tracerName).

---

Nitpick comments:
In `@tracing_test.go`:
- Around line 21-24: Tests TestNewInternalSpan and TestNewHTTPExternalSpan are
no-ops because they rely on the default noop tracer/propagator; install a test
tracer provider (e.g., the oteltest or sdk trace test provider) and set
propagation.TraceContext{} as the global propagator before running the tests,
then in TestNewInternalSpan assert
oteltrace.SpanFromContext(newCtx).SpanContext().IsValid() is true, and in
TestNewHTTPExternalSpan assert that the injected header (e.g., "traceparent")
round-trips by extracting it back with the same TraceContext propagator and
confirming the extracted span context is valid; update the test setup/teardown
to restore global tracer/provider and propagator after the tests.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 51102c71-12c2-4d8e-b970-669943691a8a

📥 Commits

Reviewing files that changed from the base of the PR and between b0465a0 and 2f7f204.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (4)
  • README.md
  • go.mod
  • tracing.go
  • tracing_test.go

- SetTag now preserves value types (int, float64, bool, string) instead
  of stringifying everything via fmt.Sprint
- GRPCTracingSpan: use fresh outgoing metadata instead of reusing
  inbound metadata for downstream propagation
- Remove empty test assertion block
- Regenerate README
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
tracing_test.go (2)

72-89: Broaden TestMetadataCarrier coverage beyond single-key happy path.

Current assertions only validate one key/value path. Consider adding table-driven cases for overwrite behavior and multiple keys to better guard carrier adapter regressions.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tracing_test.go` around lines 72 - 89, Expand TestMetadataCarrier to cover
more cases: add a table-driven set of subtests that exercise metadataCarrier's
Set, Get and Keys for (a) overwriting an existing key (call
metadataCarrier(md).Set("x-request-id","v1") then Set(...,"v2") and assert Get
returns "v2" and Keys contains the key once), (b) multiple distinct keys (set
several keys and assert Get returns each value and Keys contains all keys), and
(c) missing keys (Get returns empty string). Use the existing
TestMetadataCarrier test, the metadataCarrier constructor, and its Set/Get/Keys
methods to implement these subtests. Ensure assertions validate both values and
that Keys length/contents match expectations.

131-143: TestNewHTTPExternalSpan should assert propagation side-effects.

The test only checks non-nil values, but NewHTTPExternalSpan injects OTEL trace context into headers via otel.GetTextMapPropagator().Inject(). Without an explicit propagator configuration, the test relies on the default global propagator (which may be noop), and header injection regressions would go unnoticed. Set a deterministic propagator and assert on the injected header.

Suggested test hardening
 import (
 	"context"
 	"errors"
+	"net/http"
 	"testing"
 
+	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/propagation"
 	"google.golang.org/grpc/metadata"
 )
@@
 func TestNewHTTPExternalSpan(t *testing.T) {
+	prev := otel.GetTextMapPropagator()
+	otel.SetTextMapPropagator(propagation.TraceContext{})
+	defer otel.SetTextMapPropagator(prev)
+
 	ctx := context.Background()
-	hdr := make(map[string][]string)
+	hdr := http.Header{}
 	span, newCtx := NewHTTPExternalSpan(ctx, "external-svc", "/api/data", hdr)
 	if span == nil {
 		t.Fatal("expected non-nil span")
 	}
 	if newCtx == nil {
 		t.Fatal("expected non-nil context")
 	}
-	// Headers may contain trace propagation if a real propagator is configured.
+	if hdr.Get("traceparent") == "" {
+		t.Fatal("expected traceparent header to be injected")
+	}
 	span.End()
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tracing_test.go` around lines 131 - 143, TestNewHTTPExternalSpan currently
only checks non-nil span/context but doesn’t verify that NewHTTPExternalSpan
injects propagation headers via otel.GetTextMapPropagator().Inject; to fix, set
a deterministic global propagator at the start of the test (e.g., use
propagation.TraceContext{} or a known composite) so injection is predictable,
call NewHTTPExternalSpan(ctx, "external-svc", "/api/data", hdr), then assert
that hdr contains the expected propagation key/value (e.g., "traceparent" or the
key your chosen propagator uses) and that its value matches the produced
span/context; afterwards restore the previous global propagator if needed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@README.md`:
- Around line 45-52: Update the README package introduction to consistently
state that tracing uses OpenTelemetry (OTEL) instead of OpenTracing, align
terminology with the documented OTEL types and functions (e.g., ClientSpan and
oteltrace.Span in tracing.go), and then regenerate the docs so the intro,
function descriptions, and examples all reference OTEL APIs and types
consistently.

---

Nitpick comments:
In `@tracing_test.go`:
- Around line 72-89: Expand TestMetadataCarrier to cover more cases: add a
table-driven set of subtests that exercise metadataCarrier's Set, Get and Keys
for (a) overwriting an existing key (call
metadataCarrier(md).Set("x-request-id","v1") then Set(...,"v2") and assert Get
returns "v2" and Keys contains the key once), (b) multiple distinct keys (set
several keys and assert Get returns each value and Keys contains all keys), and
(c) missing keys (Get returns empty string). Use the existing
TestMetadataCarrier test, the metadataCarrier constructor, and its Set/Get/Keys
methods to implement these subtests. Ensure assertions validate both values and
that Keys length/contents match expectations.
- Around line 131-143: TestNewHTTPExternalSpan currently only checks non-nil
span/context but doesn’t verify that NewHTTPExternalSpan injects propagation
headers via otel.GetTextMapPropagator().Inject; to fix, set a deterministic
global propagator at the start of the test (e.g., use propagation.TraceContext{}
or a known composite) so injection is predictable, call NewHTTPExternalSpan(ctx,
"external-svc", "/api/data", hdr), then assert that hdr contains the expected
propagation key/value (e.g., "traceparent" or the key your chosen propagator
uses) and that its value matches the produced span/context; afterwards restore
the previous global propagator if needed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cfc1092b-4244-4032-9a2d-e016fe735726

📥 Commits

Reviewing files that changed from the base of the PR and between 2f7f204 and e930d17.

📒 Files selected for processing (3)
  • README.md
  • tracing.go
  • tracing_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • tracing.go

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 5 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- GRPCTracingSpan: preserve existing outgoing metadata instead of
  replacing it, avoiding loss of non-tracing headers (auth, request-id)
- Fix test: use http.Header instead of map[string][]string
- Update doc.go to describe OTEL (not OpenTracing), regenerate README
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tracing.go (1)

143-153: ⚠️ Potential issue | 🟠 Major

Handle the case where New Relic is not configured.

When NewRelicApp is nil, nrutil.StartNRTransaction() returns the context unchanged (no-op). This means txn remains nil, but the code unconditionally calls txn.StartSegmentNow() on lines 151, 191, and 229, causing a nil pointer panic.

After the transaction fetch-or-start block, check whether txn is still nil. If it is, skip the New Relic segment setup and any subsequent txn.End() or txn.AddAttribute() calls for that transaction, or return an error if the transaction is required.

This applies to all three constructor sites: NewInternalSpan (143–153), NewDatastoreSpan (184–195), and buildExternalSpan (222–231).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tracing.go` around lines 143 - 153, The code calls txn.StartSegmentNow() and
later txn.End()/txn.AddAttribute() without handling the case New Relic is not
configured; update the three constructors NewInternalSpan, NewDatastoreSpan and
buildExternalSpan to check if txn is nil after calling
nrutil.StartNRTransaction(name, ctx, ...) and, if nil, skip creating the
newrelic.Segment and any subsequent txn operations (StartSegmentNow, End,
AddAttribute) for that span (or return early if a transaction is required);
ensure you only call txn.* methods when txn != nil and keep the existing flow
for when txn is present.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tracing.go`:
- Around line 254-257: In NewHTTPExternalSpan, guard against a nil http.Header
before injecting OTEL context: check if hdr == nil and if so initialize it with
hdr = make(http.Header) before calling otel.GetTextMapPropagator().Inject(ctx,
propagation.HeaderCarrier(hdr)); this prevents the "assignment to entry in nil
map" panic when propagation.HeaderCarrier(hdr) is written to after
buildExternalSpan has returned the context.
- Around line 305-310: The metadataCarrier.Get currently returns only the first
value from metadata.MD(mc).Get(key) which discards additional comma-separated
propagation entries; change metadataCarrier.Get to join all values returned by
metadata.MD(mc).Get(key) with commas (preserving original order) and return the
combined string so baggage/tracestate propagation is preserved; locate the Get
method on type metadataCarrier and replace the vals[0] return with a
comma-joined return of vals (handling the zero-length case as before).

---

Outside diff comments:
In `@tracing.go`:
- Around line 143-153: The code calls txn.StartSegmentNow() and later
txn.End()/txn.AddAttribute() without handling the case New Relic is not
configured; update the three constructors NewInternalSpan, NewDatastoreSpan and
buildExternalSpan to check if txn is nil after calling
nrutil.StartNRTransaction(name, ctx, ...) and, if nil, skip creating the
newrelic.Segment and any subsequent txn operations (StartSegmentNow, End,
AddAttribute) for that span (or return early if a transaction is required);
ensure you only call txn.* methods when txn != nil and keep the existing flow
for when txn is present.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cf895193-b0e4-4c0d-9f74-23c08da46e25

📥 Commits

Reviewing files that changed from the base of the PR and between e930d17 and 483fbf1.

📒 Files selected for processing (4)
  • README.md
  • doc.go
  • tracing.go
  • tracing_test.go
✅ Files skipped from review due to trivial changes (1)
  • doc.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • tracing_test.go

- NewHTTPExternalSpan: skip Inject when hdr is nil to avoid panic
- metadataCarrier.Get: join multiple values with comma for W3C
  baggage/tracestate compatibility
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 6 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@@ -191,7 +216,7 @@ func buildExternalSpan(ctx context.Context, name string, url string) (*tracingSp
url = "http://" + name + "/" + url
Copy link

Copilot AI Mar 28, 2026

Choose a reason for hiding this comment

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

buildExternalSpan normalizes url to start with /, then unconditionally prefixes it with "http://" + name + "/", which produces an extra slash for already-normalized paths (e.g. /api becomes http://svc//api). Consider concatenating without the additional / once url is guaranteed to be rooted (or only inserting the / when needed) so the recorded URL is canonical.

Suggested change
url = "http://" + name + "/" + url
url = "http://" + name + url

Copilot uses AI. Check for mistakes.
Comment on lines 6 to 17
"net/http"
"runtime/trace"
"strings"

nrutil "github.com/go-coldbrew/tracing/newrelic"
newrelic "github.com/newrelic/go-agent/v3/newrelic"
opentracing "github.com/opentracing/opentracing-go"
otext "github.com/opentracing/opentracing-go/ext"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/propagation"
oteltrace "go.opentelemetry.io/otel/trace"
"google.golang.org/grpc/metadata"
Copy link

Copilot AI Mar 28, 2026

Choose a reason for hiding this comment

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

ClientSpan now returns oteltrace.Span because go.opentelemetry.io/otel/trace is imported with the local name oteltrace (to avoid clashing with runtime/trace). This leaks the alias into generated docs/README signatures and makes examples harder to copy/paste. Consider aliasing runtime/trace instead (e.g. runtimetrace) and importing OTEL as trace so public signatures render as trace.Span.

Copilot uses AI. Check for mistakes.
require (
github.com/newrelic/go-agent/v3 v3.42.0
github.com/opentracing/opentracing-go v1.2.0
go.opentelemetry.io/otel v1.42.0
Copy link

Copilot AI Mar 28, 2026

Choose a reason for hiding this comment

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

Go modules for OpenTelemetry are typically released in lockstep; here go.opentelemetry.io/otel and go.opentelemetry.io/otel/trace are pinned to v1.42.0, but the dependency graph still pulls in go.opentelemetry.io/otel/sdk v1.39.0 (per go.sum). To reduce the risk of subtle incompatibilities, consider aligning OTEL module versions (e.g., explicitly upgrading otel/sdk/related modules to the same minor) and re-running go mod tidy.

Suggested change
go.opentelemetry.io/otel v1.42.0
go.opentelemetry.io/otel v1.42.0
go.opentelemetry.io/otel/sdk v1.42.0

Copilot uses AI. Check for mistakes.
@ankurs ankurs merged commit 890216e into main Mar 28, 2026
11 checks passed
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