LOOG is a small TUI program that records every change made to one or more Kubernetes resources and lets you browse those revisions.
[ Quick Start • Installation • Contributing • ]
demo.mp4
loog watches Kubernetes resources and records every change as a revision.
You can run it interactively (TUI) to explore history as it happens,
or headless to collect revisions into a .loog file for later analysis (or both).
Tip
Run loog --help for the full flag reference and shell completions.
# Watch Pods cluster-wide in the TUI (temporary file; deleted on exit)
loog v1/pods# Watch Deployments and Services
loog apps/v1/deployments v1/services# Limit what gets recorded using a filter (see "Filtering" below)
loog -f 'Namespaces("prod","kube-system")' v1/podsResources are specified as Group/Version/Resource (GVR) strings, e.g. v1/pods, apps/v1/deployments,
batch/v1/jobs. You must provide at least one resource to watch or load an older recording using --output [FILE] file (or both).
Note
LOOG uses your kubeconfig and RBAC. You'll only see/list/watch what your credentials allow.
# Interactive (TUI) - default mode
loog apps/v1/deployments v1/pods- Opens a terminal UI and starts watching the given resources cluster-wide.
- Revisions are written to a store (temp file by default).
- Exit the TUI to stop; the temp store is removed on exit.
# Headless - collect only, no TUI (Ctrl+C to stop)
loog -H -o history.loog apps/v1/deployments v1/pods- Runs without UI and appends revisions to
history.looguntil interrupted. - Safer for long-running collection jobs and CI.
# Explore an existing file later (no new watches started)
loog -o history.loog- Opens the TUI over the saved revisions in
history.loog.
The -f/--filter flag takes an expr-lang boolean expression.
By default, it's All() (record everything).
Built-in helpers make it easy to filter by namespace, name, or both:
Namespaces("ns1", "ns2", ...)(alias:Namespace(...)) checks if the object is in one of the given namespaces.Names("n1", "n2", ...)(alias:Name(...)) checks if the object has one of the given names.Namespaced("namespace", "name")checks if the object is a namespaced resource with the given namespace and name.LabelExists("key1", "key2", ...)checks if the object has any of the given labels.Label("key", "value")checks if the object has a label with the given key and value.
Examples:
# Only objects in prod and kube-system
loog -f 'Namespaces("prod","kube-system")' v1/pods
# Only specific objects by name (cluster-wide)
loog -f 'Names("nginx","api")' v1/services
# A single namespaced object
loog -f 'Namespaced("default","nginx-deployment")' apps/v1/deployments
# Combine with boolean logic
loog -f 'Namespaces("prod") && !Names("tmp","scratch")' v1/configmapsYou can also reference the live event and object:
Event.Typeis one ofADDED|MODIFIED|DELETEDObjectis a Kubernetesunstructured.Unstructured
# Only record live MODIFIED events in prod
loog -f 'Event.Type == "MODIFIED" && Namespace("prod")' v1/pods
# Filter by label
loog -f 'Object.GetLabels()["app"] == "web" && Object.GetNamespace() == "adm"' apps/v1/deploymentsImportant
Filters are evaluated before writing live events.
Non-matching resources are not added to the database.
When opening an existing .loog file, the filter acts as a view in the UI (it doesn't delete data).
--snapshot-interval, -s <N>: write a full snapshot every N patches (default8).--no-durable-sync: skip fsync on each commit (higher throughput, unsafe on crashes).--disable-cache: disable the in-memory cache layer.
--kubeconfig <path>(default:$HOME/.kube/config)--debug: write verbose logs todebug.log(--truncate-debugto start fresh)- this is useful for debugging the TUI
go install github.com/loog-project/loog@latestor clone and build from source:
git clone https://github.com/loog-project/loog
cd loog
go install . # or: make buildLOOG supports shell completions for bash, zsh, fish and powershell.
To install completions for bash, zsh and fish, add the following lines to your shell configuration file
# bash
source <(loog completion bash)
# zsh
source <(loog completion zsh)
# fish
loog completion fish | source
# powershell
loog completion powershell | Out-String | Invoke-ExpressionYou can use
make link-kubectlto automatically install LOOG as akubectlplugin. Usemake unlink-kubectlto remove the plugin.
To install LOOG as a kubectl plugin, copy or link the LOOG binary to your PATH:
ln -s $(which loog) $(dirname $(which loog))/kubectl-observe
kubectl observe v1/configmapsNote that the plugin does not support shell completions yet.
You can use
make link-k9sto automatically install LOOG-shortcuts fork9s. Usemake unlink-k9sto remove the shortcuts.
To install LOOG-shortcuts for k9s, copy the compat/k9s/plugins.yaml to your
k9s plugins directory or extend your existing plugins.yaml.
# macOS
mkdir -p ~/Library/Application\ Support/k9s/plugins
cp ./compat/k9s/plugins.yaml ~/Library/Application\ Support/k9s/plugins/loog-plugins.yaml
# Unix
mkdir -p ~/.config/k9s/plugins
cp ./compat/k9s/plugins.yaml ~/.config/k9s/plugins/loog-plugins.yamlThe code base is very young and still moving quickly. Pull requests are welcome, but opening an issue first avoids wasted work if the surrounding code changes while you are developing.
Development requires the usual Go tool-chain and a running Kubernetes cluster (Kind or Minikube is enough).
Unit tests run with go test ./....
