c0m4r/kula: Lightweight, self-contained Linux® server monitoring tool · GitHub


Kula collects system metrics every second by directly reading /proc And /sysStores them in a built-in tiered ring-buffered storage engine, and serves them through a real-time web UI dashboard and a terminal TUI.

metric what has been collected
CPU Total usage (user, system, iowait, irq, softirq, steal) + core count
Burden 1 / 5 / 15 min average, running and total work
Memory total, free, available, used, buffers, cached, shy
Change total, free, used
network Per-interface throughput (Mbps), packets/s, errors, drops; TCP errors, reset, established connection; socket counts
Disc Per-device I/O (read/write bytes/s, reads/s, writes/s IOPS); file system access
System Uptime, Entropy, Clock Sync, Hostname, Logged-in User Count
processes Running, sleeping, getting blocked, zombie matters
Self Kula’s own CPU%, RSS memory, open file descriptors


                    ┌──────────────────────────────────────────────┐
                    │              Linux Kernel                    │
                    │     /proc/stat  /proc/meminfo  /sys/...      │
                    └──────────────────┬───────────────────────────┘
                                       │ read every 1s
                                       ▼
                              ┌──────────────────┐
                              │    Collectors    │
                              │  (cpu, mem, net, │
                              │   disk, system)  │
                              └────────┬─────────┘
                                       │ Sample struct
                          ┌────────────┼────────────┐
                          ▼            ▼            ▼
                   ┌────────────┐  ┌────────┐  ┌──────────┐
                   │  Storage   │  │  Web   │  │   TUI    │
                   │  Engine    │  │ Server │  │ Terminal │
                   └─────┬──────┘  └───┬────┘  └──────────┘
                         │             │ 
              ┌──────────┼─────────┐   └───────────┐  HTTP + WebSocket
              ▼          ▼         ▼               ▼
          ┌─────────┬─────────┬─────────┐  ┌───────────────┐
          │ Tier 1  │ Tier 2  │ Tier 3  │  │   Dashboard   │
          │   1s    │   1m    │   5m    │  │   (Browser)   │
          │ 250 MB  │ 150 MB  │  50 MB  │  └───────────────┘
          └─────────┴─────────┴─────────┘
             Ring-buffer binary files
             with circular overwrites

data persists Pre-allocated ring-buffer files per level. Each level file has a fixed maximum size – when it is full, new data overwrites the oldest entries. It provides predictable, limited disk usage without requiring any cleanup.

  • tier 1 – Raw 1-second samples (default 250 MB)
  • tier 2 – 1-minute aggregate: average CPU and network, last-value gauge (default 150MB)
  • tier 3 – 5 minute aggregate, same logic (default 50 MB)

The HTTP server exposes a REST API (/api/current, /api/history, /api/config) and a WebSocket endpoint (/ws) for live streaming. Authentication is optional – when enabled, it uses Argon2id hashing with salt and session cookies or bearer tokens.

The frontend is a single-page application embedded in the binary. Built on Chart.js with custom SVG gauges, it connects via WebSockets for live updates and falls back to the History API for longer periods of time. Features include:

  • Interactive zoom with drag-select (auto-pauses the live stream)
  • Focus mode to show only selected graphs
  • Grid/Stacked List Layout Toggle
  • Alert system for clock sync and entropy problems
  • Gap detection for missing data points

Example installation methods for amd64 (x86_64) GNU/Linux.

Check Release for Hand And RISC-V packages.

wget https://github.com/c0m4r/kula/releases/download/0.7.1/kula-0.7.1-amd64.tar.gz
echo "6baff6bee9f9bbf56adc6e264e7ff9e1dfa763e7bab76a21dbc1e7d4be0397f4 kula-0.7.1-amd64.tar.gz" | sha256sum -c || rm kula-0.7.1-amd64.tar.gz
tar -xvf kula-0.7.1-amd64.tar.gz
cd kula
./kula
wget https://github.com/c0m4r/kula/releases/download/0.7.1/kula_0.7.1_amd64.deb
echo "bbcd6ee65441c85f5bc835c40a1afaabc78b78d976c25e535c051b29ad514185 kula_0.7.1_amd64.deb" | sha256sum -c || rm kula_0.7.1_amd64.deb
sudo dpkg -i kula_0.7.1_amd64.deb
systemctl status kula
git clone https://github.com/c0m4r/kula.git
cd kula
bash addons/build.sh

kula uses Argon2ID For password hashing. If you enable authentication, it is highly recommended to tune Argon2 parameters (time, memory, threads) In config.yaml Depending on your hardware capabilities to increase resistance against cracking.

Important: Yours config.yaml The file contains plain text password_salt and generate password_hash. Make sure the configuration file is protected from unauthorized access on the server:

chmod 0600 /path/to/kula/config.yaml
# 1. Copy and edit config
cp config.example.yaml config.yaml

