Skip to content
clushiePublic

About

exporter top, explore Prometheus exporters / Alloy metrics directly in your shell, with remote ssh connect support

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Latest commit

 

History

2 Commits

Folders and files

Repository files navigation

etop

Your exporters. A terminal away.

Live dashboards for the Prometheus metrics your host already exposes.
Discover, explore, and investigate — locally or over SSH.

Website & demo · User guide · Releases · MIT license

etop showing host CPU, memory, network and disk charts alongside discovered exporters and services. All displayed metrics are synthetic.

Try it without a host: nix run github:clushie/etop -- --demo

Watch the MP4 tour. The screenshots and recordings use synthetic metrics generated by etop; they contain no real host data.

Why etop?

Sometimes you want to understand one host, right now. etop discovers its exporters, recognizes their metrics, and builds useful terminal views while you investigate. It needs no Prometheus server, saved dashboards, or etop installation on the observed host.

  • An overview that is ready to use. CPU, memory, network and disk activity, filesystems, busy services, and the series you choose to watch.
  • Cgroups with explanations. Navigate the hierarchy and separate anonymous memory, file cache, kernel memory and swap. Drill into pressure, I/O, limits, throttling and OOM events without adding overlapping memory categories. First-class integration with arianvp/cgroup-exporter.
  • Queries without the setup. Start with suggestions from the selected exporter. Edit label filters, rates, grouping and top-k; results refresh live.
  • Your metrics, directly. Browse every exposed metric and label. Resource values come from exporters, with session history held in memory.
  • A terminal citizen. Keyboard navigation, narrow-terminal layouts, automatic light/dark appearance, explicit theme overrides, and one SSH connection.

Quick start

Nix

# Synthetic demo — no network access or target host required by the app
nix run github:clushie/etop -- --demo

# Observe another host with your existing SSH configuration
nix run github:clushie/etop -- user@host

# Observe this machine
nix run github:clushie/etop -- --local

Nix packages support x86_64-linux and aarch64-linux and bundle the local collection tools. The observed SSH host needs curl; ss is optional but enables listener discovery. Existing SSH identities, aliases, ports and jump hosts work. No sudo is required by etop.

Add it to NixOS with nixpkgs.follows

Add the input to your existing system flake. Following your nixpkgs input makes etop use the same package set as the rest of your system.

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05";
    etop.url = "github:clushie/etop";
    etop.inputs.nixpkgs.follows = "nixpkgs";
  };

  outputs = { nixpkgs, etop, ... }: {
    nixosConfigurations.my-host = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux"; # Or aarch64-linux.
      modules = [
        ./configuration.nix
        ({ pkgs, ... }: {
          environment.systemPackages = [
            etop.packages.${pkgs.stdenv.hostPlatform.system}.default
          ];
        })
      ];
    };
  };
}

Merge this into your existing configuration, keeping your machine's modules and host name, then run sudo nixos-rebuild switch --flake .#my-host. The complete example is in examples/nixos-flake.nix. The followed package set must provide the supported Textual version; the project's pinned package set is tested with Textual 8.2.6.

For Home Manager, use the same inputs, pass etop through extraSpecialArgs = { inherit etop; };, and add this to your home module:

{ pkgs, etop, ... }: {
  home.packages = [ etop.packages.${pkgs.stdenv.hostPlatform.system}.default ];
}

Python wheel from GitHub Releases

Release assets include a standard Python wheel, a source archive and checksums. Install the wheel with pipx (or pip inside a virtual environment):

pipx install https://github.com/clushie/etop/releases/download/v0.1.0/etop-0.1.0-py3-none-any.whl
etop --demo

Linux and Python 3.11+ are required. For non-demo collection, install curl and openssh; install iproute2 for ss, and GLib's gdbus for desktop appearance detection. Terminal appearance detection works independently of gdbus. This project distributes through GitHub Releases; pip install etop from PyPI is not the installation method documented here.

To build or install from a checkout:

