Mob.Event.Trace (mob v0.9.6)

Copy Markdown View Source

Live tracing of Mob events for IEx debugging.

Subscribe a process to receive every event that flows through Mob.Event. Tracing is opt-in and costs one :persistent_term read per dispatch when no tracers are registered.

Usage

# In IEx connected to the running app:
Mob.Event.Trace.subscribe()

# Now every event delivered via Mob.Event.dispatch/4 also lands in your
# mailbox tagged {:mob_trace, addr, event, payload}. Pattern-match it,
# log it, whatever.

flush()  # see what's in the mailbox

# Filter on the way out:
Mob.Event.Trace.subscribe(fn addr -> addr.widget == :list end)

# From a shell on another node, name the pid to deliver to — `:rpc`
# runs the call in a short-lived process that would receive nothing:
:rpc.call(node, Mob.Event.Trace, :subscribe, [self(), nil])

# Stop tracing:
Mob.Event.Trace.unsubscribe()   # this process
Mob.Event.Trace.stop()          # every tracer

Tracers are monitored by Mob.Diag.Subscribers, so one that exits (or whose node disconnects) stops being traced to without an unsubscribe/1.

Performance

When no tracers are registered (the default), Mob.Event.dispatch/4 reads an empty list from :persistent_term and returns. When tracers are registered, each one is sended a copy of the envelope. Tracer filter functions run in the dispatch path, so keep them cheap.

Summary

Functions

Called by Mob.Event.dispatch/4 to deliver to all tracers. Internal API.

Stop tracing: unsubscribe every tracer.

Subscribe the current process to receive trace messages.

Subscribe pid — which may be on another node — with an optional filter. Subscribing a pid again replaces its filter.

Unsubscribe pid (defaults to the current process).

Functions

broadcast(addr, event, payload)

@spec broadcast(Mob.Event.Address.t(), atom(), term()) :: :ok

Called by Mob.Event.dispatch/4 to deliver to all tracers. Internal API.

Never raises: it runs inside the dispatching screen, and a tracer is a debugging aid that must not change what it observes.

stop()

@spec stop() :: :ok

Stop tracing: unsubscribe every tracer.

subscribe(filter \\ nil)

@spec subscribe((Mob.Event.Address.t() -> boolean()) | nil) :: :ok

Subscribe the current process to receive trace messages.

If filter is provided, only events for which filter.(addr) returns truthy are delivered to this subscriber.

Messages arrive shaped {:mob_trace, addr, event, payload}.

subscribe(pid, filter)

@spec subscribe(pid(), (Mob.Event.Address.t() -> boolean()) | nil) :: :ok

Subscribe pid — which may be on another node — with an optional filter. Subscribing a pid again replaces its filter.

unsubscribe(pid \\ self())

@spec unsubscribe(pid()) :: :ok

Unsubscribe pid (defaults to the current process).