ObserverWeb.Crashdump (Observer Web v0.2.6)

View Source

Browses erl_crash.dump files in the web dashboard - the web equivalent of OTP's crashdump_viewer GUI, reusing its battle-tested parser (:crashdump_viewer, part of the :observer application) instead of reimplementing the dump format.

Requirements

Parsing needs OTP's :crashdump_viewer (part of the :observer application, which ships with OTP but is commonly excluded from releases). No GUI/wx is ever started; only the parsing gen_server is used. When :observer isn't in the release, the page explains what to add.

Ingesting a dump

Two ways:

  • Upload an erl_crash.dump straight from the browser (e.g. one pulled off a crashed Nerves device) - it's parsed on the dashboard node and the temporary copy is discarded.

  • Browse dumps already present on the dashboard host, from directories the host explicitly allowlists (never a free path):

    config :observer_web, crashdump_dirs: ["/var/log/my_app/crashdumps"]

Security

Crash dumps contain everything the VM held at crash time: process states, message queues, application data. Directory browsing is limited to the allowlisted directories, uploads are size-capped, and dumps are parsed on the dashboard node only - never fetched from remote nodes.

Summary

Functions

Whether the :crashdump_viewer parser is available on this node.

General information about the loaded dump.

Lists the crash dump files found in the configured :crashdump_dirs (newest first). Returns {:error, :not_configured} when no directory is configured - the feature's off state.

Starts loading a dump. Progress and completion are broadcast on the "crashdump" PubSub topic as {:crashdump_progress, percent | {:error, reason} | :done} - subscribe via subscribe/0. Only paths returned by list_dumps/0 are accepted.

Loads a dump from an uploaded file's already-consumed temporary path. Unlike load/1 this skips the directory allowlist: the path isn't user-supplied text but a temp file LiveView produced from a size-capped upload (see Observer.Web.Crashdump.Page).

Full details of one process in the loaded dump, by its pid string (e.g. "<0.42.0>"), including the stack dump and message queue as expandable strings.

The loaded dump's process summaries (pid, name, state, current function, message queue length, reductions, memory) - the integer fields are sortable.

The server's current state: :idle, {:loading, path, percent} or {:loaded, path}.

Subscribes the caller to load progress broadcasts.

Functions

available?()

@spec available?() :: boolean()

Whether the :crashdump_viewer parser is available on this node.

general_info()

@spec general_info() :: {:ok, map()} | {:error, :no_dump_loaded}

General information about the loaded dump.

list_dumps()

@spec list_dumps() :: {:ok, [map()]} | {:error, :not_configured}

Lists the crash dump files found in the configured :crashdump_dirs (newest first). Returns {:error, :not_configured} when no directory is configured - the feature's off state.

load(path)

@spec load(String.t()) :: :ok | {:error, term()}

Starts loading a dump. Progress and completion are broadcast on the "crashdump" PubSub topic as {:crashdump_progress, percent | {:error, reason} | :done} - subscribe via subscribe/0. Only paths returned by list_dumps/0 are accepted.

load_upload(path)

@spec load_upload(String.t()) :: :ok | {:error, term()}

Loads a dump from an uploaded file's already-consumed temporary path. Unlike load/1 this skips the directory allowlist: the path isn't user-supplied text but a temp file LiveView produced from a size-capped upload (see Observer.Web.Crashdump.Page).

proc_details(pid_string)

@spec proc_details(String.t()) ::
  {:ok, map()} | {:error, :no_dump_loaded | :not_found}

Full details of one process in the loaded dump, by its pid string (e.g. "<0.42.0>"), including the stack dump and message queue as expandable strings.

processes()

@spec processes() :: {:ok, [map()]} | {:error, :no_dump_loaded}

The loaded dump's process summaries (pid, name, state, current function, message queue length, reductions, memory) - the integer fields are sortable.

status()

@spec status() ::
  :idle | {:loading, String.t(), non_neg_integer()} | {:loaded, String.t()}

The server's current state: :idle, {:loading, path, percent} or {:loaded, path}.

subscribe()

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

Subscribes the caller to load progress broadcasts.