PhoenixGenApi.Diagnostics (PhoenixGenApi v2.20.1)

Copy Markdown View Source

Runtime diagnostics, monitoring, and debugging utilities for PhoenixGenApi.

These helpers are intended for sysadmins and developers who need a safe runtime snapshot from IEx, remote shells, or custom admin tooling. They return structured maps rather than printing directly, so callers can expose them in dashboards or logs.

Health checks

PhoenixGenApi.Diagnostics.health_check()
#=> %{status: :ok | :degraded | :error, checks: %{...}}

Statistics

PhoenixGenApi.Diagnostics.statistics()
#=> %{vm: %{...}, phoenix_gen_api: %{...}}

Debug reports

PhoenixGenApi.Diagnostics.debug_report(process_limit: 10)

Call flow inspection

Trace how a request flows from the gateway to target nodes:

PhoenixGenApi.Diagnostics.call_flow("user_service", "get_user")
#=> %{config: %FunConfig{}, local?: true, nodes: [...], steps: [...]}

View the full cluster topology as seen by this node:

PhoenixGenApi.Diagnostics.cluster_view()
#=> %{self: :node@host, connected: [...], registered: [...]}

Inspect a specific request's execution path:

PhoenixGenApi.Diagnostics.inspect_request(%Request{...})

Tracing

Tracing is gated behind admin actions because it can add overhead and expose runtime internals. Configure the actions before using it:

config :phoenix_gen_api, :admin_actions, [
  :enable_tracing,
  :disable_tracing
]

PhoenixGenApi.Diagnostics.trace_processes(:all,
  flags: [:call, :return_to, :procs],
  tracer: self()
)

PhoenixGenApi.Diagnostics.trace_functions({MyApp.Api, :get_user, 1},
  tracer: self()
)

PhoenixGenApi.Diagnostics.stop_trace(:all)

Summary

Functions

Traces the call flow for a given service/request_type from the gateway node to its target node(s).

Returns a cluster topology view from the perspective of this node.

Returns a debug-oriented snapshot for local runtime inspection.

Returns a runtime health report for the VM, Erlang distribution, and PhoenixGenApi processes.

Inspects a %Request{} struct and returns a detailed execution plan showing exactly what will happen when the request is executed.

Returns a summary of all registered call flows across all services.

Returns VM and PhoenixGenApi runtime statistics.

Disables legacy Erlang tracing for processes or ports.

Disables call tracing for specific MFAs.

Enables call tracing for specific MFAs.

Enables legacy Erlang tracing for processes or ports.

Returns a small trace status snapshot.

Types

health_report()

@type health_report() :: %{
  status: health_status(),
  node: node(),
  checked_at_ms: integer(),
  checks: map()
}

health_status()

@type health_status() :: :ok | :degraded | :error

Functions

call_flow(service, request_type, version \\ nil)

@spec call_flow(String.t() | atom(), String.t(), String.t() | nil) :: map()

Traces the call flow for a given service/request_type from the gateway node to its target node(s).

Returns a map describing every step a request goes through:

  • :config — the resolved %FunConfig{} (or nil if not found)
  • :local? — whether execution is local (:local) or remote
  • :nodes — the list of target nodes after node selection
  • :steps — an ordered list of execution phases with descriptions
  • :rate_limit — which rate limiter scopes apply
  • :permission — the permission check strategy
  • :hooks — before/after hook configurations
  • :retry — retry configuration (if any)
  • :cluster — which of the target nodes are currently reachable

Examples

iex> PhoenixGenApi.Diagnostics.call_flow("user_service", "get_user")
%{
  config: %FunConfig{request_type: "get_user", ...},
  local?: false,
  nodes: [:"service@host"],
  steps: [
    %{phase: :channel, desc: "WebSocket handle_in receives payload"},
    %{phase: :decode, desc: "Payload decoded into %Request{}"},
    %{phase: :config_lookup, desc: "ConfigDb.get(service, type, version)"},
    %{phase: :hooks_before, desc: "before_execute hooks (none configured)"},
    %{phase: :permission, desc: "Permission.check_permission!/2"},
    %{phase: :rate_limit, desc: "RateLimiter.check_rate_limit/1"},
    %{phase: :argument_validation, desc: "ArgumentHandler.convert_args!/2"},
    %{phase: :node_selection, desc: "NodeSelector picks :random from [node@host]"},
    %{phase: :execution, desc: "RPC to service@host"},
    %{phase: :hooks_after, desc: "after_execute hooks (none configured)"},
    %{phase: :response, desc: "Result pushed back to client via WebSocket"}
  ],
  ...
}

