- Rename file-local thread_local globals to the .clang-tidy convention
(GlobalVariablePrefix "g" + CamelCase), keeping the Tls marker:
tlsPendingTraceId -> gTlsPendingTraceId, tlsPendingConsumed -> gTlsPendingConsumed.
- Add direct includes for opentelemetry trace_id.h / span_id.h (header uses
TraceId/SpanId in signatures) and sdk/trace/id_generator.h (.cpp references
IdGenerator directly) to satisfy misc-include-cleaner.
Both verified clean with clang-tidy against a telemetry-enabled compile DB.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The OTel naming check (Rule F) scans @code doc-comment examples and fails
on string-literal span names; Rule H warns on undefined SpanNames
constants. Replace the literal "subtask" and the undefined
rpc_span::op::dispatch with the defined rpc_span::op::process constant so
the examples model correct API usage.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
OTel distinguishes a span's own context from the thread's
current/ambient context; SpanGuard is unscoped so spanContext()
(own span, default) is what cross-thread childSpan parenting needs,
and threadLocalContext() (static) snapshots RuntimeContext::GetCurrent()
for propagation. Renames captureContext.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The generator's doc said it was 'dormant, caller lands on a later branch'.
Reworded to branch-agnostic language: hashSpan() is the primary caller that
forces the root branch to mint deterministic trace roots.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a custom OTel IdGenerator that returns a thread-local pending trace_id on
the SDK no-parent (root) branch and a random one otherwise, plus a PendingTraceId
RAII guard that pins that id for the next forced-root span and asserts on
destruction that it was consumed. Wire the generator into
TracerProviderFactory::Create via its 4-arg overload.
This lets hash-derived spans become true trace roots so they line up into one
trace across nodes. It is installed but dormant on this branch: the caller
(hashSpan) arrives on a later branch (phase-3). GenerateSpanId is always random
and is_random_ is false so the W3C random-trace-id flag is not set on
deterministic ids.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Separate the two responsibilities the old SpanGuard fused: span ownership
(thread-free) and scope activation (thread-bound TLS push).
- SpanGuard now owns ONLY the span. Its Impl drops the optional<Scope>,
the owner thread-id, the Detached tag and the scope-less ctor; ~Impl is
just `if (span) span->End()`. The guard never binds a thread-local
context stack, so it may be moved to and destroyed on any thread.
- ScopedSpanGuard is a new pimpl type that wraps a SpanGuard plus an
optional<Scope>. Member order (guard first, scope second) pops the
scope before the span ends. It is non-copyable and non-movable;
factories return unnamed temporaries so guaranteed copy elision covers
`auto s = ScopedSpanGuard::freshRoot(...)`.
- `operator SpanGuard() &&` replaces detached()/detachInPlace(): it pops
the scope eagerly on the origin thread and yields a thread-free
SpanGuard for handoff to a job or another thread. detached(),
detachInPlace() (both overloads) and the Detached apparatus are deleted.
- Move-assignment is re-enabled on SpanGuard (no Scope to re-bind), in
both the real class and the no-op stub.
- rootSpan() renamed to freshRoot() in both classes (behavior unchanged:
still forces kIsRootSpanKey).
- hashSpan behavior is intentionally unchanged (only builds the now
unscoped Impl); the true-root IdGenerator fix is a separate later task.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>