PushX.Telemetry (PushX v0.5.0)

Copy Markdown View Source

Telemetry integration for PushX.

PushX emits the following telemetry events:

Events

[:pushx, :push, :start]

Emitted when a push notification request starts.

Measurements: %{system_time: integer} Metadata:

  • :provider - :apns or :fcm
  • :token - Device token (truncated for privacy)

[:pushx, :push, :stop]

Emitted when a push notification request completes successfully.

Measurements: %{duration: integer} (in native time units) Metadata:

  • :provider - :apns or :fcm
  • :token - Device token (truncated)
  • :status - :sent
  • :id - Provider message ID (if available)

[:pushx, :push, :exception]

Emitted when a push notification request raises an exception.

Measurements: %{duration: integer} Metadata:

  • :provider - :apns or :fcm
  • :token - Device token (truncated)
  • :kind - Exception kind (:error, :exit, :throw)
  • :reason - Exception reason
  • :stacktrace - Exception stacktrace

[:pushx, :push, :error]

Emitted when a push notification request returns an error response.

Measurements: %{duration: integer} Metadata:

  • :provider - :apns or :fcm
  • :token - Device token (truncated)
  • :status - Error status (e.g., :invalid_token, :rate_limited)
  • :reason - Error reason string

[:pushx, :retry, :attempt]

Emitted when a retry attempt is made.

Measurements: %{delay_ms: integer, attempt: integer} Metadata:

  • :provider - :apns or :fcm
  • :status - The error status that triggered the retry

Example Usage

Attach a handler in your application startup:

:telemetry.attach_many(
  "pushx-logger",
  [
    [:pushx, :push, :start],
    [:pushx, :push, :stop],
    [:pushx, :push, :error],
    [:pushx, :push, :exception]
  ],
  &MyApp.PushXTelemetry.handle_event/4,
  nil
)

Example handler:

defmodule MyApp.PushXTelemetry do
  require Logger

  def handle_event([:pushx, :push, :stop], %{duration: duration}, metadata, _config) do
    duration_ms = System.convert_time_unit(duration, :native, :millisecond)
    Logger.info("Push sent to #{metadata.provider} in #{duration_ms}ms")
  end

  def handle_event([:pushx, :push, :error], _measurements, metadata, _config) do
    Logger.warning("Push failed: #{metadata.status} - #{metadata.reason}")
  end

  def handle_event(_event, _measurements, _metadata, _config), do: :ok
end

Metrics with Telemetry.Metrics

defmodule MyApp.Telemetry do
  import Telemetry.Metrics

  def metrics do
    [
      counter("pushx.push.stop.count", tags: [:provider]),
      counter("pushx.push.error.count", tags: [:provider, :status]),
      distribution("pushx.push.stop.duration",
        unit: {:native, :millisecond},
        tags: [:provider]
      )
    ]
  end
end