Telemetry Configuration & Gating
One hierarchical static-readonly bool surface that gates both tracing and the typed-event profiler at zero cost when off.
Status: โ Implemented ยท Visibility: Public ยท Level: ๐ข Start Here ยท Category: Observability
๐ฏ What it solves
Typhon instruments roughly 200 call-site families across concurrency, storage, indexing, query, ECS, and durability.
Application developers need to turn this on selectively for diagnosis โ a single subsystem, a single sub-operation โ
without shipping a different binary, without a config system per instrumentation track, and without paying for the
"is anyone watching" check when nothing is. TelemetryConfig is the one place that answers "is X being observed
right now" for both distributed tracing spans and the typed-event Profiler.
โ๏ธ How it works (in brief)
TelemetryConfig is resolved once, at static-class load, from typhon.telemetry.json plus environment variables,
into ~200 static readonly bool *Active fields. Flags are organized as a tree (e.g. Concurrency โ AccessControl
โ Contention) with parent-implies-children semantics: a disabled parent silences every descendant regardless of
its own setting, and a leaf with no explicit key inherits its parent's effective state. Because each field is
static readonly, the JIT can prove it never changes after class init and deletes a disabled if (TelemetryConfig.XxxActive)
block entirely at Tier 1 โ the same gate is read by both Activity-based span producers and the typed-event Profiler's
emit calls, so there is one on/off surface for both tracks, not two.
๐ป Usage
// Hot-path producer code โ the gate is the only cost when the flag is off.
if (TelemetryConfig.DataMvccChainWalkActive)
{
RecordChainWalkDepth(depth);
}
// Optional host startup โ Typhon.Engine self-initializes via a module initializer,
// but a DI host can force resolution explicitly before building the service provider.
services.AddTyphonProfiler();
// Log what was actually resolved at startup.
_logger.LogInformation(TelemetryConfig.GetConfigurationSummary());
typhon.telemetry.json (working directory, or next to the assembly):
{
"Typhon": {
"Profiler": {
"Enabled": true,
"Concurrency": {
"Enabled": true,
"AccessControl": { "Contention": { "Enabled": true } }
}
}
}
}
| Source | Precedence | Example |
|---|---|---|
Environment variable (__ hierarchy separator) |
Highest | TYPHON__PROFILER__CONCURRENCY__ENABLED=true |
typhon.telemetry.json in the working directory |
2nd | shape above |
typhon.telemetry.json next to the assembly |
3rd | shape above |
| Built-in defaults | Lowest | every flag false |
โ ๏ธ Guarantees & limits
- Resolved once per process (static constructor, forced early by a module initializer) and immutable thereafter โ no runtime toggle; changing a flag means editing config/environment and restarting.
- Every flag defaults to
falseโ a fresh deployment instruments nothing until explicitly opted in. - Parent-implies-children: disabling a subtree's root disables every descendant even if individually set
true. - Benchmark-verified zero overhead: a
static readonly falseguard measures identical to no guard at all (~0.22 ns);truecosts ~0.22 ns more; a mutablestaticfield or interface dispatch costs 200โ500%+ more for the equivalent check. - One resolved value gates two independent consumers โ distributed tracing spans and the typed-event Profiler โ so enabling/disabling a subsystem affects both uniformly.
๐งช Tests
- TelemetryConfigResolverTests โ parent-implies-children resolution: parent-off cascades to children despite explicit
true, explicit leaf override wins, implicit leaf inherits parent - TelemetryConfigGateShapeTests โ enforces every
*Activefield ispublic static readonly bool(the structural invariant the JIT dead-code-elimination guarantee depends on) - TelemetryConfigCpuSamplingTests โ end-to-end resolution of a real flag from
typhon.telemetry.json, composedXxxActivederivation, andGetConfigurationSummary()diagnostics
๐ Related
- Sibling: Distributed Tracing (Activity API) โ one of the two consumers this gating surface controls
- Sibling: Profiler โ the typed-event pipeline that is this gating surface's other consumer
- Source:
src/Typhon.Engine/Observability/public/TelemetryConfig.cs,TelemetryConfigResolver.cs,TelemetryServiceExtensions.cs