python -m pip install .
# Or, inside nix develop:
python -m build
python -m twine check dist/*

Get oriented

Key View or action
1 Host overview and watched series
2 Cgroup hierarchy and resource details
3 Dashboard for the selected exporter
4 Metrics, labels and history
5 Alloy components and discovery diagnostics
6 Live queries and automatic suggestions
/ Search or edit the query
Enter / Esc Drill in / return
e Add a metrics URL; works without ss
a / x Merge a known duplicate route / hide an exporter
t Cycle auto, light and dark themes
Space / r Pause collection / rediscover
q Quit

In Cgroups, c, m and i sort by CPU, RAM and I/O; h toggles the tree. In metric details, r switches raw/rate and w adds the selected series to your watch list. Tab, arrows and the mouse work throughout.

Point it at your exporters

# Skip listener discovery and use explicit endpoints
etop user@host --no-discover \
  -e http://127.0.0.1:9100/metrics \
  -e http://127.0.0.1:8080/internal/metrics

# Discover an Alloy instance on a custom port
etop user@host --alloy http://127.0.0.1:12345

# A JSON snapshot with two scrapes to warm up rates
etop user@host --once

URLs are fetched from the observed host. If ss is unavailable, etop tries common ports and explains how to add endpoints. Known metric prefixes identify exporters; Alloy's configured names are retained. Equal URLs are deduplicated. Matching metric schemas suggest possible alternate routes, but independent replicas are never silently merged.

First-class cgroup integration

arianvp/cgroup-exporter is the recommended exporter for etop's cgroup v2 exploration. It collects measurements; etop turns them into an interactive hierarchy, resource explanations, charts and query suggestions. See services and slices as well as containers.

Additional metrics, including NUMA and zswap, are accessible through Metrics and Queries without dedicated resource rows. Compatible cgroup_* schemas and cAdvisor also work.

With the exporter running on its default port:

# On the observed machine
etop --local --endpoint http://127.0.0.1:13232/metrics

# From another machine; the URL is fetched over SSH on the observed host
etop user@host --endpoint http://127.0.0.1:13232/metrics

Automatic discovery recognizes its metric schema. When ss is missing, etop also probes port 13232; press e to add a custom endpoint.

For an optional NixOS setup, add these inputs alongside etop:

cgroup-exporter.url = "github:arianvp/cgroup-exporter";
cgroup-exporter.inputs.nixpkgs.follows = "nixpkgs";

Include cgroup-exporter in your flake's outputs arguments, then add these entries to your NixOS modules:

cgroup-exporter.nixosModules.default
{
  services.prometheus.exporters.cgroup = {
    enable = true;
    listenAddress = "127.0.0.1";
    port = 13232;
  };
}

The complete example installs etop and enables the exporter using its upstream module. Merge it into your existing system configuration. The loopback binding works for both local collection and etop's SSH workflow, without exposing a new public port. Enabling this example starts the exporter service; etop itself only reads metrics.

Ask a question of the data

In Queries, choose a suggestion or write an expression:

topk(10, rate(cgroup_cpu_usage_seconds_total) * 100)
topk(10, cgroup_memory_anon_bytes)
cgroup_memory_swap_current_bytes{cgroup=~".*worker.*"}
sum by (cgroup) (rate(cgroup_io_read_bytes_total[1m]))

The language is a local PromQL-style subset: selectors, label matchers, arithmetic, rate, sum, avg, min, max, count, by, and topk. It uses only the selected endpoint's retained session samples. It does not query a Prometheus server or provide full PromQL compatibility.

How collection works

local terminal ── optional SSH connection ── observed host
                                             ├─ ss: listener addresses
                                             ├─ Alloy HTTP API: local targets
                                             └─ exporter /metrics: measurements

etop makes read-only requests, keeps history in memory, and closes its SSH connection on exit. It does not install an agent, change services, or read /proc or systemd for resource measurements. Non-metric inputs are discovery metadata, local scrape timings and local appearance detection.

History starts when you open etop. Counter resets and scrape gaps suppress rates; failed scrapes retain a clearly marked stale snapshot. Cgroup parents include descendants, and memory detail categories can overlap. The UI explains these relationships rather than presenting their sum as a new total.

Supported profiles include Linux/node, cgroups/cAdvisor, nginx, PostgreSQL, Alloy, Chrome and common runtime metrics. Other exporters remain browsable and receive generic metric cards. Authenticated endpoints, native/protobuf histograms, historical backfill and replaying Alloy authentication settings are outside the current scope. See the full user guide for discovery, appearance, query semantics and collection limits.

Feature comparison

Terminal UIs only. Snapshot 2026-10-20, sorted by GitHub stars (descending). Release dates refer to the earliest published stable GitHub release and GitHub's latest stable release. — = not documented; No = unsupported; None = no published release; Backend = a separate metrics server. Column headings and dates link to sources.

Feature btop below otel-tui Ember grom promexplorer Peat etop
GitHub stars 35,047 2,536 1,109 386 54 29 0 0
First GitHub release 2021-09-18 2025-02-25 2024-06-17 2026-03-26 2026-07-07 2023-04-02 None 2026-10-20
Latest release 2026-05-01 (v1.4.7) 2025-09-24 (v0.11.0) 2026-09-12 (v0.7.5) 2026-10-12 (v1.6.2) 2026-07-09 (v0.3.0) 2023-05-03 (v0.0.5) None 2026-10-20 (v0.1.0)
Metric source Kernel Kernel OTLP / exporters Caddy APIs Prometheus Exporter Prometheus Exporters
Target setup Local host Local host Explicit targets Caddy address Backend Explicit URL Backend Listeners + Alloy
Built-in SSH collection — — — — — — — Yes
Cgroup tree — Yes — — — — — Yes
Queries — — — — Backend PromQL — Backend PromQL Local subset · Full PromQL: Vote for this feature
History Session charts Record / replay JSON import Session charts Backend — Backend Session · Save & replay: Vote for this feature
Grafana JSON import — — — — Yes — — No · Vote for this feature
Traces — — Yes — — — — No · Vote for this feature
Logs — — Yes Yes — — — No · Vote for this feature

Feature votes use GitHub Discussion upvotes; proposals are not release commitments.

Development

nix develop
python -m etop --demo
pytest -q
ruff check .
nix flake check
nix build

The test suite covers discovery, missing tools, alternate routes, parsing, rates, memory accounting, queries, terminal replies, SSH cleanup and keyboard navigation. nix develop also includes the Python packaging and demo recording tools. Rebuild the synthetic screenshots and MP4 tours with:

python scripts/record_demo.py

The website is buildless HTML/CSS/JS in site/, with no analytics, external fonts, or third-party scripts. Preview it using python -m http.server 8080 --directory site. GitHub Actions deploys that directory to Pages when main changes. A v* tag runs tests, builds the wheel/source archive, checks metadata and publishes release assets. The tag must match the version in pyproject.toml.

Contributions and bug reports are welcome. Include your terminal, etop version, and a small sanitized metric example when reporting exporter behavior.

MIT · Built with Textual, Prometheus client and Nix.

About

exporter top, explore Prometheus exporters / Alloy metrics directly in your shell, with remote ssh connect support

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages