Skip to main content

logsleuth

Local AI root-cause analysis for production logs. Nothing leaves your machine.

Feed it an incident's worth of logs — gigabytes really are fine: 183MB scans in 3 seconds across your cores using 21MB of RAM — and get back a structured root-cause report: symptom, timeline, hypothesis with cited evidence, ruled-out red herrings, next steps. All inference runs locally via Ollama, so you can use it on logs you'd never paste into a cloud AI: they're full of PII, tokens and internal hostnames, and your security team knows it.

$ logsleuth incident.log

## Root cause hypothesis
PostgreSQL connection pool size reduction (from 50 to 10) during deployment.
Confidence: High.
- Deployment log explicitly sets PG_POOL_MAX=10 (line 1316)
- "pg pool timeout" errors start immediately after the deployment
- Latency grew from 56.9ms to 217.9ms (x3.8), idle connections dropped to 0

## Ruled out
- "healthz" noise present before the incident — baseline, not cause
...

Why

  • Your logs never leave the machine. No API keys, no cloud, no data processing agreements, no argument with the CISO. Works air-gapped.
  • Reads the formats you actually have. JSON lines, logfmt, plain text — sniffed automatically. Timestamps in ISO, syslog, Apache and epoch form all parse. Java/Python stack traces fold into the event they belong to instead of polluting the analysis as fifty separate lines. Structured fields (level, pod, latency_ms) are used directly, and dimensions are picked by cardinality — no hardcoded field list.
  • Built for real log sizes. Streaming, parallel, bounded memory: the file is read once in byte-range chunks across CPU cores and only aggregates are kept, so a 2GB log costs the same RAM as a 2MB one. (Measured: 2M lines in 3.1s / 21MB on an M1 Pro; a naive in-memory pass took 29s and 788MB.)
  • It never shows you a traceback. Binary files, broken archives, a directory, UTF-16, a 20MB line with no newlines, 60k distinct lines, no timestamps at all — each gets a plain sentence explaining the problem. When something unexpected does break, the message tells you to run logsleuth --health <file>, which prints parse diagnostics — counts, formats, line shapes — with no log content, so you can attach it to an issue without leaking anything.
  • Verified on 132 real public corpora. Every LogHub dataset, full size — including HDFS (1.6GB, 11.2M lines, scanned in 37s) and BGL (4.7M lines) — plus Spark, OpenStack, Android, Apache, syslog and Kubernetes container logs. Zero failures, peak memory 28MB regardless of file size, timestamps parsed on 87% of corpora. bench/corpus_sweep.py reproduces the whole table.
  • Fits how logs actually live. Kubernetes CRI lines (<ts> stdout F …) and Docker JSON envelopes are unwrapped to the application line underneath; gzipped rotated archives open directly; several files merge chronologically.
  • Analyze a moment, not a file. --last 30m / --since / --until binary-search the window by byte offset, so a 30-minute slice of a huge log is read in milliseconds — measured: 400k lines, 7.5s for the whole file vs 0.24s for the last 2 hours, skipping 99% of it. Unsorted files fall back to filtering, with a notice.
  • Templates learned, not guessed. Line grouping uses a Drain-style parse tree (ours, pure stdlib): variable parts are found positionally — block ids, hostnames, usernames, paths — instead of matching a list of "looks like data" regexes. Measured on Loghub-2.0 — 13 real systems, 39 million lines, human-annotated: 79.3% grouping accuracy at 116,000 lines/second. bench/loghub2_ga.py reproduces it.
  • No keyword lists to maintain. State changes are found structurally: a deploy, an eviction or a leader switch is a near-unique line in a file where normal operation repeats thousands of times. Rare + shortly-before-the-first-error = prime suspect, in any stack, any vendor, any phrasing.
  • It reads all of it. A deterministic preprocessor crunches the full file — deduplicates error patterns, computes numeric trends (heap, latency, disk, queue depths), finds deploys/migrations/flag flips, detects error concentration by node/pod/build — and hands the model a dense evidence pack. No more guessing which 10KB of a 2GB log to paste into a chatbot.
  • It distrusts loud noise. Patterns present since the start of the file are flagged as baseline; the report explicitly lists red herrings it didn't blame.
  • Honest by design. The model is instructed to cite only real lines and to say "insufficient evidence" rather than invent a story.

