Kubernetes multi pod and container log tailing in Rust inspired by the original stern
Requires Rust 1.88+ (rust-version in Cargo.toml).
make release # → target/release/rstn
make install # → ~/.cargo/bin/rstn
make install-local # → ~/.local/bin/rstnVerify: rstn --version
Ensure ~/.cargo/bin (or your install dir) is on PATH:
export PATH="$HOME/.cargo/bin:$PATH"Uninstall: make uninstall
Behavior is tracked against stern; not every flag matches yet.
- Pod name query with
-l/--field-selector: when--selector/-lor--field-selectoris set, the positional QUERY may be omitted (implicit.*). With-l, a positional.is still treated as.*in the runner (Rust regex.is one character). - Namespaces: repeat
-n/--namespaceand/or comma-separate in one value (-n a,b); trim, drop empties, dedupe while keeping first-seen order.-A/--all-namespacesconflicts with-nand ignores explicit namespaces. With neither, use the active kube context's namespace from kubeconfig (fallbackdefault; kubeconfig read errors fail before run). --max-log-requests: defaults match stern’s intended caps (50with follow /5with--no-follow) when omitted; when following, exceeding--max-log-requestsconcurrent openings ends with an error instead of blocking indefinitely.- Timestamps / log window:
-sis a short alias for--since(relative duration or seconds).--since-timeaccepts an RFC3339 timestamp (kubectl parity; mutually exclusive with--since).--previousfetches logs from the previous terminated container instance. Line prefixes are off unless-t/--timestampsis set (bare flag → sterndefault/ RFC3339 nano;short→MM-DD HH:MM:SS).--timezonedefaults to local (stern parity);utcor an IANA zone overrides.epochandomitare also accepted. - Which containers: repeatable
-E/--exclude-container(comma-separated in one flag allowed);--init-containers/--no-init-containersand--ephemeral-containers/--no-ephemeral-containersfollow stern-style defaults (both kinds included unless opted out);--container-state running|waiting|terminated|alllimits streams using Pod container statuses (filtered modes skip containers whose status is not known yet). -H/--highlight: merged with-i/--includeand applied after default formatter lines (bold-red emphasis akin to stern); ineffective for--format raw|json.--only-log-lines: stern suppresses +/- attach banners on stderr; rustern does not emit equivalents yet—the flag stays for parity and only logs at debug level internally.kind/namepod selection (stern parity): supported kinds arepod,replicationcontroller,service,daemonset,deployment,replicaset,statefulset, andjob(short aliases such asdeploy,rs,ds,sts,svc,rc,powork too). For a single namespace, rusternGETs the workload and builds the label selector from its spec (includingmatchExpressions). With multiple-nvalues, it resolves per namespace and uses the common selector when they agree; otherwise it falls back toapp=<name>. With-A/--all-namespaces, selectors can differ per namespace, so rustern always uses the legacyapp=<name>fallback. Not supported today:cronjob,horizontalpodautoscaler, and other controller kinds stern does not list either.
--exit-on REGEX(repeatable): exit code 1 on first raw log line matching any pattern (evaluated before-i/-e, so hidden lines still trigger exit). Useful for CI/smoke.--exit-on-level LEVEL: exit code 1 when classified log level is at or aboveLEVEL(trace<debug<info<warn<error). Uses--level-keywhen set; works with follow and one-shot.