# 2. Start the server
./kula serve
# Dashboard at http://localhost:8080

# 3. Or use the terminal UI
./kula tui

Authentication (optional)

# Generate password hash
./kula hash-password

# Add the output to config.yaml under web.auth

Init system files are provided addons/init/: :

# systemd
sudo cp addons/init/systemd/kula.service /etc/systemd/system/
sudo systemctl enable --now kula

# OpenRC
sudo cp addons/init/openrc/kula /etc/init.d/
sudo rc-update add kula default

# runit
sudo cp -r addons/init/runit/kula /etc/sv/
sudo ln -s /etc/sv/kula /var/service/

running behind reverse proxy (nginx)

server {
    listen 80 ;
    listen [::]:80 ;
    server_name kula.localhost;

    location / {
        proxy_pass http://localhost:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

All settings are live config.yaml. Look config.example.yaml For default.


# Lint + test suite
bash ./addons/check.sh

# Build dev (Binary size: ~11MB)
CGO_ENABLED=0 go build -o kula ./cmd/kula/

# Build prod (Binary size: ~8MB)
CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -buildvcs=false -o kula ./cmd/kula/

To safely update only Go modules used by Kula to their latest minor/patch versions, and remove any unused dependencies:

go get -u ./...
go mod tidy
# Run unit tests with race detector
go test -race ./...

# Run the full storage benchmark suite (default: 3s per bench)
bash addons/benchmark.sh

# Shorter run for quick iteration
bash addons/benchmark.sh 500ms

# Python scripts formatter and linters
black addons/*.py
pylint addons/*.py
mypy --strict addons/*.py

Benchmarks cover the full storage engine: codec encode/decode, ring-buffered write throughput, concurrent writes, queryranges in different sizes (small/large/wrapped), QueryLatest Cache versus cold-disk paths, multi-level aggregation, and inline downsamplers.

bash addons/build.sh cross    # builds amd64, arm64, riscv64
bash addons/build_deb.sh
sudo dpkg -i dist/kula_*.deb
bash addons/build_aur.sh
cd dist/aur && makepkg -si
bash addons/docker/build.sh
docker compose -f addons/docker/docker-compose.yml up -d

kula/
├── cmd/
│   ├── kula/
│   │   └── main.go             # CLI entry point, flag parsing, commands
│   └── gen-mock-data/
│       └── main.go             # Mock data generator utility
├── internal/
│   ├── collector/              # Metric collectors (/proc, /sys readers)
│   │   ├── collector.go        #   Orchestrator — gathers all metrics
│   │   ├── types.go            #   Sample struct (CPU, mem, net, disk...)
│   │   ├── cpu.go              #   /proc/stat parser
│   │   ├── memory.go           #   /proc/meminfo parser
│   │   ├── network.go          #   /proc/net/* parser
│   │   ├── disk.go             #   /proc/diskstats + /proc/mounts
│   │   └── system.go           #   Uptime, entropy, hostname
│   ├── config/                 # YAML config loader with defaults
│   ├── sandbox/                # Linux Landlock sandboxing
│   ├── storage/                # Tiered ring-buffer engine
│   │   ├── store.go            #   Multi-tier coordinator + aggregation
│   │   ├── tier.go             #   Single ring-buffer file
│   │   └── codec.go            #   JSON encode/decode for samples
│   ├── tui/                    # Terminal UI (bubbletea + lipgloss)
│   └── web/                    # HTTP/WebSocket server
│       ├── server.go           #   Routes, API handlers, startup
│       ├── websocket.go        #   Live streaming hub + client mgmt
│       ├── auth.go             #   Argon2id auth, sessions, middleware
│       └── static/             #   Embedded SPA (served from binary)
│           ├── index.html      #     Dashboard markup
│           ├── app.js          #     Charts, WebSocket, UI logic
│           └── style.css       #     Dark theme, glassmorphism
├── addons/
│   ├── inspect_tier.py         # Standalone Python script for reading tiers
│   ├── benchmark.sh            # Storage engine benchmark suite (formatted output)
│   ├── build.sh                # Cross-compile (amd64/arm64/riscv64)
│   ├── build_deb.sh            # Debian package builder
│   ├── build_aur.sh            # Arch AUR PKGBUILD generator
│   ├── check.sh                # Linting + testing
│   ├── kula.1                  # Man page
│   ├── release.sh              # CI packaging wrapper
│   ├── bash-completion/        # Bash completion script
│   ├── docker/                 # Dockerfile + compose
│   └── init/                   # Service files (systemd/openrc/runit)
├── config.example.yaml
├── VERSION                     # Single source of truth for version
├── CHANGELOG
└── LICENSE                     # AGPL-3.0

GNU Affero General Public License v3.0


  • Linux® is a registered trademark of Linus Torvalds in the US and other countries.
  • Chart.js library is licensed under MIT



<a href

Leave a Comment