cluster_view()

@spec cluster_view() :: map()

Returns a cluster topology view from the perspective of this node.

Shows connected nodes, registered processes, and which PhoenixGenApi services are reachable.

debug_report(opts \\ [])

@spec debug_report(keyword()) :: map()

Returns a debug-oriented snapshot for local runtime inspection.

Options:

  • :process_limit — Maximum number of processes to include, sorted by memory usage. Defaults to 20.
  • :include_current_stacktrace — Includes each process stacktrace when true. Defaults to false.

The returned process summaries intentionally avoid full message queues and dictionaries by default.

health_check(opts \\ [])

@spec health_check(keyword()) :: health_report()

Returns a runtime health report for the VM, Erlang distribution, and PhoenixGenApi processes.

Options:

  • :max_memory_bytes — if set and total memory exceeds it, the vm check is marked :degraded.

The report is structured and non-destructive. It does not mutate the system.

inspect_request(request)

@spec inspect_request(map() | PhoenixGenApi.Structs.Request.t()) :: map()

Inspects a %Request{} struct and returns a detailed execution plan showing exactly what will happen when the request is executed.

This is useful for debugging why a request succeeds, fails, or routes to a particular node.

list_call_flows(opts \\ [])

@spec list_call_flows(keyword()) :: [map()]

Returns a summary of all registered call flows across all services.

Each entry shows the service, request_type, version, target nodes, and execution mode (local vs remote).

statistics(opts \\ [])

@spec statistics(keyword()) :: map()

Returns VM and PhoenixGenApi runtime statistics.

The VM section contains process, memory, scheduler, reductions, runtime, and garbage collection counters. The PhoenixGenApi section contains status for the config cache, puller, receiver, rate limiter, worker pools, relay server, and telemetry event coverage.

stop_trace(targets \\ :all, opts \\ [])

@spec stop_trace(
  term(),
  keyword()
) :: {:ok, map()} | {:error, term()}

Disables legacy Erlang tracing for processes or ports.

This operation requires the :disable_tracing admin action.

stop_trace_functions(mfas \\ :all)

@spec stop_trace_functions(term()) :: {:ok, map()} | {:error, term()}

Disables call tracing for specific MFAs.

Passing :all disables all call trace patterns.

trace_functions(mfas, opts \\ [])

@spec trace_functions(
  term(),
  keyword()
) :: {:ok, map()} | {:error, term()}

Enables call tracing for specific MFAs.

This operation requires the :enable_tracing admin action.

MFAs can be {Module, Function}, {Module, Function, Arity}, or :all. Arity may be a non-negative integer or :_ for all arities.

Options:

  • :flags — Process trace flags. Defaults to [:call, :return_to, :procs].
  • :match_spec — Match specification passed to :erlang.trace_pattern/3. Defaults to true.
  • :tracer — PID that receives trace messages. Defaults to self().

trace_processes(targets, opts \\ [])

@spec trace_processes(
  term(),
  keyword()
) :: {:ok, map()} | {:error, term()}

Enables legacy Erlang tracing for processes or ports.

This operation requires the :enable_tracing admin action.

Supported targets:

  • :all
  • :processes
  • :ports
  • :existing
  • :existing_processes
  • :existing_ports
  • :new
  • :new_processes
  • :new_ports
  • a PID or port
  • a list of the above

Options:

  • :flags — Trace flags. Defaults to [:call, :return_to, :procs].
  • :tracer — PID that receives trace messages. Defaults to self().

trace_status()

@spec trace_status() :: map()

Returns a small trace status snapshot.