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).
Instruments
Section titled “Instruments”All published under the meter Shiny.Extensions.Push (PushMetrics.MeterName):
| Instrument | Kind | Description |
|---|---|---|
push.notifications.sent | Counter | Notifications accepted by a provider |
push.notifications.failed | Counter | Notifications that failed to send |
push.notifications.skipped | Counter | Devices skipped by an interceptor |
push.tokens.pruned | Counter | Device tokens removed after being reported dead |
push.send.duration | Histogram (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.
OpenTelemetry
Section titled “OpenTelemetry”builder.Services .AddOpenTelemetry() .WithMetrics(m => m .AddMeter(PushMetrics.MeterName) .AddOtlpExporter()); // or your exporter of choiceThe instruments are zero-cost when nothing is listening.
Logging
Section titled “Logging”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.