Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

51 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TOPIC

topic: top inside a container

A top-like tool for containers that displays resource usage based on cgroup limits, not the host's resources.

CI Latest Release


The Problem

Traditional monitoring tools like top or htop, when run inside a container, report resource usage as a percentage of the host machine's total resources. When working in containerized environments like Kubernetes Pods, it is hard to monitor the resource usage from inside the container.

For example, a container with a 2GB memory limit on a 128GB host may be using 1.8GB of RAM. While htop would show a negligible system-wide usage, the container is actually at 90% of its capacity and is dangerously close to being OOMKilled with no warning.

The Solution

topic (top inside a container) is a simple terminal-based monitoring tool that solves this problem. It reads the container's resource limits directly from the cgroup filesystem and calculates all usage percentages based on those limits.

This provides an accurate view of how close a container is to its resource boundaries, without the need to access the host or external monitoring tools.

Current topic dashboard showing system metrics and the process table

The screenshot is captured inside a demo container limited to 2 CPUs, 2 GiB of memory, and 256 PIDs, with a synthetic CUDA workload using an attached GPU.

Dashboard

The system panel adapts to the terminal width. Wide terminals use two aligned resource columns; narrower terminals switch to one column and truncate secondary details before hiding primary measurements.

  • CPU, memory, storage, and GPU rows share the same label, percentage, bar, and detail alignment.
  • Network and disk throughput, PID usage, cgroup pressure, and metric history use a shared label gutter for quick scanning.
  • Utilization is green below 70%, gold from 70% to 89.9%, and red at 90% or above.
  • Docker, Kubernetes, and NVIDIA/NVML availability is shown in the compact status panel. Missing integrations remain non-fatal.

Installation

You can install the latest version of topic with a single command. The script will automatically detect your system's architecture (amd64/arm64) and install the binary to a directory in your PATH.

curl -s https://raw.githubusercontent.com/yurirocha15/topic/master/install.sh | bash

or for containers based on alpine:

wget -qO- https://raw.githubusercontent.com/yurirocha15/topic/master/install.sh | sh

The script will attempt to install to /usr/local/bin (prompting for sudo if needed). If that fails, it will fall back to $HOME/.local/bin and notify you if you need to add this directory to your PATH.


Usage

After installation, simply run the command:

topic

Common options:

topic --refresh=2s        # change refresh interval
topic --no-gpu           # disable GPU collection
topic --no-docker        # disable Docker metadata lookup
topic --no-kubernetes    # disable Kubernetes metadata lookup
topic --no-nvml          # disable NVML/NVIDIA integration status
topic --ascii            # start with the large ASCII logo visible
topic --once             # print one text snapshot and exit
topic --once --json      # print one JSON snapshot for scripts
topic --sort=mem         # initial sort: cpu, mem, gpu, gpumem, pid, user, command

Controls

  • Quit: q or Ctrl+C
  • Navigate: Use the arrow keys (, , , ) or mouse to scroll through the process list.
  • Filter mode: / to enter, type to filter, Ctrl+U to clear, Esc to leave.
  • Sort mode: s to enter, / to choose a column, / to choose direction, Esc to leave.
  • Process details: Enter
  • Signal process: k
  • Pause refresh: p
  • Tree view: t
  • Toggle logo: a
  • Help: ?

Building from Source

If you prefer to build the project yourself, you will need:

  • Go (version 1.23 or later)
  • make

Clone the repository and run the build command:

git clone https://github.com/yurirocha15/topic.git
cd topic
make build

The compiled binary will be available at ./dist/topic.

Testing

Run the standard validation gates from the repository root:

make test
make lint
make build

Race detection and benchmarks run directly from the Go module:

cd pkg
go test -race ./...
go test -bench=. -benchmem -count=5 ./...

The test suite includes simulated TUI renders at compact, medium, and wide terminal sizes, plus input-flow coverage for filtering, sorting, process details, and clean shutdown.

Testing Integrations

The normal test suite uses fake Docker, Kubernetes, and NVML providers so it does not require host services:

make test-integrations

This target also runs scripts/smoke-integration.sh, which executes topic --once --json and validates that Docker, Kubernetes, and NVML integration statuses are present in the JSON snapshot.

To validate that integrations work inside real environments, use the opt-in E2E targets:

make e2e-docker
make e2e-kubernetes
make e2e-integrations   # runs both

make e2e-docker requires Docker and /var/run/docker.sock. It builds a local image, runs topic --once --json inside Docker with the Docker socket mounted, and asserts Docker metadata is actually available.

make e2e-kubernetes requires kubectl connected to a cluster. By default it builds a local Docker image named topic:e2e-kubernetes; if your cluster cannot see local Docker images, publish an image yourself and run:

TOPIC_KUBE_E2E_BUILD_IMAGE=0 TOPIC_KUBE_E2E_IMAGE=registry.example.com/topic:e2e make e2e-kubernetes

For kind clusters, the script automatically loads the local image when the current context starts with kind-.

For k3s clusters, the script can import the local image only when it is run as root or passwordless sudo is available. Otherwise, publish the image to a registry or manually import it into k3s/containerd before running the target.

For single-node local clusters where the Kubernetes node can access this checkout path, you can avoid image publishing by mounting the built binary into a stock Alpine pod:

TOPIC_KUBE_E2E_USE_HOSTPATH=1 make e2e-kubernetes

Live integration discovery is opt-in:

TOPIC_LIVE_INTEGRATION_TESTS=1 make test-integrations

Live tests assert that discovery returns well-formed statuses without hanging or crashing. They do not require every integration to be available; unavailable Docker, Kubernetes, or NVIDIA/NVML environments are valid results. Use the E2E targets above when you need to prove an integration is available and returning correct metadata in its native environment.


Contributing

Contributions are welcome! If you find a bug or have a feature request, please open an issue on the GitHub Issues page.


License

This project is licensed under the MIT License.

About

Top inside containers

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages