CLI tool
zhongwencool/observer_cli avatar
zhongwencool/observer_cli

observer_cli: Bounded BEAM Diagnostics from the Command Line

Visualize Erlang/Elixir Nodes On The Command Line

1,536 stars95 forksErlangMIT

At a glance

What is it?
observer_cli turns questions about Erlang and Elixir nodes into bounded, evidence-based inspections with text or JSON output. It suits operators and automation that need controlled visibility into CPU, memory, mailboxes, connections, processes, ports, and traces.
Who is it for?
Adopt observer_cli when an engineer needs repeatable, bounded inspection of an Erlang or Elixir node and can supply a trusted distribution target and protected cookie. Do not adopt it if the target lacks `observer_cli` and `recon`, if OTP 26 must produce JSON, or if you need persistent saved connections.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 16 days ago.
What is it written in?
Mainly Erlang, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Why observer_cli targets BEAM investigations

observer_cli is designed for a specific operational problem: understanding a live Erlang or Elixir node without beginning with an open-ended dashboard or a blanket diagnostic session. Its intended users include engineers diagnosing scheduler pressure, resource pressure, mailbox growth, process behavior, ports, connections, and node activity. The workflow is built around a question, a bounded observation, and a smaller follow-up command. That design is useful when an investigation needs evidence that can be read by a person or processed by automation.

The tool covers a defined set of runtime views. `check` can examine the whole node or focus on `cpu`, `memory`, `mailbox`, or `connections`. `inspect RESOURCE` exposes runtime facts, rankings, or detail for resources such as processes and ports. Tracing is separate under `trace call` and `trace stop`, while `tui` supports continuous interaction with existing pages and plugins. This is not presented as a general-purpose log viewer or a complete replacement for the standard Erlang Observer interface.

Each command has a time or resource boundary defined by its interface. A bare `check` observes for 15 seconds. Focused examples use a five-second window. This bounded approach makes the output easier to interpret and gives automation a defined observation period. However, a lack of findings is not proof that the node is healthy. The documentation explicitly warns that a short check can miss intermittent behavior, so the command supports a next step rather than presenting absence of evidence as a health certificate.

How observer_cli reaches and evaluates a node

observer_cli is a controller-side CLI packaged as an Erlang escript. It connects through BEAM distribution to an explicitly named node. The operator supplies the target and directs the CLI to an environment variable containing the distribution cookie. The cookie is not placed directly in the command arguments, which reduces exposure through process listings and shell history, but it remains a powerful secret because BEAM distribution grants trusted-peer execution authority.

The current checkout describes a redesign with protocol 2 and a matching `2.1.0` bundle requirement on the target. Commands are explicit about their target rather than retaining a connection between calls. The README states that there is no saved connection and no `connect` or `disconnect` step. That design favors clear authorization at each invocation and makes automation easier to reason about, though it also requires automation to supply the target and cookie reference every time.

Default checks collect operational evidence without reading business contents, state, logs, or traces. State access and tracing require specific consent, and loading TUI code requires both `--load-code` and a matching OTP major. Results can be rendered as concise text or JSON. JSON is intended for agents and scripts, with a public schema at `priv/schema/observer_cli.cli.v2.schema.json`. Selectors should be followed as typed fields rather than display labels. Suggestions emitted during diagnostics do not execute themselves.

The tool distinguishes activity from processor time. In particular, reductions per second measure activity associated with process reductions, not process CPU time. That distinction matters when interpreting scheduler rules or comparing processes. Identifiers are included to support follow-up commands, while `--redact` can hide selected metadata before sharing. The README does not claim that redaction makes results harmless, because counts, topology, and arbitrary logs can remain sensitive.

Building observer_cli and preparing a distributed target

This checkout must be built locally. The README says the resulting commands do not publish a release, so operators should not interpret successful compilation as an installed system-wide tool. The Erlang controller requires Erlang/OTP 26 through 29. JSON requires controller OTP 27 or newer; OTP 26 supports text and term output but rejects JSON before attempting a connection.

The escript route requires `rebar3`. Build it, then invoke the generated executable and check its reported version:

sh
rebar3 escriptize
./_build/default/bin/observer_cli --version

The alternative documented toolchain uses OTP 29 and Elixir 1.20:

sh
mix deps.get
mix escript.build
./observer_cli --version

Before connecting, the target release must include both `observer_cli` and `recon`. The controller does not upload missing code as part of command diagnostics. This requirement is an important deployment constraint. A successful local build cannot make an older or incomplete target instrumentable, and mixing bundle versions can violate the documented protocol requirement.

The checkout implements unreleased 2.1.0 and calls it a breaking redesign. Its README instructs users to retain a versioned 2.0 binary until the migration guide has been applied. That note matters when reproducing the quick-start commands against a node rather than building the current checkout. Before using the new commands, confirm that both the controller and target bundle match the selected protocol version.

The project is published under the MIT license. That identifies the license recorded for the repository, but operators still need to account for their own distribution, security, and compliance requirements.

Running a first CPU and process investigation

Start by setting the distributed target. The cookie must come from a protected secret source, so this example deliberately sets only the node variable:

sh
export OBSERVER_CLI_NODE='app@host'

Run an initial connectivity and bounded health check. A bare `check` uses a 15-second observation and evaluates VM-limit and scheduler-pressure rules:

sh
observer_cli check

The output should contain the observed evidence and any suggested next steps. It may also contain findings. A completed check exits with status `0` even when findings exist, so automation that needs findings to affect job status must opt into `--fail-on`.

To shorten a focused CPU investigation, use a five-second window:

sh
observer_cli check cpu --window 5s

If process activity needs ranking, request process inspection sorted by reductions rate over the same bounded period:

sh
observer_cli inspect process --sort reductions-rate --window 5s

For a specific process, use a quoted BEAM identifier:

sh
observer_cli inspect process --pid '<0.123.0>'

For automation, bind the target on every call, read the cookie from the named environment variable, and request JSON:

sh
observer_cli check cpu --window 5s \
  --node 'app@host' --cookie-env OBSERVER_CLI_COOKIE --json

Use `observer_cli --help` for the command overview. For exact field names and constraints, the README points to `describe inspect process --json`, the CLI reference, and the public JSON schema. Those discovery paths are preferable to scraping terminal text, especially when another tool will consume the results.

Tracing, TUI access, and the trust boundary

observer_cli includes more invasive capabilities, but does not make them equivalent to a default check. `trace call` begins explicitly authorized, node-global tracing, and `trace stop` ends it. Because the scope is the node rather than one process, tracing needs careful authorization. The project documentation does not provide an access-control model inside observer_cli itself. Trust depends on the BEAM distribution boundary and the cookie supplied to the controller.

That boundary is substantial. An Erlang cookie grants trusted-peer execution authority, and BEAM distribution is not encrypted by default. The README therefore directs users toward trusted nodes and trusted transport. It does not claim that using `--redact` makes an operational result safe for an arbitrary recipient. Process counts, connection topology, identifiers, and logs can expose information even after some fields are removed. In particular, arbitrary logs cannot be reliably redacted.

The `tui` command provides continuous interaction with existing pages and plugins. It is not the same as the bounded command model. Loading code into the target requires `--load-code` and the same OTP major, which prevents accidentally mixing code built for different major runtime versions. Even with that guard, code loading changes what the controller can execute against the node and should be treated as privileged operational access.

observer_cli is therefore the wrong choice for an untrusted network, a shared cookie, or a workflow that assumes distribution traffic is confidential by default. It is also a poor fit where only static configuration review is available. The target must be live, reachable, and prepared with the required bundle.

Limits, maintenance, and the choice against dashboard workflows

The clearest limitation is compatibility. The current checkout is not the published 2.0 release line described in the quick-start text, and it targets a breaking redesign. The target needs the matching 2.1.0 bundle and protocol 2. The controller has a separate OTP boundary: versions 26 through 29 are supported, but JSON begins at OTP 27. These are adoption constraints rather than minor setup details.

The tool also limits concurrency implicitly through its operating model. The README says to use one active observation per target and warns that per-request budgets do not limit aggregate concurrent load. This matters when several agents schedule checks against the same production node. A short observation window does not make overlapping investigations free.

A real alternative is an open-ended dashboard or ad hoc remote shell workflow. A dashboard can support continuous browsing without making every invocation a fresh CLI request, while an operator can issue arbitrary BEAM commands during an active troubleshooting session. observer_cli takes the opposite approach: short commands, explicit target binding, typed output, bounded evidence, and optional JSON. That makes it more suitable for scripted investigations, but it cannot provide the same persistent browsing or arbitrary expression surface. observer_cli is also not a replacement for a full logging, tracing, or application-level metrics system. Its documented scope is BEAM runtime inspection.

Maintenance activity is recent according to the repository record. It is not archived, and its last push was on 2026-10-07. The recorded releases include `v2.0.0` on 2026-07-14 and `1.8.8` on 2026-07-04, so teams using an older release should account for version skew. Upgrade planning is not free because the current branch announces a breaking redesign and supplies a dedicated migration guide at `docs/guides/migrate-2-1.md`.

Editorial conclusion

Adopt observer_cli when an engineer needs repeatable, bounded inspection of an Erlang or Elixir node and can supply a trusted distribution target and protected cookie. Do not adopt it if the target lacks `observer_cli` and `recon`, if OTP 26 must produce JSON, or if you need persistent saved connections. Verify the controller and target bundle versions, protocol compatibility, OTP major, distribution transport, and the exact metric meaning before using findings as an operational decision. The checked-out `main` branch is tied to an unreleased 2.1.0 redesign, so a versioned 2.0 binary remains necessary until migration is complete.

Frequently asked questions

What does observer_cli do?

observer_cli visualizes and investigates Erlang and Elixir nodes from the command line. Its commands cover bounded checks, resource inspection, explicitly authorized tracing, and a terminal UI.

How do I build observer_cli?

The documented Erlang build uses `rebar3 escriptize` and requires Erlang/OTP 26 through 29. An alternative documented build uses OTP 29, Elixir 1.20, `mix deps.get`, and `mix escript.build`.

What must be configured before observer_cli connects to a node?

Set `OBSERVER_CLI_NODE` to the distributed node and obtain `OBSERVER_CLI_COOKIE` from a protected secret source. The target release must also include `observer_cli` and `recon`.

Does observer_cli support JSON on Erlang/OTP 26?

No. JSON requires controller OTP 27 or newer. OTP 26 supports text and term output and rejects JSON before connecting to the node.

Are the commands in the main checkout part of a released version?

No. The README describes this checkout as implementing unreleased 2.1.0, a breaking redesign, and advises keeping a versioned 2.0 binary until migration is complete.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. zhongwencool/observer_cli on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/zhongwencool-observer-cli.svg)](https://hysenlabs.com/projects/zhongwencool-observer-cli)

Was this useful?