ObserverWeb.SystemInfo (Observer Web v0.2.8)

View Source

Read-only system snapshot of a node: runtime information, resource counts against their VM limits, and per-allocator carrier utilization (the observer GUI's System/Memory Allocators tabs, observer_cli's Home/System panes).

Everything is fetched through stdlib-only RPCs (:erlang.system_info/1 and friends), so it works against any node in the cluster regardless of the observer_web version running there.

Summary

Functions

Reduces one allocator's :erlang.system_info({:allocator_sizes, alloc}) instance list into total block/carrier sizes and a utilization percentage.

Carrier utilization per alloc_util allocator: how much of the memory reserved in carriers is actually occupied by blocks. Low utilization on a busy allocator points at fragmentation - the same signal recon_alloc and the observer GUI's Memory Allocators tab expose.

Resource counts against their configured VM limits.

General runtime information for the node.

Operating system level data - load averages, per-CPU utilization, OS memory and disk usage - collected through the os_mon probes (:cpu_sup, :memsup, :disksup), the same source the observer GUI's load charts and LiveDashboard's OS Data page read from.

Types

allocator()

@type allocator() :: %{
  name: atom(),
  blocks_size: non_neg_integer(),
  carriers_size: non_neg_integer(),
  utilization_percent: float() | nil
}

limit()

@type limit() :: %{
  name: String.t(),
  count: non_neg_integer(),
  limit: pos_integer(),
  percent: float()
}

os_data()

@type os_data() :: %{
  os: String.t() | nil,
  load: %{avg1: float(), avg5: float(), avg15: float()} | nil,
  cpus: [%{id: non_neg_integer(), busy_percent: float()}],
  memory:
    %{
      total_bytes: non_neg_integer(),
      available_bytes: non_neg_integer(),
      used_percent: float()
    }
    | nil,
  disks: [
    %{
      mount: String.t(),
      total_kbytes: non_neg_integer(),
      capacity_percent: integer()
    }
  ]
}

Functions

allocator_utilization(alloc, instances)

@spec allocator_utilization(atom(), list()) :: allocator()

Reduces one allocator's :erlang.system_info({:allocator_sizes, alloc}) instance list into total block/carrier sizes and a utilization percentage.

Sizes are reported as {:size, current, last_max, max} (or {:size, current} on some emulator types), under mbcs/sbcs (multi/single-block carriers) per scheduler instance - anything with an unexpected shape is skipped rather than crashing the caller.

allocators(node)

@spec allocators(node()) :: [allocator()]

Carrier utilization per alloc_util allocator: how much of the memory reserved in carriers is actually occupied by blocks. Low utilization on a busy allocator points at fragmentation - the same signal recon_alloc and the observer GUI's Memory Allocators tab expose.

limits(node)

@spec limits(node()) :: [limit()]

Resource counts against their configured VM limits.

node_info(node)

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

General runtime information for the node.

os_data(node)

@spec os_data(node()) :: {:ok, os_data()} | {:error, :os_mon_not_started | term()}

Operating system level data - load averages, per-CPU utilization, OS memory and disk usage - collected through the os_mon probes (:cpu_sup, :memsup, :disksup), the same source the observer GUI's load charts and LiveDashboard's OS Data page read from.

Requires the :os_mon application to be running on the target node; returns {:error, :os_mon_not_started} otherwise so callers can hint at adding it to extra_applications. Individual probes vary per platform, so each section degrades to nil (or an empty list) instead of failing the whole snapshot.