TracingHook
extends Hook
in package
LaunchDarkly feature flag evaluation hook that enriches OpenTelemetry spans with `feature_flag` events whenever a flag is evaluated.
When a LaunchDarkly SDK variation call runs inside an active OpenTelemetry
span, this hook attaches a feature_flag span event carrying the required
semantic-convention attributes (feature_flag.key,
feature_flag.provider.name, feature_flag.context.id) as well as any
enabled optional attributes:
-
feature_flag.result.valuewhen TracingHookOptions::$includeValue is true. The value is serialized per self::serializeValue(). -
feature_flag.result.variationIndexwhen the evaluation produced a variation index (emitted as an integer primitive). -
feature_flag.result.reason.inExperimentwhen the evaluation reason is part of an experiment. Omitted when false. -
feature_flag.set.idwhen an environment ID is available, sourced from TracingHookOptions::$environmentId when configured, or otherwise fromEvaluationSeriesContext::$environmentId(which the LaunchDarkly SDK populates from polling-response metadata when fetching directly from LaunchDarkly). The configuration path takes precedence when both are set.
When no span is active, the hook is a no-op.
Experimental: when TracingHookOptions::$addSpans is enabled,
beforeEvaluation also creates a dedicated OpenTelemetry span named
LDClient.<method> (where <method> is the raw variation method name,
e.g. variation, variationDetail, migrationVariation) that wraps the
variation call. The wrapper span carries only the feature_flag.key and
feature_flag.context.id attributes; all other attributes remain on the
feature_flag span event. afterEvaluation detaches the wrapper span's
context and ends it BEFORE attaching the feature_flag event, so the
event lands on the caller's surrounding span rather than on the wrapper.
The wrapper span and the scope used to restore the caller's context are
threaded between beforeEvaluation and afterEvaluation through the
hook $data array under the reserved keys identified by the
self::DATA_KEY_SPAN and self::DATA_KEY_SCOPE class
constants. Other hooks must not write to those keys. On exit from
afterEvaluation the keys are removed from $data so downstream stages
are not surprised by OpenTelemetry objects in their inputs.
The hook is registered on an LDClient via the SDK's hooks configuration
and is safe to share across threads/requests.
Tags
Table of Contents
- __construct() : mixed
- Construct a tracing hook.
- afterEvaluation() : array<string, mixed>
- Attach a `feature_flag` span event to the currently active span describing the evaluation that just completed.
- beforeEvaluation() : array<string, mixed>
- Experimental. When {@see TracingHookOptions::$addSpans} is enabled, start a wrapper span named `LDClient.<method>` around the upcoming variation call and attach its context so subsequent work is nested beneath it. The wrapper span carries only `feature_flag.key` and `feature_flag.context.id`; all other attributes belong on the `feature_flag` event.
- getMetadata() : Metadata
- Return the hook's identification metadata.
Methods
__construct()
Construct a tracing hook.
public
__construct([TracingHookOptions $options = new TracingHookOptions() ][, TracerInterface|null $tracer = null ]) : mixed
Parameters
- $options : TracingHookOptions = new TracingHookOptions()
-
Configuration for the optional attributes emitted on the
feature_flagevent and for the experimentaladdSpanswrapper-span behavior. Defaults to an options object with all optional features disabled. - $tracer : TracerInterface|null = null
-
Tracer used by the experimental
addSpanspath to create wrapper spans for every variation call. Whennull, a tracer namedlaunchdarklyis acquired from the global OpenTelemetry tracer provider via Globals::tracerProvider(). Primarily a test injection point; production callers should leave thisnull.
Return values
mixed —afterEvaluation()
Attach a `feature_flag` span event to the currently active span describing the evaluation that just completed.
public
afterEvaluation(EvaluationSeriesContext $seriesContext, array<string, mixed> $data, EvaluationDetail $detail) : array<string, mixed>
Runs in this order:
- If TracingHookOptions::$addSpans is enabled and
beforeEvaluationstashed a wrapper span and scope under the reserved$datakeys, detach the scope then end the wrapper span. This MUST happen before step 2 so the event below lands on the caller's surrounding span, not on our wrapper. - Look up the currently active span. If the span context is
invalid (no active span, or a
NonRecordingSpanwith an invalid context), return without emitting anything. - Build the attribute map: the three required attributes always, plus any optional attributes whose gates are satisfied.
- Call
Span::addEvent('feature_flag', $attributes).
The reserved $data keys are removed before returning so downstream
hook stages do not observe OpenTelemetry objects in their inputs.
Parameters
- $seriesContext : EvaluationSeriesContext
-
Flag key, context, and method for the evaluation.
- $data : array<string, mixed>
-
Hook state threaded from
beforeEvaluation; may contain the reserved keys self::DATA_KEY_SPAN and self::DATA_KEY_SCOPE whenaddSpansis on. - $detail : EvaluationDetail
-
Evaluation result — drives the optional attributes.
Tags
Return values
array<string, mixed> —The $data array with the reserved keys stripped.
beforeEvaluation()
Experimental. When {@see TracingHookOptions::$addSpans} is enabled, start a wrapper span named `LDClient.<method>` around the upcoming variation call and attach its context so subsequent work is nested beneath it. The wrapper span carries only `feature_flag.key` and `feature_flag.context.id`; all other attributes belong on the `feature_flag` event.
public
beforeEvaluation(EvaluationSeriesContext $seriesContext, array<string, mixed> $data) : array<string, mixed>
The span and the scope used to detach its context are stashed under
self::DATA_KEY_SPAN and self::DATA_KEY_SCOPE in the
returned $data so afterEvaluation can tear them down in the
correct order.
When addSpans is disabled, $data is returned unchanged.
The span name is the raw PHP SDK method string (variation,
variationDetail, migrationVariation), which yields
LDClient.variation and friends. Aligning the method-name casing is
a concern for the core PHP Server-Side SDK and is tracked separately.
Parameters
- $seriesContext : EvaluationSeriesContext
- $data : array<string, mixed>
Return values
array<string, mixed> —getMetadata()
Return the hook's identification metadata.
public
getMetadata() : Metadata
The name is used by the LaunchDarkly SDK when it logs errors raised from this hook so the offending hook can be identified among the (possibly many) registered hooks.
Tags
Return values
Metadata —Metadata whose name is the fixed string
"LaunchDarkly Tracing Hook".