Skip to content
Document DB v8.0 Interceptors, Temporal Support, Telemetry Collection, All Calculations, String Based APIs, & Orleans Storage Providers! Feed The Machine Here

Metrics

Push delivery telemetry is emitted via System.Diagnostics.Metrics, so it plugs straight into OpenTelemetry. Metrics are wired up automatically by AddPushNotifications (it registers IMeterFactory).

All published under the meter Shiny.Extensions.Push (PushMetrics.MeterName):

InstrumentKindDescription
push.notifications.sentCounterNotifications accepted by a provider
push.notifications.failedCounterNotifications that failed to send
push.notifications.skippedCounterDevices skipped by an interceptor
push.tokens.prunedCounterDevice tokens removed after being reported dead
push.send.durationHistogram (ms)Per-device provider send latency

Every measurement is tagged with platform, provider, and status — deliberately low-cardinality. The per-send BatchId is not a tag (it’s unbounded and would explode a metrics backend); it lives on PushSendResult and in logs for correlation instead.

builder.Services
.AddOpenTelemetry()
.WithMetrics(m => m
.AddMeter(PushMetrics.MeterName)
.AddOtlpExporter()); // or your exporter of choice

The instruments are zero-cost when nothing is listening.

The manager also logs each batch (start + completion with sent/failed/pruned/skipped counts) using the batch’s BatchId as the correlation id. Device tokens are masked in logs.