Heavy OpenTelemetry exporters and always-on instrumentation can consume measurable CPU alongside request handling — especially noticeable on asymmetric CPU layouts (e.g. NVIDIA Jetson Denver + A57).
We should add explicit, configurable sampling for traces (and optionally adjust metric export intervals) so production observability stays useful without dominating the hottest cores.
Goals
Tracing: Use a configurable ratio sampler (e.g. TraceIdRatioBasedSampler) with a sane default under load; allow 100% in dev/Diagnostics scenarios.
Configuration: Wire via existing config patterns (appsettings.json / env), e.g. OpenTelemetry:Tracing:SampleRatio or similar — document defaults.
Optional: Separate sampling knobs for ASP.NET incoming vs outbound HttpClient if we need finer control later.
Metrics: Consider longer export intervals or reduced metric cardinality in constrained profiles (secondary; traces are usually the hotspot).
Proposed backend touchpoints
SpikerSoft.Api/Extensions/ServiceCollectionExtensions.cs → AddTelemetryConfiguration (where tracing + exporters are wired today).
Mirror the same pattern in worker Program.cs stacks that register OTel if we want uniform behavior cluster-wide.
Acceptance criteria
Sampling is off-by-default-transparent or has a conservative production default documented in appsettings commentary.
Operators can tune ratio without rebuilding (env / configuration).
Document how to correlate when sampling is < 100% (e.g. rely on logs + trace context propagation from sampled roots).
Smoke test: API starts with sampling 0, 1, and 0.1 without exceptions.
Labels
enhancement · backend · telemetry
## Summary
Heavy OpenTelemetry exporters and always-on instrumentation can consume measurable CPU alongside request handling — especially noticeable on asymmetric CPU layouts (e.g. NVIDIA Jetson Denver + A57).
We should add **explicit, configurable sampling** for traces (and optionally adjust metric export intervals) so production observability stays useful without dominating the hottest cores.
## Goals
- **Tracing:** Use a configurable ratio sampler (e.g. `TraceIdRatioBasedSampler`) with a sane default under load; allow `100%` in dev/Diagnostics scenarios.
- **Configuration:** Wire via existing config patterns (`appsettings.json` / env), e.g. `OpenTelemetry:Tracing:SampleRatio` or similar — document defaults.
- **Optional:** Separate sampling knobs for ASP.NET incoming vs outbound `HttpClient` if we need finer control later.
- **Metrics:** Consider longer export intervals or reduced metric cardinality in constrained profiles (secondary; traces are usually the hotspot).
## Proposed backend touchpoints
- `SpikerSoft.Api/Extensions/ServiceCollectionExtensions.cs` → `AddTelemetryConfiguration` (where tracing + exporters are wired today).
- Mirror the same pattern in worker `Program.cs` stacks that register OTel if we want uniform behavior cluster-wide.
## Acceptance criteria
1. Sampling is **off-by-default-transparent** or has a conservative production default documented in appsettings commentary.
2. Operators can tune ratio without rebuilding (env / configuration).
3. Document how to correlate when sampling is `< 100%` (e.g. rely on logs + trace context propagation from sampled roots).
4. Smoke test: API starts with sampling `0`, `1`, and `0.1` without exceptions.
## Labels
`enhancement` · `backend` · `telemetry`
AddEventHandlerTelemetry follows the identical pattern: reads ratio → clamps → ParentBasedSampler.
All 19 workers that call EventHandlerHostBuilder.WithTelemetry() automatically inherit this behavior.
3. Configuration — appsettings.json (API + all workers)
Added OpenTelemetry.Tracing.SampleRatio key with default 1.0 (transparent / no change in behavior).
Operators can override via env var: OpenTelemetry__Tracing__SampleRatio=0.1
4. Unit Tests — SpikerSoft.Tests.Unit/Telemetry/TelemetrySamplingTests.cs
14 new tests covering:
Valid ratios (0.0, 0.1, 0.5, 1.0) don't throw.
Missing config defaults to 1.0.
Out-of-range values (−1, 2, 100) are clamped without exceptions.
Ratio 0.0 marks traces as not sampled (IsAllDataRequested = false).
Ratio 1.0 records all traces (IsAllDataRequested = true).
ParentBasedSampler honors a sampled parent even when root ratio is 0.0.
Config value round-trips correctly.
All 14 tests pass ✅
Correlation at < 100% Sampling
Because ParentBasedSampler wraps the ratio sampler, any child span whose parent was sampled will also be sampled. This means distributed traces that start as sampled will be complete end-to-end. Un-sampled roots still propagate W3C traceparent headers, so downstream services can correlate via logs + trace context even when the trace itself is not exported.
Acceptance Criteria
Sampling is transparent by default (1.0 = sample everything, same as before).
Operators can tune ratio without rebuilding (env / appsettings).
Correlation preserved via ParentBasedSampler + W3C context propagation.
Smoke: API & workers start with 0, 1, and 0.1 without exceptions (covered by unit tests).
## Implementation Summary
Configurable OpenTelemetry trace sampling has been implemented across the API and all 19 event handler workers.
### Changes
**1. API — `SpikerSoft.Api/Extensions/ServiceCollectionExtensions.cs`**
- `AddTelemetryConfiguration` now reads `OpenTelemetry:Tracing:SampleRatio` from config (default `1.0`).
- Value is clamped to `[0.0, 1.0]` for safety.
- A `ParentBasedSampler(new TraceIdRatioBasedSampler(ratio))` is wired into the `TracerProviderBuilder`. This ensures:
- Root traces are sampled at the configured ratio.
- Child spans inherit the sampling decision from their parent, preserving full distributed-trace correlation.
**2. Workers — `SpikerSoft.EventHandlers.Infrastructure/Extensions/ServiceCollectionExtensions.cs`**
- `AddEventHandlerTelemetry` follows the identical pattern: reads ratio → clamps → `ParentBasedSampler`.
- All 19 workers that call `EventHandlerHostBuilder.WithTelemetry()` automatically inherit this behavior.
**3. Configuration — `appsettings.json` (API + all workers)**
- Added `OpenTelemetry.Tracing.SampleRatio` key with default `1.0` (transparent / no change in behavior).
- Operators can override via env var: `OpenTelemetry__Tracing__SampleRatio=0.1`
**4. Unit Tests — `SpikerSoft.Tests.Unit/Telemetry/TelemetrySamplingTests.cs`**
- 14 new tests covering:
- Valid ratios (0.0, 0.1, 0.5, 1.0) don't throw.
- Missing config defaults to 1.0.
- Out-of-range values (−1, 2, 100) are clamped without exceptions.
- Ratio 0.0 marks traces as not sampled (`IsAllDataRequested = false`).
- Ratio 1.0 records all traces (`IsAllDataRequested = true`).
- `ParentBasedSampler` honors a sampled parent even when root ratio is 0.0.
- Config value round-trips correctly.
All 14 tests pass ✅
### Correlation at < 100% Sampling
Because `ParentBasedSampler` wraps the ratio sampler, any child span whose parent was sampled will also be sampled. This means distributed traces that start as sampled will be complete end-to-end. Un-sampled roots still propagate W3C `traceparent` headers, so downstream services can correlate via logs + trace context even when the trace itself is not exported.
### Acceptance Criteria
- [x] Sampling is transparent by default (`1.0` = sample everything, same as before).
- [x] Operators can tune ratio without rebuilding (env / appsettings).
- [x] Correlation preserved via `ParentBasedSampler` + W3C context propagation.
- [x] Smoke: API & workers start with `0`, `1`, and `0.1` without exceptions (covered by unit tests).
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Heavy OpenTelemetry exporters and always-on instrumentation can consume measurable CPU alongside request handling — especially noticeable on asymmetric CPU layouts (e.g. NVIDIA Jetson Denver + A57).
We should add explicit, configurable sampling for traces (and optionally adjust metric export intervals) so production observability stays useful without dominating the hottest cores.
Goals
TraceIdRatioBasedSampler) with a sane default under load; allow100%in dev/Diagnostics scenarios.appsettings.json/ env), e.g.OpenTelemetry:Tracing:SampleRatioor similar — document defaults.HttpClientif we need finer control later.Proposed backend touchpoints
SpikerSoft.Api/Extensions/ServiceCollectionExtensions.cs→AddTelemetryConfiguration(where tracing + exporters are wired today).Program.csstacks that register OTel if we want uniform behavior cluster-wide.Acceptance criteria
< 100%(e.g. rely on logs + trace context propagation from sampled roots).0,1, and0.1without exceptions.Labels
enhancement·backend·telemetryImplementation Summary
Configurable OpenTelemetry trace sampling has been implemented across the API and all 19 event handler workers.
Changes
1. API —
SpikerSoft.Api/Extensions/ServiceCollectionExtensions.csAddTelemetryConfigurationnow readsOpenTelemetry:Tracing:SampleRatiofrom config (default1.0).[0.0, 1.0]for safety.ParentBasedSampler(new TraceIdRatioBasedSampler(ratio))is wired into theTracerProviderBuilder. This ensures:2. Workers —
SpikerSoft.EventHandlers.Infrastructure/Extensions/ServiceCollectionExtensions.csAddEventHandlerTelemetryfollows the identical pattern: reads ratio → clamps →ParentBasedSampler.EventHandlerHostBuilder.WithTelemetry()automatically inherit this behavior.3. Configuration —
appsettings.json(API + all workers)OpenTelemetry.Tracing.SampleRatiokey with default1.0(transparent / no change in behavior).OpenTelemetry__Tracing__SampleRatio=0.14. Unit Tests —
SpikerSoft.Tests.Unit/Telemetry/TelemetrySamplingTests.csIsAllDataRequested = false).IsAllDataRequested = true).ParentBasedSamplerhonors a sampled parent even when root ratio is 0.0.All 14 tests pass ✅
Correlation at < 100% Sampling
Because
ParentBasedSamplerwraps the ratio sampler, any child span whose parent was sampled will also be sampled. This means distributed traces that start as sampled will be complete end-to-end. Un-sampled roots still propagate W3Ctraceparentheaders, so downstream services can correlate via logs + trace context even when the trace itself is not exported.Acceptance Criteria
1.0= sample everything, same as before).ParentBasedSampler+ W3C context propagation.0,1, and0.1without exceptions (covered by unit tests).