mdbkit 0.2.0__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mdbkit-0.2.0/mdbkit.egg-info → mdbkit-0.3.0}/PKG-INFO +195 -10
- mdbkit-0.2.0/PKG-INFO → mdbkit-0.3.0/README.md +738 -577
- {mdbkit-0.2.0 → mdbkit-0.3.0}/mdbkit/__init__.py +1 -1
- {mdbkit-0.2.0 → mdbkit-0.3.0}/mdbkit/analysis.py +117 -7
- mdbkit-0.3.0/mdbkit/build/lib/mdbkit/__init__.py +3 -0
- mdbkit-0.3.0/mdbkit/build/lib/mdbkit/advisor.py +319 -0
- mdbkit-0.3.0/mdbkit/build/lib/mdbkit/analysis.py +567 -0
- {mdbkit-0.2.0 → mdbkit-0.3.0/mdbkit/build/lib}/mdbkit/cli.py +214 -5
- mdbkit-0.3.0/mdbkit/build/lib/mdbkit/demo.py +401 -0
- {mdbkit-0.2.0 → mdbkit-0.3.0/mdbkit/build/lib}/mdbkit/ftdc.py +263 -75
- mdbkit-0.3.0/mdbkit/build/lib/mdbkit/lab.py +385 -0
- {mdbkit-0.2.0 → mdbkit-0.3.0/mdbkit/build/lib}/mdbkit/parser.py +7 -0
- {mdbkit-0.2.0 → mdbkit-0.3.0/mdbkit/build/lib}/mdbkit/rebuild.py +23 -9
- {mdbkit-0.2.0 → mdbkit-0.3.0/mdbkit/build/lib}/mdbkit/render.py +40 -3
- {mdbkit-0.2.0 → mdbkit-0.3.0/mdbkit/build/lib}/mdbkit/triage.py +126 -6
- mdbkit-0.3.0/mdbkit/cli.py +655 -0
- mdbkit-0.3.0/mdbkit/demo.py +401 -0
- mdbkit-0.3.0/mdbkit/explain.py +281 -0
- mdbkit-0.3.0/mdbkit/filtering.py +93 -0
- mdbkit-0.3.0/mdbkit/ftdc.py +654 -0
- mdbkit-0.3.0/mdbkit/lab.py +385 -0
- mdbkit-0.3.0/mdbkit/mdbkit/__init__.py +3 -0
- mdbkit-0.3.0/mdbkit/mdbkit/advisor.py +319 -0
- mdbkit-0.3.0/mdbkit/mdbkit/analysis.py +567 -0
- mdbkit-0.3.0/mdbkit/mdbkit/cli.py +655 -0
- mdbkit-0.3.0/mdbkit/mdbkit/demo.py +401 -0
- mdbkit-0.3.0/mdbkit/mdbkit/explain.py +281 -0
- mdbkit-0.3.0/mdbkit/mdbkit/filtering.py +93 -0
- mdbkit-0.3.0/mdbkit/mdbkit/ftdc.py +654 -0
- mdbkit-0.3.0/mdbkit/mdbkit/lab.py +385 -0
- mdbkit-0.3.0/mdbkit/mdbkit/parser.py +156 -0
- mdbkit-0.3.0/mdbkit/mdbkit/rebuild.py +185 -0
- mdbkit-0.3.0/mdbkit/mdbkit/render.py +336 -0
- mdbkit-0.3.0/mdbkit/mdbkit/report.py +187 -0
- mdbkit-0.3.0/mdbkit/mdbkit/scripts.py +69 -0
- mdbkit-0.3.0/mdbkit/mdbkit/triage.py +810 -0
- mdbkit-0.3.0/mdbkit/parser.py +156 -0
- mdbkit-0.3.0/mdbkit/rebuild.py +185 -0
- mdbkit-0.3.0/mdbkit/render.py +336 -0
- mdbkit-0.3.0/mdbkit/report.py +187 -0
- mdbkit-0.3.0/mdbkit/scripts.py +69 -0
- mdbkit-0.3.0/mdbkit/tests/test_demo_lab.py +315 -0
- {mdbkit-0.2.0 → mdbkit-0.3.0/mdbkit}/tests/test_ftdc.py +54 -0
- {mdbkit-0.2.0 → mdbkit-0.3.0/mdbkit}/tests/test_rebuild_report.py +35 -0
- mdbkit-0.3.0/mdbkit/triage.py +810 -0
- mdbkit-0.2.0/README.md → mdbkit-0.3.0/mdbkit.egg-info/PKG-INFO +762 -553
- mdbkit-0.3.0/mdbkit.egg-info/SOURCES.txt +66 -0
- {mdbkit-0.2.0 → mdbkit-0.3.0}/pyproject.toml +1 -1
- mdbkit-0.3.0/tests/test_demo_lab.py +315 -0
- mdbkit-0.3.0/tests/test_explain.py +119 -0
- mdbkit-0.3.0/tests/test_ftdc.py +320 -0
- mdbkit-0.3.0/tests/test_mdbkit.py +331 -0
- mdbkit-0.3.0/tests/test_rebuild_report.py +160 -0
- mdbkit-0.3.0/tests/test_triage.py +173 -0
- mdbkit-0.2.0/mdbkit.egg-info/SOURCES.txt +0 -27
- {mdbkit-0.2.0 → mdbkit-0.3.0}/LICENSE +0 -0
- {mdbkit-0.2.0 → mdbkit-0.3.0}/mdbkit/advisor.py +0 -0
- {mdbkit-0.2.0 → mdbkit-0.3.0/mdbkit/build/lib}/mdbkit/explain.py +0 -0
- {mdbkit-0.2.0 → mdbkit-0.3.0/mdbkit/build/lib}/mdbkit/filtering.py +0 -0
- {mdbkit-0.2.0 → mdbkit-0.3.0/mdbkit/build/lib}/mdbkit/report.py +0 -0
- {mdbkit-0.2.0 → mdbkit-0.3.0/mdbkit/build/lib}/mdbkit/scripts.py +0 -0
- {mdbkit-0.2.0 → mdbkit-0.3.0/mdbkit}/tests/test_explain.py +0 -0
- {mdbkit-0.2.0 → mdbkit-0.3.0/mdbkit}/tests/test_mdbkit.py +0 -0
- {mdbkit-0.2.0 → mdbkit-0.3.0/mdbkit}/tests/test_triage.py +0 -0
- {mdbkit-0.2.0 → mdbkit-0.3.0}/mdbkit.egg-info/dependency_links.txt +0 -0
- {mdbkit-0.2.0 → mdbkit-0.3.0}/mdbkit.egg-info/entry_points.txt +0 -0
- {mdbkit-0.2.0 → mdbkit-0.3.0}/mdbkit.egg-info/requires.txt +0 -0
- {mdbkit-0.2.0 → mdbkit-0.3.0}/mdbkit.egg-info/top_level.txt +0 -0
- {mdbkit-0.2.0 → mdbkit-0.3.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mdbkit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Offline toolkit for MongoDB 4.4+ structured logs: log analysis, slow-query shapes, connection churn, and deterministic index advice. A spiritual successor to mtools' log tools.
|
|
5
5
|
Author: Saqib Ameen Subhan
|
|
6
6
|
License: MIT
|
|
@@ -36,6 +36,25 @@ MongoDB 4.4 switched to structured JSON logging, and the beloved mtools log comm
|
|
|
36
36
|
|
|
37
37
|
mdbkit fills that gap: a single, dependency-free CLI that turns structured logs into answers.
|
|
38
38
|
|
|
39
|
+
## Try it in 30 seconds
|
|
40
|
+
|
|
41
|
+
No MongoDB required — `mdbkit demo` writes a realistic log with a real
|
|
42
|
+
incident in it:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pip install mdbkit
|
|
46
|
+
mdbkit demo --with-extras -o demo.log
|
|
47
|
+
|
|
48
|
+
mdbkit loginfo demo.log
|
|
49
|
+
mdbkit queries demo.log
|
|
50
|
+
mdbkit triage demo.log --window 0 --no-sysprobe
|
|
51
|
+
mdbkit advise demo.log --indexes indexes.json --schema schema.json
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
You will see a connection storm, a replica set election, an index build, and
|
|
55
|
+
a collection scan burning 47 million document reads — then the candidate
|
|
56
|
+
index that fixes it.
|
|
57
|
+
|
|
39
58
|
## Install
|
|
40
59
|
|
|
41
60
|
**Recommended on any Linux/Mac/Windows:**
|
|
@@ -199,6 +218,8 @@ mdbkit triage mongod.log --no-sysprobe # analyzing a log copied off-host
|
|
|
199
218
|
**Defaults to the last 60 minutes of log time**, because triage is for
|
|
200
219
|
incidents happening now or just finished. In one command:
|
|
201
220
|
|
|
221
|
+
- **cluster health** — this node's replica set role, every peer's last known
|
|
222
|
+
state, heartbeat failures, and whether the node is still serving
|
|
202
223
|
- restarts, error clusters, election/stepdown events
|
|
203
224
|
- connection storms — with the peak minute and the top source IPs
|
|
204
225
|
- slow-query volume and the peak minute, so you know *when* it hurt
|
|
@@ -211,8 +232,15 @@ incidents happening now or just finished. In one command:
|
|
|
211
232
|
When run on the database host, mdbkit finds `dbPath` automatically — from the
|
|
212
233
|
log's startup line, or the running `mongod` process, or `/etc/mongod.conf`,
|
|
213
234
|
or common defaults — so the disk check works even when the current log has no
|
|
214
|
-
startup event.
|
|
215
|
-
|
|
235
|
+
startup event. **`diagnostic.data` lives inside the dbPath, so it is picked up
|
|
236
|
+
automatically too**: you only need `--ftdc` to point somewhere else, such as a
|
|
237
|
+
directory copied off another host. All probing is stdlib-only (`/proc`,
|
|
238
|
+
`statvfs`); no shell-outs, nothing leaves the machine.
|
|
239
|
+
|
|
240
|
+
Cluster health is derived entirely from the log — no connection to the
|
|
241
|
+
database. It reports what the node last said about itself and its peers, which
|
|
242
|
+
is the honest limit of an offline tool, and enough to answer "is this node
|
|
243
|
+
serving, and what does it think of the others?"
|
|
216
244
|
|
|
217
245
|
Read-only: it never connects to the database, and every finding ends with a
|
|
218
246
|
next step for a human to review. Detectors marked beta are pattern-matched and
|
|
@@ -295,7 +323,7 @@ query with different parameters is counted once.
|
|
|
295
323
|
| `--limit N` | all | Show only the top N shapes |
|
|
296
324
|
| `--min-ms N` | 0 | Ignore operations faster than N milliseconds |
|
|
297
325
|
| `--include-system` | off | Include internal `admin`/`config`/`local` namespaces (hidden by default — they are server housekeeping, not your workload) |
|
|
298
|
-
| `--report FILE` | | Write a shareable `.md` or `.html` report instead |
|
|
326
|
+
| `--report FILE` | | Write a shareable `.md` or `.html` report instead (see [Shareable reports](#shareable-reports----report-file)) |
|
|
299
327
|
| `--json` | | Machine-readable output |
|
|
300
328
|
|
|
301
329
|
**Reading the columns:**
|
|
@@ -319,13 +347,38 @@ mdbkit queries mongod.log --min-ms 500 --json
|
|
|
319
347
|
|
|
320
348
|
### `mdbkit connections <log>`
|
|
321
349
|
|
|
322
|
-
Connection churn
|
|
323
|
-
the client applications and
|
|
350
|
+
Connection churn and **who authenticated**: totals, peak concurrent count,
|
|
351
|
+
per-source-IP breakdown with first/last seen, the client applications and
|
|
352
|
+
drivers, and a per-user table.
|
|
324
353
|
|
|
325
354
|
| Option | Description |
|
|
326
355
|
|---|---|
|
|
327
356
|
| `--json` | Machine-readable output |
|
|
328
357
|
|
|
358
|
+
```bash
|
|
359
|
+
mdbkit connections mongod.log
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
```
|
|
363
|
+
source ip accepted ended first seen last seen appName
|
|
364
|
+
---------- -------- ----- ------------------- ------------------- ------------
|
|
365
|
+
10.20.9.77 220 0 2026-07-01 08:49:30 2026-07-01 08:49:30 checkout-api
|
|
366
|
+
10.20.4.11 4 1 2026-07-01 08:00:15 2026-07-01 09:29:30 OrderService
|
|
367
|
+
|
|
368
|
+
authenticated users
|
|
369
|
+
user auth db ok failed last authenticated from
|
|
370
|
+
------------ ------- --- ------ ------------------- -----------
|
|
371
|
+
svc_checkout admin 221 0 2026-07-01 08:49:30 10.20.9.77
|
|
372
|
+
etl_batch admin 0 5 2026-07-01 08:51:54 10.20.11.40
|
|
373
|
+
|
|
374
|
+
etl_batch: 5 failed authentication(s) — last error: AuthenticationFailed
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
This answers the question that starts most access incidents: *did that
|
|
378
|
+
account connect, from where, and when last?* If the log shows no
|
|
379
|
+
authentication events at all, mdbkit says so — either auth is disabled, or
|
|
380
|
+
the window contains no new logins because clients are reusing connections.
|
|
381
|
+
|
|
329
382
|
---
|
|
330
383
|
|
|
331
384
|
### `mdbkit filter <log>`
|
|
@@ -500,11 +553,21 @@ not encrypted; mdbkit decodes it offline.
|
|
|
500
553
|
|
|
501
554
|
| Option | Default | Description |
|
|
502
555
|
|---|---|---|
|
|
556
|
+
| `--last DURATION` | `4h` | Analyze only the most recent window — `90m`, `4h`, `2d` |
|
|
557
|
+
| `--all` | off | Analyze the entire history (see the performance note below) |
|
|
503
558
|
| `--metric LABEL` | all | Restrict to one metric (repeatable), e.g. `--metric conns.current` |
|
|
504
559
|
| `--step SECONDS` | 60 | Timeline bucket size |
|
|
505
|
-
| `--from` / `--to` | |
|
|
560
|
+
| `--from` / `--to` | | Explicit time bounds (same formats as `filter`) |
|
|
506
561
|
| `--json` | | Machine-readable output |
|
|
507
562
|
|
|
563
|
+
**Performance note.** `diagnostic.data` can hold weeks of per-second samples —
|
|
564
|
+
a few hundred megabytes covering thousands of chunks and several thousand
|
|
565
|
+
metrics each. Decoding all of it is CPU-bound and takes minutes, so these
|
|
566
|
+
commands **default to the last 4 hours** and skip older chunks before
|
|
567
|
+
decompressing them. On a 250 MB directory that is the difference between about
|
|
568
|
+
a second and about a minute. Use `--last`/`--from`/`--to` to move the window,
|
|
569
|
+
and `--all` when you really do want the whole history.
|
|
570
|
+
|
|
508
571
|
```bash
|
|
509
572
|
mdbkit ftdc summary /var/lib/mongodb/diagnostic.data
|
|
510
573
|
mdbkit ftdc timeline diagnostic.data --metric conns.current --step 300
|
|
@@ -521,6 +584,126 @@ contains metrics only, never document contents.
|
|
|
521
584
|
|
|
522
585
|
---
|
|
523
586
|
|
|
587
|
+
### Shareable reports — `--report FILE`
|
|
588
|
+
|
|
589
|
+
`triage` and `queries` can write a self-contained report instead of printing to
|
|
590
|
+
the terminal — for a ticket, a handover, or a post-incident review.
|
|
591
|
+
|
|
592
|
+
```bash
|
|
593
|
+
mdbkit triage mongod.log --report incident.html # styled, self-contained
|
|
594
|
+
mdbkit triage mongod.log --report incident.md # for tickets and PRs
|
|
595
|
+
mdbkit queries mongod.log --limit 20 --report slow-queries.md
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
The format follows the file extension: `.html` or `.md`.
|
|
599
|
+
|
|
600
|
+
Markdown output looks like this:
|
|
601
|
+
|
|
602
|
+
```markdown
|
|
603
|
+
# MongoDB incident triage
|
|
604
|
+
|
|
605
|
+
*window 2026-07-01 08:10 -> 09:10 · generated 2026-07-01 09:12*
|
|
606
|
+
|
|
607
|
+
## Findings
|
|
608
|
+
|
|
609
|
+
- **[CRIT] Replica set instability** — 3 election/stepdown event(s) at 08:41:02, 08:58:14
|
|
610
|
+
- Starting an election, since we've seen no PRIMARY in election timeout period
|
|
611
|
+
- *next:* `Correlate with connection storms and slow checkpoints below`
|
|
612
|
+
- **[WARN] Connection storm** — 2 minute(s) at >= 60 new connections/min; peak 480 at 08:41
|
|
613
|
+
- 10.2.1.7: 312 in the peak minute
|
|
614
|
+
- *next:* `mdbkit connections <log>`
|
|
615
|
+
- **[OK] Errors** — No error/fatal severity lines in window.
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
The HTML version carries the same content with a dark, print-friendly
|
|
619
|
+
stylesheet. It is **fully self-contained**: inline CSS, no JavaScript, no
|
|
620
|
+
external assets or CDN references, so it opens on an air-gapped machine and
|
|
621
|
+
sends nothing anywhere.
|
|
622
|
+
|
|
623
|
+
Reports contain the same information as the terminal output — query **shapes**
|
|
624
|
+
and metrics, never literal values from your documents.
|
|
625
|
+
|
|
626
|
+
---
|
|
627
|
+
|
|
628
|
+
### `mdbkit demo`
|
|
629
|
+
|
|
630
|
+
Generates a realistic MongoDB structured log so you can evaluate mdbkit — or
|
|
631
|
+
run a live demo — without a cluster. Output is deterministic for a given
|
|
632
|
+
seed, so a demo behaves identically every time, including on a projector.
|
|
633
|
+
|
|
634
|
+
| Option | Default | Description |
|
|
635
|
+
|---|---|---|
|
|
636
|
+
| `--scenario` | `mixed` | `healthy`, `incident`, or `mixed` |
|
|
637
|
+
| `--minutes N` | 90 | How much log time to generate |
|
|
638
|
+
| `--seed N` | 7 | Same seed produces byte-identical output |
|
|
639
|
+
| `-o, --out FILE` | stdout | Write to a file |
|
|
640
|
+
| `--with-extras` | off | Also write `indexes.json`, `schema.json` and `explain.json` beside the log |
|
|
641
|
+
|
|
642
|
+
```bash
|
|
643
|
+
mdbkit demo -o demo.log # 90 minutes, mixed
|
|
644
|
+
mdbkit demo --scenario incident --minutes 30 -o incident.log
|
|
645
|
+
mdbkit demo --scenario healthy -o quiet.log # nothing wrong: the control case
|
|
646
|
+
mdbkit demo | mdbkit queries - # straight down a pipe
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
The `incident` scenario contains an index build, a connection storm from a
|
|
650
|
+
single client, a replica set election, plan-executor errors, a slow
|
|
651
|
+
WiredTiger checkpoint, and a burst of unindexed queries afterwards — the
|
|
652
|
+
shape of a real bad afternoon.
|
|
653
|
+
|
|
654
|
+
---
|
|
655
|
+
|
|
656
|
+
### `mdbkit lab`
|
|
657
|
+
|
|
658
|
+
Starts a **disposable local MongoDB** for testing, reproducing a slow query,
|
|
659
|
+
or rehearsing a demo. This is the only command that starts external
|
|
660
|
+
processes; see [SECURITY.md](SECURITY.md) for exactly how it is bounded.
|
|
661
|
+
|
|
662
|
+
Requires `mongod` on your `PATH` (and `mongosh` to initiate the replica set
|
|
663
|
+
and seed data). Linux and macOS.
|
|
664
|
+
|
|
665
|
+
| Action | What it does |
|
|
666
|
+
|---|---|
|
|
667
|
+
| `start` | Create and start a replica set, print the connection string and log paths |
|
|
668
|
+
| `seed` | Insert sample data and run a workload with deliberately interesting queries |
|
|
669
|
+
| `status` | Show ports, pids and whether each node is running |
|
|
670
|
+
| `logs` | Print the log file paths, ready to pipe into other commands |
|
|
671
|
+
| `stop` | Stop the nodes, keep the data |
|
|
672
|
+
| `destroy` | Stop and delete the lab (requires `--yes`) |
|
|
673
|
+
|
|
674
|
+
| Option | Default | Description |
|
|
675
|
+
|---|---|---|
|
|
676
|
+
| `--dir PATH` | `~/.mdbkit-lab` | Where the lab lives |
|
|
677
|
+
| `--nodes N` | 3 | Replica set size |
|
|
678
|
+
| `--port N` | 28110 | Base port — deliberately far from 27017 |
|
|
679
|
+
| `--slowms N` | 0 | Log every operation, which is what makes the log worth reading |
|
|
680
|
+
| `--standalone` | off | Single node, no replica set |
|
|
681
|
+
| `--docs N` | 50000 | Documents inserted by `seed` |
|
|
682
|
+
| `--yes` | | Confirm `destroy` |
|
|
683
|
+
|
|
684
|
+
**The full loop:**
|
|
685
|
+
|
|
686
|
+
```bash
|
|
687
|
+
mdbkit lab start # 3-node replica set on 28110-28112
|
|
688
|
+
mdbkit lab seed # sample data + a mixed workload
|
|
689
|
+
|
|
690
|
+
mdbkit queries $(mdbkit lab logs | head -1)
|
|
691
|
+
mdbkit advise $(mdbkit lab logs | head -1)
|
|
692
|
+
|
|
693
|
+
mdbkit lab destroy --yes # remove everything
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
`seed` runs indexed point lookups alongside deliberately unindexed queries —
|
|
697
|
+
an equality-plus-range-plus-sort with no supporting index, an aggregation
|
|
698
|
+
that scans the collection, and updates whose predicate has no index — so the
|
|
699
|
+
log immediately contains something worth analysing.
|
|
700
|
+
|
|
701
|
+
**Safety.** The lab binds to `127.0.0.1` only, refuses to use or delete any
|
|
702
|
+
directory it did not create, and never touches a MongoDB it did not start.
|
|
703
|
+
It is a laptop and scratch-VM tool, not a deployment tool.
|
|
704
|
+
|
|
705
|
+
---
|
|
706
|
+
|
|
524
707
|
### `mdbkit export-script {schema|indexes}`
|
|
525
708
|
|
|
526
709
|
Prints a small `mongosh` script to stdout. **mdbkit never connects to your
|
|
@@ -540,12 +723,14 @@ mdbkit export-script schema > export_schema.js
|
|
|
540
723
|
Terminal output is and will remain first-class — this tool is built for the
|
|
541
724
|
Linux box the database actually runs on.
|
|
542
725
|
|
|
543
|
-
**Shipped in v0.
|
|
544
|
-
|
|
726
|
+
**Shipped in v0.3:** `demo` log generation and `lab` disposable clusters, on
|
|
727
|
+
top of v0.2's FTDC decoding, incident triage, query reconstruction and
|
|
728
|
+
shareable reports.
|
|
545
729
|
|
|
546
730
|
Next up:
|
|
731
|
+
* `mdbkit compare before.log after.log` — did the index actually help?
|
|
732
|
+
* Multiple log files and globs in one command, for rotated logs.
|
|
547
733
|
* Per-shape drill-down (`mdbkit queries --shape N` with full detail).
|
|
548
|
-
* `serverStatus` snapshot digest for triage (two snapshots for true rates).
|
|
549
734
|
* Graduating the remaining beta detectors (checkpoints, eviction, flow
|
|
550
735
|
control) once validated against real incident logs — see
|
|
551
736
|
`docs/TESTING-PLAYBOOK.md`. Real logs very welcome.
|