Roux.Telemetry (roux v0.2.2)

Copy Markdown View Source

Structured event definitions for observability and debugging.

Emits :telemetry events for all significant framework operations. Essential for answering "why did this query re-execute?" and "why didn't this query re-execute?"

All events are prefixed with [:roux, ...]. Helper functions enforce consistent metadata shapes for each event type.

The database

Every event about a database's queries, inputs or sweeps carries the database it happened in as database: metadata (Roux.Database.id/1), so a handler can tell apart events of databases running side by side in one VM — concurrent tests, or a compiler and an LSP session. Roux.QueryLog filters on it. [:roux, :intern, :new] carries none: an intern table belongs to no one database.

Event reference

Query lifecycle

  • [:roux, :query, :start] — query execution begins
  • [:roux, :query, :stop] — query execution completes
  • [:roux, :query, :exception] — query execution raised

Cache operations

  • [:roux, :cache, :hit] — memo entry is valid, no re-execution needed
  • [:roux, :cache, :miss] — no memo entry, must execute
  • [:roux, :cache, :early_cutoff] — value unchanged after re-execution

Validation

  • [:roux, :validation, :start] — validation begins
  • [:roux, :validation, :stop] — validation completes
  • [:roux, :validation, :durability_skip] — validation skipped via durability

Other operations

  • [:roux, :input, :set] — input value set or modified
  • [:roux, :input, :delete] — input value removed
  • [:roux, :cycle, :detected] — dependency cycle detected
  • [:roux, :cancel, :task] — query task cancelled
  • [:roux, :gc, :sweep] — garbage collection sweep completed
  • [:roux, :intern, :new] — new value interned
  • [:roux, :blob, :missing] — a value held by digest was gone, and is recomputed

Summary

Types

The database an event happened in: its Roux.Database.id/1.

Functions

Emits [:roux, :blob, :missing].

Emits [:roux, :cache, :miss].

Emits [:roux, :cancel, :task].

Emits [:roux, :cycle, :detected].

Emits [:roux, :validation, :durability_skip].

Emits a single :telemetry event with the [:roux | event_name] prefix.

Emits [:roux, :intern, :new].

Emits [:roux, :query, :start].

Wraps :telemetry.span/3 with the [:roux | event_prefix] prefix.

Emits [:roux, :validation, :start].

Types

database()

@type database() :: term()

The database an event happened in: its Roux.Database.id/1.

Functions

blob_missing(database, query_name, key, revision)

@spec blob_missing(database(), atom(), term(), non_neg_integer()) :: :ok

Emits [:roux, :blob, :missing].

cache_hit(database, query_name, key, revision, changed_at, verified_at)

@spec cache_hit(
  database(),
  atom(),
  term(),
  non_neg_integer(),
  non_neg_integer(),
  non_neg_integer()
) :: :ok

Emits [:roux, :cache, :hit].

cache_miss(database, query_name, key, revision)

@spec cache_miss(database(), atom(), term(), non_neg_integer()) :: :ok

Emits [:roux, :cache, :miss].

cancel_task(database, query_name, key, reason)

@spec cancel_task(database(), atom(), term(), term()) :: :ok

Emits [:roux, :cancel, :task].

cycle_detected(database, query_name, key, stack)

@spec cycle_detected(database(), atom(), term(), [term()]) :: :ok

Emits [:roux, :cycle, :detected].

durability_skip(database, query_name, key, durability, revision)

@spec durability_skip(database(), atom(), term(), atom(), non_neg_integer()) :: :ok

Emits [:roux, :validation, :durability_skip].

early_cutoff(database, query_name, key, revision, changed_at)

@spec early_cutoff(database(), atom(), term(), non_neg_integer(), non_neg_integer()) ::
  :ok

Emits [:roux, :cache, :early_cutoff].

event(event_name, measurements \\ %{}, metadata)

@spec event([atom()], map(), map()) :: :ok

Emits a single :telemetry event with the [:roux | event_name] prefix.

gc_sweep(database, duration, memo_entries_removed, entities_removed, revision)

Emits [:roux, :gc, :sweep].

input_delete(database, input_name, key, revision, durability)

@spec input_delete(database(), atom(), term(), non_neg_integer(), atom()) :: :ok

Emits [:roux, :input, :delete].

input_set(database, input_name, key, revision, durability)

@spec input_set(database(), atom(), term(), non_neg_integer(), atom()) :: :ok

Emits [:roux, :input, :set].

intern_new(table_name, id, value_size)

@spec intern_new(atom(), pos_integer(), non_neg_integer()) :: :ok

Emits [:roux, :intern, :new].

query_exception(database, query_name, key, revision, duration, kind, reason)

@spec query_exception(
  database(),
  atom(),
  term(),
  non_neg_integer(),
  non_neg_integer(),
  atom(),
  term()
) :: :ok

Emits [:roux, :query, :exception].

query_start(database, query_name, key, revision)

@spec query_start(database(), atom(), term(), non_neg_integer()) :: :ok

Emits [:roux, :query, :start].

query_stop(database, query_name, key, revision, duration, result_hash)

@spec query_stop(
  database(),
  atom(),
  term(),
  non_neg_integer(),
  non_neg_integer(),
  term()
) :: :ok

Emits [:roux, :query, :stop].

span(event_prefix, metadata, fun)

@spec span([atom()], map(), (-> {term(), map()})) :: term()

Wraps :telemetry.span/3 with the [:roux | event_prefix] prefix.

Executes fun, emitting start and stop (or exception) events automatically.

validation_start(database, query_name, key, revision)

@spec validation_start(database(), atom(), term(), non_neg_integer()) :: :ok

Emits [:roux, :validation, :start].

validation_stop(database, query_name, key, revision, duration, result)

@spec validation_stop(
  database(),
  atom(),
  term(),
  non_neg_integer(),
  non_neg_integer(),
  :valid | :stale
) :: :ok

Emits [:roux, :validation, :stop].