Skip to content

fix(otel): end spans on non-terminal invocations - #850

Draft
ayushiahjolia wants to merge 1 commit into
mainfrom
fix/otel-831-span-lifecycle
Draft

fix(otel): end spans on non-terminal invocations#850
ayushiahjolia wants to merge 1 commit into
mainfrom
fix/otel-831-span-lifecycle

Conversation

@ayushiahjolia

Copy link
Copy Markdown
Contributor

Issue #, if available:
#831

Description of changes:
Both OTel plugins created a recording Workflow span at invocation start and dropped it un-ended on non-terminal (PENDING/RETRYING) invocations. An un-ended span is never delivered to span processors, so it leaked across warm Lambda invocations and was never exported. In-flight attempt spans (and, in ExecutionOtelPlugin, suspended operation spans) were also left un-ended.

Carry the Workflow span identity as a non-recording span context while the execution is in flight, and create the single recording Workflow span once, at the terminal invocation, backdated to the execution start. End in-flight attempt and suspended operation spans at invocation cleanup; a later invocation that resumes an operation exports it under its own ID rather than reusing the deterministic one, so no two exported spans share a (traceId, spanId). Resolve the non-recording context's sampling decision from the provider's own sampler (resolveWorkflowRoot) so operations are sampled consistently with the eventual root and enrichLogContext() reports the true sampling flag.

Also fixes a latent bug in ExecutionOtelPlugin where onOperationStart firing twice for one operation (internal retry) overwrote the span map and orphaned the first span.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Both OTel plugins created a recording Workflow span at invocation start and
dropped it un-ended on non-terminal (PENDING/RETRYING) invocations. An un-ended
span is never delivered to span processors, so it leaked across warm Lambda
invocations and was never exported. In-flight attempt spans (and, in
ExecutionOtelPlugin, suspended operation spans) were also left un-ended.

Carry the Workflow span identity as a non-recording span context while the
execution is in flight, and create the single recording Workflow span once, at
the terminal invocation, backdated to the execution start. End in-flight
attempt and suspended operation spans at invocation cleanup; a later invocation
that resumes an operation exports it under its own ID rather than reusing the
deterministic one, so no two exported spans share a (traceId, spanId). Resolve
the non-recording context's sampling decision from the provider's own sampler
(resolveWorkflowRoot) so operations are sampled consistently with the eventual
root and enrichLogContext() reports the true sampling flag.

Also fixes a latent bug in ExecutionOtelPlugin where onOperationStart firing
twice for one operation (internal retry) overwrote the span map and orphaned
the first span.

Fixes #831

sim: #831
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.

1 participant