Benchmarks

Three benchmark sets, all reproducible from this repo.

RCAEval — third-party academic benchmark (Pham et al.), 30 real Sock Shop failure cases with an annotated root-cause service, ~85k log lines each: ~50% correct service localization, scored strictly (the right service must be named in the first sentence of the root cause, not merely mentioned somewhere).

That number reads low until you see what it is beating. Running the same 30 cases through simple rules, with no model involved at all (bench/rcaeval_ceiling.py):

method correct
service with the most error lines 0/30
most error lines in the 10 min after fault injection 0/30
highest error over-representation vs. baseline traffic 0/30
pick a service at random 2/30
logsleuth ~15/30

Every count-based heuristic scores zero because in a microservice cascade the loudest service is the caller that timed out, not the one that broke — the median share of error lines coming from the actually-faulty service is 10%. The upper bound is 30/30: the faulty service does emit error lines in every case, so the task is solvable from logs, just not by counting.

Note logsleuth reads only logs, while RCAEval is built for methods that also consume metrics and traces. bench/rcaeval_run.py reproduces the run.

Loghub-2.0 — 13 real systems, 39 million annotated lines. This is the benchmark the ISSTA'24 study "How Far Are We?" built after showing that the older 2,000-line LogHub flatters every parser; on full-size data accuracy drops sharply and most parsers cannot finish at all — only 6 of 15 completed within 12 hours.

grouping accuracy 79.3% (74.9% before enum-aware templates)
throughput 116,000 lines/second, 39M lines in 5.6 minutes

bench/loghub2_ga.py reproduces it. The older 2k benchmark is kept as bench/loghub_ga.py for continuity (79.1%), but the number above is the one that predicts behaviour on a real file.

Blind synthetic sets — scenarios written after the code was frozen, so nothing is tuned to the answers. Set 1 (10 common failures): 10/10. Set 2 (9 harder, 2-3 causal hops): 6/9 — the misses name the right component but stop one hop short of the trigger.

Measured with qwen3:8b on a MacBook M1 Pro (16GB). On qwen3:4b — what we auto-select on machines under 10GB of RAM — set 1 scores 9/10, and the tenth is an honest "insufficient evidence" rather than a wrong answer. Bigger models do better; that's a one-flag change.

Install

pipx install logsleuth        # or: pip install logsleuth
logsleuth demo

That is the whole install. On first run logsleuth asks once before setting up local inference, then does it for you:

logsleuth runs the model on this machine, so your logs never leave it.
  It needs a local runtime (0.1GB) and the model qwen3:8b (5.2GB).
  Both go in ~/.logsleuth and can be deleted later.
  Set this up now? [Y/n]

Nothing is installed system-wide and nothing needs sudo; rm -rf ~/.logsleuth undoes it. If you already run Ollama, logsleuth uses it as-is — including whatever model you already have pulled, so there is nothing to download at all. Add --yes for unattended setup.

The model is picked to fit your machine: qwen3:4b under 10GB of RAM, qwen3:8b under 24GB, qwen3:14b above that. Override any of it with --model or LOGSLEUTH_MODEL.

No Python dependencies — pure stdlib.

Output

