Tinkex.Telemetry.Reporter (Tinkex v0.3.4)

View Source

Client-side telemetry reporter that batches events and ships them to the Tinker backend via /api/v1/telemetry.

A reporter is scoped to a single Tinker session. It:

  • Emits session start/end events.
  • Accepts generic events and exceptions via log/4, log_exception/3, and log_fatal_exception/3.
  • Optionally listens to :telemetry events and forwards ones that include matching :session_id metadata.
  • Batches up to 100 events per request, flushing periodically and whenever the queue crosses the configured threshold.
  • Retries failed sends with exponential backoff (up to 3 retries).
  • Supports wait-until-drained semantics for graceful shutdown.

Telemetry can be disabled by setting TINKER_TELEMETRY=0|false|no.

Typed Events

The reporter now uses typed structs for all telemetry events. See Tinkex.Types.Telemetry for available types:

Summary

Functions

Returns a specification to start this module under a supervisor.

Traverse the exception cause chain to find a user error.

Flush pending events.

Log a generic telemetry event.

Log an exception (non-fatal) and trigger an async flush.

Log a fatal exception, emit a session end event, and flush synchronously.

Start a reporter for the provided session/config.

Stop the reporter gracefully.

Wait until all queued events have been flushed.

Types

severity()

@type severity() :: :debug | :info | :warning | :error | :critical | String.t()

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

find_user_error_in_chain(exception, visited \\ %{})

@spec find_user_error_in_chain(term(), map()) :: {:ok, term()} | :not_found

Traverse the exception cause chain to find a user error.

Checks exception fields in order: :cause, :reason, :plugstatus (4xx except 408/429), :cause, :_context. Depth-first, first match wins.

flush(pid, opts \\ [])

@spec flush(
  pid() | nil,
  keyword()
) :: :ok | boolean()

Flush pending events.

Options:

  • :sync? - when true, blocks until all batches are sent (default: false)
  • :wait_drained? - when true with sync?, waits until push_counter == flush_counter

log(pid, name, data \\ %{}, severity \\ :info)

@spec log(pid() | nil, String.t(), map(), severity()) :: boolean()

Log a generic telemetry event.

log_exception(pid, exception, severity \\ :error)

@spec log_exception(pid() | nil, Exception.t(), severity()) :: boolean()

Log an exception (non-fatal) and trigger an async flush.

log_fatal_exception(pid, exception, severity \\ :error)

@spec log_fatal_exception(pid() | nil, Exception.t(), severity()) :: boolean()

Log a fatal exception, emit a session end event, and flush synchronously.

Waits until all queued events are flushed (up to flush_timeout_ms) and logs a notification with the session ID for debugging purposes.

start_link(opts)

@spec start_link(keyword()) :: GenServer.on_start() | :ignore

Start a reporter for the provided session/config.

Options:

  • :config (required) - Tinkex.Config.t()
  • :session_id (required) - Tinker session id
  • :handler_id - telemetry handler id (auto-generated)
  • :events - telemetry events to capture (default: HTTP + queue state)
  • :attach_events? - whether to attach telemetry handlers (default: true)
  • :flush_interval_ms - periodic flush interval (default: 10s)
  • :flush_threshold - flush when queue reaches this size (default: 100)
  • :flush_timeout_ms - max wait time for drain operations (default: 30s)
  • :http_timeout_ms - HTTP request timeout (default: 5s)
  • :max_retries - max retries per batch (default: 3)
  • :retry_base_delay_ms - base delay for exponential backoff (default: 1s)
  • :max_queue_size - drop events beyond this size (default: 10_000)
  • :max_batch_size - events per POST (default: 100)
  • :enabled - override env flag; when false returns :ignore

stop(pid, timeout \\ 5000)

@spec stop(pid() | nil, timeout()) :: :ok | boolean()

Stop the reporter gracefully.

Emits a session end event (if not already emitted) and flushes all pending events synchronously before stopping the GenServer.

wait_until_drained(pid, timeout \\ 30000)

@spec wait_until_drained(pid() | nil, timeout()) :: boolean()

Wait until all queued events have been flushed.

Returns true if drained within timeout, false otherwise.