mdbkit 0.2.1__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.
Files changed (69) hide show
  1. {mdbkit-0.2.1/mdbkit.egg-info → mdbkit-0.3.0}/PKG-INFO +142 -8
  2. mdbkit-0.2.1/PKG-INFO → mdbkit-0.3.0/README.md +738 -628
  3. {mdbkit-0.2.1 → mdbkit-0.3.0}/mdbkit/__init__.py +1 -1
  4. {mdbkit-0.2.1 → mdbkit-0.3.0}/mdbkit/analysis.py +117 -7
  5. mdbkit-0.3.0/mdbkit/build/lib/mdbkit/__init__.py +3 -0
  6. mdbkit-0.3.0/mdbkit/build/lib/mdbkit/advisor.py +319 -0
  7. mdbkit-0.3.0/mdbkit/build/lib/mdbkit/analysis.py +567 -0
  8. {mdbkit-0.2.1 → mdbkit-0.3.0/mdbkit/build/lib}/mdbkit/cli.py +141 -0
  9. mdbkit-0.3.0/mdbkit/build/lib/mdbkit/demo.py +401 -0
  10. mdbkit-0.3.0/mdbkit/build/lib/mdbkit/lab.py +385 -0
  11. {mdbkit-0.2.1 → mdbkit-0.3.0/mdbkit/build/lib}/mdbkit/parser.py +7 -0
  12. {mdbkit-0.2.1 → mdbkit-0.3.0/mdbkit/build/lib}/mdbkit/render.py +40 -3
  13. {mdbkit-0.2.1 → mdbkit-0.3.0/mdbkit/build/lib}/mdbkit/triage.py +116 -2
  14. mdbkit-0.3.0/mdbkit/cli.py +655 -0
  15. mdbkit-0.3.0/mdbkit/demo.py +401 -0
  16. mdbkit-0.3.0/mdbkit/explain.py +281 -0
  17. mdbkit-0.3.0/mdbkit/filtering.py +93 -0
  18. mdbkit-0.3.0/mdbkit/ftdc.py +654 -0
  19. mdbkit-0.3.0/mdbkit/lab.py +385 -0
  20. mdbkit-0.3.0/mdbkit/mdbkit/__init__.py +3 -0
  21. mdbkit-0.3.0/mdbkit/mdbkit/advisor.py +319 -0
  22. mdbkit-0.3.0/mdbkit/mdbkit/analysis.py +567 -0
  23. mdbkit-0.3.0/mdbkit/mdbkit/cli.py +655 -0
  24. mdbkit-0.3.0/mdbkit/mdbkit/demo.py +401 -0
  25. mdbkit-0.3.0/mdbkit/mdbkit/explain.py +281 -0
  26. mdbkit-0.3.0/mdbkit/mdbkit/filtering.py +93 -0
  27. mdbkit-0.3.0/mdbkit/mdbkit/ftdc.py +654 -0
  28. mdbkit-0.3.0/mdbkit/mdbkit/lab.py +385 -0
  29. mdbkit-0.3.0/mdbkit/mdbkit/parser.py +156 -0
  30. mdbkit-0.3.0/mdbkit/mdbkit/rebuild.py +185 -0
  31. mdbkit-0.3.0/mdbkit/mdbkit/render.py +336 -0
  32. mdbkit-0.3.0/mdbkit/mdbkit/report.py +187 -0
  33. mdbkit-0.3.0/mdbkit/mdbkit/scripts.py +69 -0
  34. mdbkit-0.3.0/mdbkit/mdbkit/triage.py +810 -0
  35. mdbkit-0.3.0/mdbkit/parser.py +156 -0
  36. mdbkit-0.3.0/mdbkit/rebuild.py +185 -0
  37. mdbkit-0.3.0/mdbkit/render.py +336 -0
  38. mdbkit-0.3.0/mdbkit/report.py +187 -0
  39. mdbkit-0.3.0/mdbkit/scripts.py +69 -0
  40. mdbkit-0.3.0/mdbkit/tests/test_demo_lab.py +315 -0
  41. mdbkit-0.3.0/mdbkit/triage.py +810 -0
  42. mdbkit-0.2.1/README.md → mdbkit-0.3.0/mdbkit.egg-info/PKG-INFO +762 -604
  43. mdbkit-0.3.0/mdbkit.egg-info/SOURCES.txt +66 -0
  44. {mdbkit-0.2.1 → mdbkit-0.3.0}/pyproject.toml +1 -1
  45. mdbkit-0.3.0/tests/test_demo_lab.py +315 -0
  46. mdbkit-0.3.0/tests/test_explain.py +119 -0
  47. mdbkit-0.3.0/tests/test_ftdc.py +320 -0
  48. mdbkit-0.3.0/tests/test_mdbkit.py +331 -0
  49. mdbkit-0.3.0/tests/test_rebuild_report.py +160 -0
  50. mdbkit-0.3.0/tests/test_triage.py +173 -0
  51. mdbkit-0.2.1/mdbkit.egg-info/SOURCES.txt +0 -27
  52. {mdbkit-0.2.1 → mdbkit-0.3.0}/LICENSE +0 -0
  53. {mdbkit-0.2.1 → mdbkit-0.3.0}/mdbkit/advisor.py +0 -0
  54. {mdbkit-0.2.1 → mdbkit-0.3.0/mdbkit/build/lib}/mdbkit/explain.py +0 -0
  55. {mdbkit-0.2.1 → mdbkit-0.3.0/mdbkit/build/lib}/mdbkit/filtering.py +0 -0
  56. {mdbkit-0.2.1 → mdbkit-0.3.0/mdbkit/build/lib}/mdbkit/ftdc.py +0 -0
  57. {mdbkit-0.2.1 → mdbkit-0.3.0/mdbkit/build/lib}/mdbkit/rebuild.py +0 -0
  58. {mdbkit-0.2.1 → mdbkit-0.3.0/mdbkit/build/lib}/mdbkit/report.py +0 -0
  59. {mdbkit-0.2.1 → mdbkit-0.3.0/mdbkit/build/lib}/mdbkit/scripts.py +0 -0
  60. {mdbkit-0.2.1 → mdbkit-0.3.0/mdbkit}/tests/test_explain.py +0 -0
  61. {mdbkit-0.2.1 → mdbkit-0.3.0/mdbkit}/tests/test_ftdc.py +0 -0
  62. {mdbkit-0.2.1 → mdbkit-0.3.0/mdbkit}/tests/test_mdbkit.py +0 -0
  63. {mdbkit-0.2.1 → mdbkit-0.3.0/mdbkit}/tests/test_rebuild_report.py +0 -0
  64. {mdbkit-0.2.1 → mdbkit-0.3.0/mdbkit}/tests/test_triage.py +0 -0
  65. {mdbkit-0.2.1 → mdbkit-0.3.0}/mdbkit.egg-info/dependency_links.txt +0 -0
  66. {mdbkit-0.2.1 → mdbkit-0.3.0}/mdbkit.egg-info/entry_points.txt +0 -0
  67. {mdbkit-0.2.1 → mdbkit-0.3.0}/mdbkit.egg-info/requires.txt +0 -0
  68. {mdbkit-0.2.1 → mdbkit-0.3.0}/mdbkit.egg-info/top_level.txt +0 -0
  69. {mdbkit-0.2.1 → 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.2.1
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. All probing is stdlib-only (`/proc`, `statvfs`); no shell-outs,
215
- nothing leaves the machine.
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
@@ -319,13 +347,38 @@ mdbkit queries mongod.log --min-ms 500 --json
319
347
 
320
348
  ### `mdbkit connections <log>`
321
349
 
322
- Connection churn: totals, peak concurrent count, per-source-IP breakdown, and
323
- the client applications and drivers seen.
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>`
@@ -572,6 +625,85 @@ and metrics, never literal values from your documents.
572
625
 
573
626
  ---
574
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
+
575
707
  ### `mdbkit export-script {schema|indexes}`
576
708
 
577
709
  Prints a small `mongosh` script to stdout. **mdbkit never connects to your
@@ -591,12 +723,14 @@ mdbkit export-script schema > export_schema.js
591
723
  Terminal output is and will remain first-class — this tool is built for the
592
724
  Linux box the database actually runs on.
593
725
 
594
- **Shipped in v0.2:** FTDC decoding, incident triage with system metrics,
595
- query reconstruction (`--as-explain`), and shareable Markdown/HTML reports.
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.
596
729
 
597
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.
598
733
  * Per-shape drill-down (`mdbkit queries --shape N` with full detail).
599
- * `serverStatus` snapshot digest for triage (two snapshots for true rates).
600
734
  * Graduating the remaining beta detectors (checkpoints, eviction, flow
601
735
  control) once validated against real incident logs — see
602
736
  `docs/TESTING-PLAYBOOK.md`. Real logs very welcome.