The report leads with the answer — root cause first, with quoted evidence — so you can stop reading as soon as you have what you need. In a terminal you also get a visual header: an incident map (error density across the file, with deploy/config markers), trend sparklines (latency, memory, queue depths), and color-coded sections with confidence badges. Piped or with --plain it degrades to clean markdown; --json for machines.

 INCIDENT MAP (error density across the file)
   ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▃▅▄▅▅▄▄▅▆▇▅▆▆▆▆▆▆▆▆▆▆▆▇▆▇▆▆███
                 ▼                               ▼ = deploy/config/migration

 TRENDS
   ▼ idle 28→0                    ██████▄▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
   ▲ latency 57→218ms             ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁██▇███▁▁▁▁▁

Usage

logsleuth demo                        # try it right now on a bundled sample incident
logsleuth app.log --last 30m          # only the last 30 minutes (seeks, does not read the rest)
logsleuth app.log --since 03:00 --until 04:00
kubectl logs deploy/api --since=1h | logsleuth -   # k8s CRI format is unwrapped automatically
logsleuth app.log.2.gz                # rotated archives work as-is
logsleuth app.log --health            # parse diagnostics only, safe to share
logsleuth incident.log                # analyze a file
logsleuth api.log db.log gateway.log  # merge services chronologically; source becomes a dimension
kubectl logs deploy/api | logsleuth -  # or pipe anything into it
logsleuth incident.log --json         # machine-readable output
logsleuth incident.log --dry-run      # show the evidence pack, prove nothing else is sent
logsleuth incident.log --model qwen3:14b  # bigger machine, smarter analysis

--dry-run prints exactly what would be passed to the local model — audit it, then grep your favorite secret to confirm it's not there.

Choosing a model

Picked automatically from your RAM, so this table is only for overriding it.

Your machine Model Notes
under 10GB RAM qwen3:4b auto-selected; fast, decent
10–24GB RAM qwen3:8b auto-selected; benchmark numbers above
24GB+ RAM qwen3:14b / qwen3:32b auto-selected; noticeably deeper analysis
On-prem server anything Ollama serves point LOGSLEUTH_OLLAMA_URL at it

How it works

raw logs ──► deterministic preprocessor ──► evidence pack ──► local LLM ──► report
             (dedup, trends, changes,        (~25KB max)       (Ollama)
              dimensions, context windows)

The preprocessor is the point: local 8B models are good analysts but bad readers of 2GB files. logsleuth does the reading with boring, auditable code and saves the model for the part it's actually good at — causal reasoning over dense evidence.

Roadmap

  • Deeper causal-chain analysis (the 2/10 benchmark misses)
  • logsleuth-8b: a fine-tuned model distilled from thousands of incident analyses
  • Watch mode / webhook: auto-analyze on alert
  • Team features: shared incident history, PagerDuty/Opsgenie integration

License

MIT

Metadata

Release files for logsleuth 0.11.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for logsleuth 0.11.0
File Size Uploaded
logsleuth-0.11.0.tar.gz 78.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for logsleuth 0.11.0
File Interpreter ABI Platform
logsleuth-0.11.0-py3-none-any.whl Python 3 none any Details

Total release size: 158.2 kB

Release files / logsleuth-0.11.0.tar.gz

Download URL logsleuth-0.11.0.tar.gz
Size 78.7 kB
Tags Source
SHA-256 checksum
How to use checksums
1f5de55232e52433e9474c64095b0fc7659a3864cf3b03668f509149e79f33fc
BLAKE2b-256 checksum
How to use checksums
15a2773b8c062c12dbb0aa7f6f53454ca4e4d28a3d129d55c0df4e0d270ab492
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.6

Release files / logsleuth-0.11.0-py3-none-any.whl

Download URL logsleuth-0.11.0-py3-none-any.whl
Size 79.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1934e78e3d1221f8401b9973db51b0a482e94c15dfed0d0791a22b9a0125c382
BLAKE2b-256 checksum
How to use checksums
f94eba25b4998e818a1456f6e7ffe084595d31b9b47d8b8128ee37e6cb2231e9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.6

Release history Release notifications | RSS feed

This release

0.11.0 This release

2 release files

0.9.0

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page