Threadline.Telemetry defines Threadline's emitted event contract and lets
hosts record accurate transaction table counts.
Threadline emits the following :telemetry events. No event carries row
values, actor identifiers, correlation ids, or free-text reasons — with one
narrow exception: [:threadline, :retention, :purge, :exception]'s
reason/stacktrace metadata, forwarded verbatim from a raised exception
for incident diagnosis (see the Telemetry guide's
"Keep row data out of your handlers" section before logging it anywhere
durable). See the guide for an attach_many example per family, a
telemetry_metrics example, handler-safety and cardinality warnings, and a
recipe for observing Threadline's own repo queries through your host's
[:my_app, :repo, :query] event.
| Event | Measurements | Metadata | When emitted |
|---|---|---|---|
[:threadline, :transaction, :committed] | table_count | — | an AuditTransaction is committed |
[:threadline, :action, :recorded] | status | — | Threadline.record_action/2 completes, whether it succeeds or fails |
[:threadline, :health, :checked] | covered, expected_uncovered, uncovered | — | Threadline.Health.trigger_coverage/1 returns |
[:threadline, :health, :checked, :error] | — | exception | a polled coverage check raises |
[:threadline, :health, :findings_checked] | errors, warnings | — | Threadline.Health.trigger_findings/1 returns |
[:threadline, :operator_surface, :authorize] | result | path, scope_keys | an operator-surface mount or request is authorized, denied, or errors |
[:threadline, :operator_surface, :export_authorize] | count, result | — | an export-specific authorization check raises |
[:threadline, :operator_surface, :actor_ref_mismatch] | count | — | the session actor and the scope-derived actor disagree |
[:threadline, :export, :completed] | duration, row_count | format, truncated | an export (eager CSV/JSON, the async orchestrator job, or the chunked operator-surface download) finishes successfully |
[:threadline, :export, :failed] | duration, row_count | format, error_kind, exception | an eager facade filter/option or direct Export option validation raises; or an eager CSV/JSON read, async orchestrator job, or chunked operator-surface download fails |
[:threadline, :retention, :purge, :start] | monotonic_time, system_time | dry_run, telemetry_span_context | after purge/1's input checks pass, when the purge work begins |
[:threadline, :retention, :purge, :stop] | batches_run, deleted_changes, deleted_transactions, duration, monotonic_time | dry_run, telemetry_span_context | when the run or preview returns |
[:threadline, :retention, :purge, :exception] | duration, monotonic_time | dry_run, kind, reason, stacktrace, telemetry_span_context | when the database raises mid-run |
[:threadline, :retention, :batch_purged] | deleted_changes, deleted_transactions, duration | — | after a purge_loop step's change delete_all and full orphan drain both return, once per step including the terminating empty one |
[:threadline, :row_history, :truncated] | limit | schema | Threadline.row_history/3's default 200-row cap dropped older changes |
[:threadline, :transaction, :committed] is automatically emitted (with
table_count: 0) when Threadline.record_action/2 succeeds. For accurate
per-transaction counts, call Threadline.Telemetry.transaction_committed/2
explicitly after a known DB transaction commit.
Every emission in this library goes through a @doc false helper function
in this module; :telemetry.execute/3 and :telemetry.span/3 are called
only here. Every event this module can emit, along with its measurement
and metadata keys, is held in an internal registry exposed through
__events__/0 (@doc false) — not a public events/0 — for use by this
library's own test suite.
Entry points
transaction_committed/2— call after a host database transaction commits when its audited table count is known.emit_action_recorded/1,emit_transaction_committed_proxy/0,emit_health_checked/3,emit_health_checked_error/1,emit_findings_checked/2,emit_operator_surface_authorize/3,emit_export_authorize_error/0,emit_actor_ref_mismatch/0,emit_export_completed/4,emit_export_failed/5,purge_span/2,emit_row_history_truncated/2, andemit_batch_purged/3— internal@doc falsehooks called by Threadline at the matching event sites; host applications should subscribe to the events instead of calling these.__events__/0— the internal registry used by the library's contract tests, not an adopter entry point.
Usage
Attach handlers in your application's start/2 callback:
:telemetry.attach(
"my-app-audit",
[:threadline, :action, :recorded],
&MyApp.Instrumentation.handle_event/4,
nil
)
Summary
Types
An option accepted by transaction_committed/2.
An opaque host transaction result passed to transaction_committed/2.
Functions
Emits [:threadline, :transaction, :committed] with the given table count.
Types
@type transaction_committed_opt() :: {:table_count, integer()}
An option accepted by transaction_committed/2.
@type transaction_value() :: atom() | number() | bitstring() | pid() | port() | reference() | function() | tuple() | maybe_improper_list(transaction_value(), transaction_value()) | %{optional(transaction_value()) => transaction_value()}
An opaque host transaction result passed to transaction_committed/2.
Functions
@spec transaction_committed(transaction_value(), [transaction_committed_opt()]) :: :ok
Emits [:threadline, :transaction, :committed] with the given table count.
Call this after a DB transaction that you know produced AuditTransaction
records, when you need accurate table_count measurements.
Options
:table_count— integer. Defaults to0; reports the number of audited tables in the transaction.
Other option keys are ignored.
Returns
:okafter the telemetry event is emitted.
Example
{:ok, txn} = MyApp.Repo.transaction(fn ->
# ... your writes ...
end)
Threadline.Telemetry.transaction_committed(txn, table_count: 3)