ExUnitJSON.Trace.Recorder (ex_unit_json v0.6.0)

Copy Markdown View Source

Per-test tracer process: the "flight recorder" half of message tracing.

Created by ExUnitJSON.Trace when a test opts in via @tag trace_messages. The recorder owns an OTP-27 dynamic trace session (:trace.session_create/3) with itself as the tracer, so it survives the test process dying on failure (it is started unlinked). It records :send/:receive events of the traced process tree into a bounded ring buffer, and when the monitored test process exits it freezes the buffer, takes a best-effort mailbox snapshot of still-alive traced processes, and writes the result to ExUnitJSON.Trace.Store.

Bounding is twofold: the ring keeps only the last :cap events, and a hard :budget on total events received stops tracing entirely (setting overflow) so a chatty process tree cannot flood the recorder's own mailbox.

Summary

Types

A recorded send/receive event with a relative microsecond timestamp

Functions

Begins tracing trace_pids and monitors monitor_pid (the test process). Returns once tracing is active, so the caller's subsequent work is captured.

Blocks until the recorder has written its buffer to the store, then stops it.

Returns a specification to start this module under a supervisor.

Starts a recorder (unlinked, so it outlives the test process).

Types

event()

@type event() :: map()

A recorded send/receive event with a relative microsecond timestamp

Functions

attach(recorder, trace_pids, monitor_pid)

@spec attach(pid(), [pid()], pid()) :: :ok

Begins tracing trace_pids and monitors monitor_pid (the test process). Returns once tracing is active, so the caller's subsequent work is captured.

await(recorder)

@spec await(pid()) :: :ok

Blocks until the recorder has written its buffer to the store, then stops it.

Called from an on_exit callback so the store write happens-before the formatter reads it at :test_finished. The monitored process's :DOWN is already enqueued by the time on_exit runs, so it is processed before this call — the snapshot is taken while children are still alive. Tolerates an already-stopped recorder.

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

start(key, opts \\ [])

@spec start(
  term(),
  keyword()
) :: {:ok, pid()}

Starts a recorder (unlinked, so it outlives the test process).

Options: :cap (ring size, default 50), :budget (max events before tracing stops, default 5000).