Rindle is a media processing library. When you attach the Rindle integration, Parapet translates all seven Rindle async lifecycle events into three async metric families you can observe in Prometheus and track via pre-built SLO slices.
Prerequisites
rindleinstalled in your host app (optional dep — if it is absent, Rindle never emits the telemetry events the adapter listens for, so the attached handlers stay dormant and harmless; Parapet does not probe for therindlelibrary itself)- Parapet installed and configured (
mix parapet.install)
What it unlocks
Rindle media-processing events become Parapet async metrics across three event families:
parapet_async_stage— fromstarted,processed,failed, anddiscardedevents; tagged bypipeline_stage,outcome,retry_state,fault_planeparapet_async_backlog— frombacklogevents; tagged byoutcome,delay_bucket,fault_planeparapet_async_callback— fromcallback_delayedandreconciliation_delayedevents; tagged bypipeline_stage,outcome,delay_bucket,fault_plane
All events carry integration: :rindle, provider, and queue tags. Optional refs included when present: job_id, webhook_id.
The Parapet.SLO.RindleAsync provider uses these metrics for five slices: rindle_terminal_success, rindle_queue_freshness, rindle_callback_freshness, rindle_long_running_stage, and rindle_funnel_regression. Register it with:
config :parapet, providers: [Parapet.SLO.RindleAsync]Then run mix parapet.gen.prometheus to generate the alerting rules. See Parapet SLO Reference for the full slice catalog.
Activation
Add the adapter when you start your supervision tree, typically in application.ex:
Parapet.attach(adapters: [:rindle])This attaches handlers for all seven Rindle events (handler id parapet-rindle-async):
[:rindle, :media, :started], [:rindle, :media, :processed], [:rindle, :media, :failed],
[:rindle, :media, :discarded], [:rindle, :media, :backlog],
[:rindle, :media, :callback_delayed], and [:rindle, :media, :reconciliation_delayed].
Config keys
The Rindle integration has no Parapet-level config keys. It reads standard Rindle telemetry events and re-emits them as Parapet async events without additional configuration.
Troubleshooting
Telemetry handler raises a conflict error on startup
A second call to Parapet.attach(adapters: [:rindle]) raises a telemetry conflict because the handler name parapet-rindle-async is already registered. Attach each adapter exactly once at application startup.
The pipeline_stage tag shows unexpected values
Parapet normalizes pipeline_stage from string to atom at event time: strings are lowercased, trimmed, and non-alphanumeric characters are replaced with underscores before String.to_atom/1 is called. If your Rindle metadata passes stage as a string like "Media Processing", Parapet normalizes it to :media_processing. If you need a specific atom key in SLO slices, ensure Rindle metadata passes stage as the expected atom directly, or align your slice filter to the normalized form.
The retry_state tag shows :first_attempt when a retry is expected
Parapet infers retry_state from the attempt or attempt_number integer keys in Rindle metadata when no explicit retry_state key is present. If the metadata does not include either key, or the value is 1 (first attempt), Parapet sets retry_state: :first_attempt. For events at attempt > 1, the tag becomes :retrying. If your Rindle metadata uses a different key for the attempt counter, Parapet will not pick it up automatically — set retry_state explicitly in your Rindle job metadata to guarantee the correct label.