Skip to content

Commit 54137f6

Browse files
mikearnaldieffect-bot
authored andcommitted
Automatically set otel parent when present as external span (#5433)
1 parent 8ea2029 commit 54137f6

File tree

4 files changed

+41
-8
lines changed

4 files changed

+41
-8
lines changed

.changeset/giant-clowns-relax.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@effect/opentelemetry": minor
3+
"effect": minor
4+
---
5+
6+
Automatically set otel parent when present as external span

packages/effect/src/Tracer.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ export interface Tracer {
3131
context: Context.Context<never>,
3232
links: ReadonlyArray<SpanLink>,
3333
startTime: bigint,
34-
kind: SpanKind
34+
kind: SpanKind,
35+
options?: SpanOptions
3536
): Span
3637
context<X>(f: () => X, fiber: Fiber.RuntimeFiber<any, any>): X
3738
}

packages/effect/src/internal/core-effect.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2126,7 +2126,8 @@ export const unsafeMakeSpan = <XA, XE>(
21262126
options.context ?? Context.empty(),
21272127
links,
21282128
timingEnabled ? clock.unsafeCurrentTimeNanos() : bigint0,
2129-
options.kind ?? "internal"
2129+
options.kind ?? "internal",
2130+
options
21302131
)
21312132

21322133
if (annotationsFromEnv._tag === "Some") {

packages/opentelemetry/src/internal/tracer.ts

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,21 @@ const kindMap = {
2222
"consumer": OtelApi.SpanKind.CONSUMER
2323
}
2424

25+
const getOtelParent = (tracer: OtelApi.TraceAPI, otelContext: OtelApi.Context, context: Context.Context<never>) => {
26+
const active = tracer.getSpan(otelContext)
27+
const otelParent = active ? active.spanContext() : undefined
28+
return otelParent
29+
? Option.some(
30+
EffectTracer.externalSpan({
31+
spanId: otelParent.spanId,
32+
traceId: otelParent.traceId,
33+
sampled: (otelParent.traceFlags & 1) === 1,
34+
context
35+
})
36+
)
37+
: Option.none()
38+
}
39+
2540
/** @internal */
2641
export class OtelSpan implements EffectTracer.Span {
2742
readonly [OtelSpanTypeId]: typeof OtelSpanTypeId
@@ -32,20 +47,28 @@ export class OtelSpan implements EffectTracer.Span {
3247
readonly traceId: string
3348
readonly attributes = new Map<string, unknown>()
3449
readonly sampled: boolean
50+
readonly parent: Option.Option<EffectTracer.AnySpan>
3551
status: EffectTracer.SpanStatus
3652

3753
constructor(
3854
contextApi: OtelApi.ContextAPI,
55+
traceApi: OtelApi.TraceAPI,
3956
tracer: OtelApi.Tracer,
4057
readonly name: string,
41-
readonly parent: Option.Option<EffectTracer.AnySpan>,
58+
effectParent: Option.Option<EffectTracer.AnySpan>,
4259
readonly context: Context.Context<never>,
4360
readonly links: Array<EffectTracer.SpanLink>,
4461
startTime: bigint,
45-
readonly kind: EffectTracer.SpanKind
62+
readonly kind: EffectTracer.SpanKind,
63+
options?: EffectTracer.SpanOptions
4664
) {
4765
this[OtelSpanTypeId] = OtelSpanTypeId
4866
const active = contextApi.active()
67+
this.parent = effectParent._tag === "Some"
68+
? effectParent
69+
: (options?.root !== true)
70+
? getOtelParent(traceApi, active, context)
71+
: Option.none()
4972
this.span = tracer.startSpan(
5073
name,
5174
{
@@ -58,8 +81,8 @@ export class OtelSpan implements EffectTracer.Span {
5881
: undefined as any,
5982
kind: kindMap[this.kind]
6083
},
61-
parent._tag === "Some"
62-
? populateContext(active, parent.value, context)
84+
this.parent._tag === "Some"
85+
? populateContext(active, this.parent.value, context)
6386
: OtelApi.trace.deleteSpan(active)
6487
)
6588
const spanContext = this.span.spanContext()
@@ -143,16 +166,18 @@ export const Tracer = Context.GenericTag<OtelTracer, OtelApi.Tracer>("@effect/op
143166
/** @internal */
144167
export const make = Effect.map(Tracer, (tracer) =>
145168
EffectTracer.make({
146-
span(name, parent, context, links, startTime, kind) {
169+
span(name, parent, context, links, startTime, kind, options) {
147170
return new OtelSpan(
148171
OtelApi.context,
172+
OtelApi.trace,
149173
tracer,
150174
name,
151175
parent,
152176
context,
153177
links.slice(),
154178
startTime,
155-
kind
179+
kind,
180+
options
156181
)
157182
},
158183
context(execution, fiber) {

0 commit comments

Comments
 (0)