_
| | ___ __ _ ___ _ __ _ ___ __
| |/ _ \ / _` |/ __| '__| | | \ \/ /
| | (_) | (_| | (__| | | |_| |> <
|_|\___/ \__, |\___|_| \__,_/_/\_\
|___/
an intelligent, fully local log analyzer. point it at a log, it tells
you what's actually wrong.
works on any text log, and natively understands 200+ web, database,
container, cloud, security, and Linux/Unix system-log formats.
no cloud. no telemetry. no account. uv tool install --python 3.12 logcrux and go.
[ Apache-2.0 ] [ Python ≥3.11 or uvx ] [ runs unprivileged ] [ works offline ]
logcrux reads a log file (nginx, postgres, kubernetes, syslog, auth, whatever) and tells you if something is actually wrong. Bursts and spikes, yes, but also the failures that are a single line: a crashed backend, a backup job that did not run, an app that died on an unhandled exception, an expired certificate, a disk that went read-only, a proxy with no live backend, a process out of file descriptors.
Every finding says what it is about (the attacking IPs and users, the process the OOM killer chose, the unit that crashed) and points at the log lines, by number, that prove it. A clean result says what was checked. Everything runs on your machine. No server component, no API key, no log data ever leaves the box it runs on.
Point it at a file, or pipe a stream into it:
$ logcrux /var/log/syslog
$ logcrux /var/log/nginx/
$ journalctl -b | logcrux
$ docker logs myapp 2>&1 | logcrux
$ kubectl logs deploy/api --previous | logcrux
See install to get it running and usage for the full command reference.
An actual run against a server's journal after a bad afternoon: an OOM kill, a crash-looping service, a rejected nginx config and an SSH brute force.
$ journalctl -b | logcrux
╭──────────────────────── CRITICAL Out of Memory ─────────────────────────╮
│ ● OOM killer fired (6 events) │
│ 2026-10-19 19:41:55 → 19:42:14 (19s) │
│ killed: tail ×2 · cgroup: /system.slice/report-export.service ×1 │
│ line 1443: kernel: Memory cgroup out of memory: Killed process 17110 (… │
│ line 1444: systemd: report-export.service: A process of this unit has … │
│ ● Service crashed (10 events) │
│ 2026-10-19 19:41:55 → 19:42:52 (57s) │
│ process: tail ×1 · unit: orders-worker.service ×6, report-export.serv… │
│ line 1530: systemd: orders-worker.service: Main process exited, code=e… │
│ line 1571: systemd: Failed to start orders worker. │
│ ● Configuration rejected (1 event) │
│ at 2026-10-19 19:42:52 │
│ line 1607: nginx: configuration file /etc/nginx/nginx.conf test failed │
│ ● Authentication failure cluster (60 events) │
│ 2026-10-19 19:41:58 → 19:42:11 (13s) │
│ ● Error burst detected (77 events) │
│ 2026-10-19 19:38:06 → 19:42:52 (4m46s) │
│ │
│ Confidence: 90% │
│ │
│ Remediation: Check /proc/meminfo and `dmesg | grep -i oom`. Consider adding │
│ swap or tuning vm.overcommit_memory=2 in /etc/sysctl.conf. │
╰──────────────────────────────────────────────────────────────────────────────╯
Checked 1,611 events as syslog │ 100% of 1,620 lines parsed │ 2026-10-19
19:37:49 → 19:43:02 (5m13s) │ 78 error · 1 warning
Analyzed 1,611 events in 0.5s │ 5 incident(s) │ logcrux v0.10.0
$ echo $?
4
No incident, no news: a clean run prints a brief CLEAN box and exits 0. See usage for exit codes and how it works for the pipeline behind this.
See the full list of formats. Anything unrecognized still gets parsed by a generic fallback that never silently drops a line.