mdbkit 0.1.0__tar.gz → 0.1.1__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 (29) hide show
  1. mdbkit-0.1.1/PKG-INFO +486 -0
  2. mdbkit-0.1.1/README.md +462 -0
  3. {mdbkit-0.1.0 → mdbkit-0.1.1}/mdbkit/__init__.py +1 -1
  4. {mdbkit-0.1.0 → mdbkit-0.1.1}/mdbkit/advisor.py +11 -3
  5. {mdbkit-0.1.0 → mdbkit-0.1.1}/mdbkit/analysis.py +25 -4
  6. {mdbkit-0.1.0 → mdbkit-0.1.1}/mdbkit/cli.py +89 -18
  7. mdbkit-0.1.1/mdbkit/filtering.py +93 -0
  8. {mdbkit-0.1.0 → mdbkit-0.1.1}/mdbkit/render.py +63 -13
  9. mdbkit-0.1.1/mdbkit/triage.py +591 -0
  10. mdbkit-0.1.1/mdbkit.egg-info/PKG-INFO +486 -0
  11. {mdbkit-0.1.0 → mdbkit-0.1.1}/pyproject.toml +40 -40
  12. {mdbkit-0.1.0 → mdbkit-0.1.1}/tests/test_mdbkit.py +116 -0
  13. {mdbkit-0.1.0 → mdbkit-0.1.1}/tests/test_triage.py +53 -0
  14. mdbkit-0.1.0/PKG-INFO +0 -207
  15. mdbkit-0.1.0/README.md +0 -183
  16. mdbkit-0.1.0/mdbkit/filtering.py +0 -55
  17. mdbkit-0.1.0/mdbkit/triage.py +0 -360
  18. mdbkit-0.1.0/mdbkit.egg-info/PKG-INFO +0 -207
  19. {mdbkit-0.1.0 → mdbkit-0.1.1}/LICENSE +0 -0
  20. {mdbkit-0.1.0 → mdbkit-0.1.1}/mdbkit/explain.py +0 -0
  21. {mdbkit-0.1.0 → mdbkit-0.1.1}/mdbkit/parser.py +0 -0
  22. {mdbkit-0.1.0 → mdbkit-0.1.1}/mdbkit/scripts.py +0 -0
  23. {mdbkit-0.1.0 → mdbkit-0.1.1}/mdbkit.egg-info/SOURCES.txt +0 -0
  24. {mdbkit-0.1.0 → mdbkit-0.1.1}/mdbkit.egg-info/dependency_links.txt +0 -0
  25. {mdbkit-0.1.0 → mdbkit-0.1.1}/mdbkit.egg-info/entry_points.txt +0 -0
  26. {mdbkit-0.1.0 → mdbkit-0.1.1}/mdbkit.egg-info/requires.txt +0 -0
  27. {mdbkit-0.1.0 → mdbkit-0.1.1}/mdbkit.egg-info/top_level.txt +0 -0
  28. {mdbkit-0.1.0 → mdbkit-0.1.1}/setup.cfg +0 -0
  29. {mdbkit-0.1.0 → mdbkit-0.1.1}/tests/test_explain.py +0 -0
mdbkit-0.1.1/PKG-INFO ADDED
@@ -0,0 +1,486 @@
1
+ Metadata-Version: 2.4
2
+ Name: mdbkit
3
+ Version: 0.1.1
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
+ Author: Saqib Ameen Subhan
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/CHANGEME/mdbkit
8
+ Project-URL: Issues, https://github.com/CHANGEME/mdbkit/issues
9
+ Keywords: mongodb,logs,logv2,mtools,index,dba,slow-query
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: System Administrators
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Topic :: Database
17
+ Classifier: Topic :: System :: Systems Administration
18
+ Requires-Python: >=3.8
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Provides-Extra: dev
22
+ Requires-Dist: pytest>=7; extra == "dev"
23
+ Dynamic: license-file
24
+
25
+ # mdbkit
26
+
27
+ **An offline toolkit for MongoDB structured logs — log analysis, slow-query shapes, connection churn, and deterministic index advice.**
28
+
29
+ A spiritual successor to [mtools](https://github.com/rueckstiess/mtools)' log tools (`mloginfo`, `mlogfilter`) for the structured JSON log format MongoDB has used since 4.4 — the format mtools never supported. Built for DBAs and ops engineers running self-managed MongoDB 4.4 / 5.0 / 6.0 / 7.0 / 8.0.
30
+
31
+ > **Privacy by design: mdbkit never makes a network call.** It reads log files (or stdin) and writes to stdout. No telemetry, no phoning home, no cloud. Your logs never leave your machine. It is safe to run on air-gapped database hosts.
32
+
33
+ ## Why
34
+
35
+ MongoDB 4.4 switched to structured JSON logging, and the beloved mtools log commands stopped working — the issue has been open since 2020. Meanwhile, index recommendations from MongoDB's Performance Advisor require a paid Atlas tier or Cloud/Ops Manager. If you run Community Edition on your own infrastructure, you're back to reading raw JSON logs with `grep` and `jq`.
36
+
37
+ mdbkit fills that gap: a single, dependency-free CLI that turns structured logs into answers.
38
+
39
+ ## Install
40
+
41
+ **Recommended on any Linux/Mac/Windows:**
42
+ ```bash
43
+ pip install mdbkit
44
+ ```
45
+
46
+ **Ubuntu 20.04 / Debian / Amazon Linux 2 (Python 3.8 hosts):**
47
+ ```bash
48
+ # Step 1: install pipx (manages isolated Python tool environments)
49
+ sudo apt install pipx # Ubuntu/Debian
50
+ # or: sudo dnf install pipx # RHEL/Rocky/Amazon Linux
51
+
52
+ # Step 2: install mdbkit
53
+ pipx install mdbkit
54
+
55
+ # Step 3: if pipx is not on your PATH yet
56
+ pipx ensurepath && source ~/.bashrc
57
+ ```
58
+
59
+ **If you get "externally-managed-environment" on modern Ubuntu (23.04+):**
60
+ ```bash
61
+ pip install mdbkit --break-system-packages
62
+ ```
63
+
64
+ **Air-gapped database hosts (no internet access):**
65
+ ```bash
66
+ # On a connected machine, download the wheel file
67
+ pip download mdbkit -d ./wheels
68
+
69
+ # Copy the ./wheels folder to the database host, then run
70
+ pip install --no-index --find-links ./wheels mdbkit
71
+ ```
72
+
73
+ **Upgrading to a newer version:**
74
+ ```bash
75
+ pip install --upgrade mdbkit # if installed with pip
76
+ pipx upgrade mdbkit # if installed with pipx
77
+ mdbkit --version # confirm
78
+ ```
79
+ mdbkit never updates itself and never checks for updates — it makes no network
80
+ calls at all. Upgrades are always explicit.
81
+
82
+ Requires Python 3.8+. Zero runtime dependencies — safe to install on production hosts.
83
+
84
+ > mdbkit is a Python package distributed via PyPI. It is **not** available
85
+ > via `apt install`, `dnf install`, or `yum install` — use `pip` or `pipx`.
86
+
87
+ ## Quick start
88
+
89
+ ```bash
90
+ # Overall log summary: versions, restarts, connection counts, error/warning totals
91
+ mdbkit loginfo /var/log/mongodb/mongod.log
92
+
93
+ # Slow queries grouped by query shape (literals stripped), ranked by total time
94
+ mdbkit queries mongod.log
95
+ mdbkit queries mongod.log --sort scanRatio --limit 10 --json
96
+
97
+ # Columns: cumMs = time summed across ALL occurrences of that shape (not one
98
+ # query); docsEx = documents examined; scan = examined per doc returned;
99
+ # plan = the plan MongoDB chose (COLLSCAN / IXSCAN{fields} / +SORT)
100
+
101
+ # Connection churn by source IP, appName, and driver
102
+ mdbkit connections mongod.log
103
+
104
+ # Filter raw log lines (output stays valid logv2 JSON — chainable)
105
+ mdbkit filter mongod.log --slow 500 --component COMMAND --ns shop.orders
106
+ mdbkit filter mongod.log --severity E --last 20 # 20 most recent errors
107
+ mdbkit filter mongod.log --slow 200 --limit 50 # first 50 matches only
108
+
109
+ # Time ranges — with or without a timezone offset
110
+ mdbkit filter mongod.log --from 2026-07-01T08:00:00+04:00 --to 2026-07-01T09:00:00+04:00
111
+ mdbkit filter mongod.log --from 2026-07-01T08:00:00Z # UTC
112
+ mdbkit filter mongod.log --from 2026-07-01T08:00:00 # log's own timezone
113
+ mdbkit filter mongod.log --from 2026-07-01 | mdbkit queries -
114
+
115
+ # Rotated/compressed logs work directly
116
+ mdbkit queries mongod.log.2.gz
117
+ ```
118
+
119
+ ### Step 1 — Export your indexes and schema (recommended)
120
+
121
+ mdbkit never connects to your database directly. Instead it prints small
122
+ `mongosh` scripts you run yourself, so you can inspect exactly what they do
123
+ before running them. The exports contain **field names and types only — no
124
+ document values.**
125
+
126
+ **Generate the export scripts:**
127
+ ```bash
128
+ mdbkit export-script indexes > export_indexes.js
129
+ mdbkit export-script schema > export_schema.js
130
+ ```
131
+
132
+ **Run them against your database** (replace with your actual host, port, and credentials):
133
+ ```bash
134
+ # Basic (local, no auth):
135
+ mongosh --quiet "mongodb://localhost/yourdb" export_indexes.js > indexes.json
136
+ mongosh --quiet "mongodb://localhost/yourdb" export_schema.js > schema.json
137
+
138
+ # With authentication (typical production setup):
139
+ mongosh --quiet \
140
+ --host your-db-host \
141
+ --port 27017 \
142
+ --username your-username \
143
+ --password your-password \
144
+ --authenticationDatabase admin \
145
+ --eval "$(cat export_indexes.js)" > indexes.json
146
+
147
+ mongosh --quiet \
148
+ --host your-db-host \
149
+ --port 27017 \
150
+ --username your-username \
151
+ --password your-password \
152
+ --authenticationDatabase admin \
153
+ --eval "$(cat export_schema.js)" > schema.json
154
+ ```
155
+
156
+ > In these examples, replace `yourdb` with your actual database name (e.g. `shop`, `myapp`).
157
+ > The `--authenticationDatabase` is usually `admin` unless you use per-db auth.
158
+
159
+ ### Step 2 — Run index advice
160
+
161
+ ```bash
162
+ # Basic (without index/schema context — still useful, but lower confidence):
163
+ mdbkit advise mongod.log
164
+
165
+ # Full (with context — sharper recommendations):
166
+ mdbkit advise mongod.log --indexes indexes.json --schema schema.json
167
+
168
+ # Focus on one collection (recommended for large logs):
169
+ mdbkit advise mongod.log --indexes indexes.json --schema schema.json --ns shop.orders
170
+ ```
171
+
172
+ Sample output:
173
+ ```
174
+ [1] shop.orders — confidence: HIGH
175
+ query shape : {createdAt:gt, status:eq} sort:{createdAt:-1}
176
+ candidate : { status: 1, createdAt: -1 }
177
+ evidence : COLLSCAN observed in planSummary
178
+ evidence : examined 251,400 docs to return 73 (3444:1)
179
+ caveat : Every index adds write and storage overhead ...
180
+ validate : Re-run the query with .explain('executionStats') ...
181
+ ```
182
+
183
+ With `--indexes`, mdbkit checks candidates against your existing indexes —
184
+ flagging when an existing index should already cover the query (it flags, never
185
+ auto-drops). With `--schema`, it warns about array (multikey) fields,
186
+ low-cardinality booleans, and field-name typos, and adjusts confidence
187
+ accordingly.
188
+
189
+ ### Incident triage (beta)
190
+
191
+ ```bash
192
+ mdbkit triage /var/log/mongodb/mongod.log # last 60 minutes (default)
193
+ mdbkit triage mongod.log --window 30 # last 30 minutes
194
+ mdbkit triage mongod.log --window 0 # whole file
195
+ mdbkit triage mongod.log --dbpath /data/db # if auto-discovery misses it
196
+ mdbkit triage mongod.log --no-sysprobe # analyzing a log copied off-host
197
+ ```
198
+
199
+ **Defaults to the last 60 minutes of log time**, because triage is for
200
+ incidents happening now or just finished. In one command:
201
+
202
+ - restarts, error clusters, election/stepdown events
203
+ - connection storms — with the peak minute and the top source IPs
204
+ - slow-query volume and the peak minute, so you know *when* it hurt
205
+ - COLLSCAN share of slow operations (the missing-index signal)
206
+ - the hot collection plus its top three query shapes inline
207
+ - index-build activity (a common cause of surprise load)
208
+ - slow checkpoints, cache eviction pressure, flow control
209
+ - disk / memory / CPU load, and the running mongod's RSS and uptime
210
+
211
+ When run on the database host, mdbkit finds `dbPath` automatically — from the
212
+ log's startup line, or the running `mongod` process, or `/etc/mongod.conf`,
213
+ 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.
216
+
217
+ Read-only: it never connects to the database, and every finding ends with a
218
+ next step for a human to review. Detectors marked beta are pattern-matched and
219
+ clearly labeled while broader validation is pending.
220
+
221
+ ### Explain-plan analysis
222
+
223
+ Got a slow query in hand rather than a log? Save its explain output and ask
224
+ mdbkit what's wrong:
225
+
226
+ ```bash
227
+ # in mongosh: EJSON.stringify(db.orders.find({...}).sort({...}).explain("executionStats"))
228
+ mdbkit explain explain.json
229
+ ```
230
+
231
+ You get the plan chain (`SORT -> COLLSCAN`), the examined/returned math, plain-
232
+ English verdicts (full collection scan, blocking in-memory sort, weakly
233
+ selective index, covered query), and — when the plan needs help — the same
234
+ evidence-backed candidate index the advisor would produce. Works with find and
235
+ aggregate explains, classic and SBE (6.0+) plans, and sharded winning plans.
236
+
237
+ ### Design principles
238
+
239
+ * **Deterministic.** Same log in, same advice out. Rules, not AI. Every
240
+ recommendation shows its evidence and its rule of reasoning.
241
+ * **Candidates, not commands.** mdbkit never tells you to blindly run
242
+ `createIndex`, and never advises dropping an index.
243
+ * **Honest about uncertainty.** Shapes seen once are labeled low-confidence;
244
+ `$or`, `$regex`, `$in` and low-selectivity operators carry explicit caveats.
245
+ * **Offline, always.** No network code exists in this codebase.
246
+
247
+ ## What it reads
248
+
249
+ Any MongoDB 4.4+ structured log: `mongod.log`, `mongos` logs, rotated `.gz`
250
+ files, or stdin (`-`). Slow-query lines (`"msg":"Slow query"`) are logged by
251
+ default for operations over `slowms` (100 ms); lower `slowms` or enable
252
+ profiling level 1 to capture more:
253
+
254
+ ```js
255
+ db.setProfilingLevel(1, { slowms: 50 })
256
+ ```
257
+
258
+ Pre-4.4 plain-text logs are detected and politely refused — for those, the
259
+ original mtools still works.
260
+
261
+ ## Command reference
262
+
263
+ Every command reads files or stdin and writes to stdout. `--help` works on any
264
+ command (`mdbkit queries --help`). Global: `mdbkit --version`.
265
+
266
+ All commands that read a log accept a path to a `.log` file, a rotated `.gz`
267
+ file, or `-` for stdin.
268
+
269
+ ---
270
+
271
+ ### `mdbkit loginfo <log>`
272
+
273
+ Overall log summary: server version, host, restarts, connections accepted,
274
+ slow-query count, warning/error counts, and a per-component line breakdown.
275
+
276
+ | Option | Description |
277
+ |---|---|
278
+ | `--json` | Machine-readable output |
279
+
280
+ ```bash
281
+ mdbkit loginfo /var/log/mongodb/mongod.log
282
+ mdbkit loginfo mongod.log.2.gz --json
283
+ ```
284
+
285
+ ---
286
+
287
+ ### `mdbkit queries <log>`
288
+
289
+ Slow queries grouped by **query shape** — literal values stripped, so the same
290
+ query with different parameters is counted once.
291
+
292
+ | Option | Default | Description |
293
+ |---|---|---|
294
+ | `--sort FIELD` | `totalMs` | Order by `totalMs`, `count`, `mean`, `max`, `docsExamined`, or `scanRatio` |
295
+ | `--limit N` | all | Show only the top N shapes |
296
+ | `--min-ms N` | 0 | Ignore operations faster than N milliseconds |
297
+ | `--include-system` | off | Include internal `admin`/`config`/`local` namespaces (hidden by default — they are server housekeeping, not your workload) |
298
+ | `--json` | | Machine-readable output |
299
+
300
+ **Reading the columns:**
301
+
302
+ | Column | Meaning |
303
+ |---|---|
304
+ | `cumMs` | Time summed across **all** occurrences of that shape — not one query |
305
+ | `mean` / `max` | Per-occurrence average and worst case |
306
+ | `docsEx` | Documents examined, summed across all occurrences |
307
+ | `scan` | Documents examined per document returned. `1:1` is ideal; `3444:1` means a missing or weak index |
308
+ | `plan` | The plan MongoDB chose: `COLLSCAN` (no index), `IXSCAN{fields}` (index used), `IDHACK` (`_id` lookup), `+SORT` (in-memory sort). `?` = the plan was not recorded on that line |
309
+ | `shape` | Fields and operators queried, with the sort |
310
+
311
+ ```bash
312
+ mdbkit queries mongod.log
313
+ mdbkit queries mongod.log --sort scanRatio --limit 10
314
+ mdbkit queries mongod.log --min-ms 500 --json
315
+ ```
316
+
317
+ ---
318
+
319
+ ### `mdbkit connections <log>`
320
+
321
+ Connection churn: totals, peak concurrent count, per-source-IP breakdown, and
322
+ the client applications and drivers seen.
323
+
324
+ | Option | Description |
325
+ |---|---|
326
+ | `--json` | Machine-readable output |
327
+
328
+ ---
329
+
330
+ ### `mdbkit filter <log>`
331
+
332
+ Streams **matching raw log lines** to stdout. Output stays valid logv2 JSON, so
333
+ it chains with other tools (including mdbkit itself).
334
+
335
+ | Option | Description |
336
+ |---|---|
337
+ | `--component NAME` | `COMMAND`, `NETWORK`, `REPL`, `STORAGE`, `INDEX`, `WRITE`, `QUERY`, `CONTROL`, … |
338
+ | `--severity S` | `I` info, `W` warning, `E` error, `F` fatal |
339
+ | `--ns NAMESPACE` | Exact namespace, e.g. `shop.orders` |
340
+ | `--slow N` | Only operations with `durationMillis` >= N |
341
+ | `--from TIMESTAMP` | Lower time bound (inclusive) |
342
+ | `--to TIMESTAMP` | Upper time bound (inclusive) |
343
+ | `--msg TEXT` | Substring match on the message field |
344
+ | `--limit N` | Print only the **first** N matches |
345
+ | `--last N` | Print only the **last** N matches — usually what you want during an incident |
346
+
347
+ **Timestamp formats accepted** by `--from` / `--to`:
348
+
349
+ ```
350
+ 2026-07-01T08:00:00+04:00 with an explicit offset (production logs)
351
+ 2026-07-01T08:00:00Z UTC
352
+ 2026-07-01T08:00:00 no offset — read as the log's own timezone
353
+ 2026-07-01 08:00:00 space instead of T
354
+ 2026-07-01T08:00 minute precision
355
+ 2026-07-01 whole day
356
+ ```
357
+
358
+ ```bash
359
+ mdbkit filter mongod.log --severity E --last 20
360
+ mdbkit filter mongod.log --component REPL --msg election
361
+ mdbkit filter mongod.log --slow 500 --ns shop.orders --limit 50
362
+ mdbkit filter mongod.log --from 2026-07-01T14:30:00+04:00 --to 2026-07-01T15:00:00+04:00
363
+ mdbkit filter mongod.log --slow 100 | mdbkit queries -
364
+ ```
365
+
366
+ ---
367
+
368
+ ### `mdbkit advise <log>`
369
+
370
+ Deterministic **candidate** index recommendations from observed slow-query
371
+ shapes, using the ESR guideline (Equality → Sort → Range). Rules, not AI: the
372
+ same log always produces the same advice.
373
+
374
+ | Option | Default | Description |
375
+ |---|---|---|
376
+ | `--indexes FILE` | | `indexes.json` from `mdbkit export-script indexes` — enables overlap checks against existing indexes |
377
+ | `--schema FILE` | | `schema.json` from `mdbkit export-script schema` — enables field-type caveats and confidence adjustment |
378
+ | `--ns NAMESPACE` | all | Only advise on one namespace (recommended on large logs) |
379
+ | `--limit N` | 10 | Show only the top N recommendations (`0` = all) |
380
+ | `--min-ms N` | 0 | Ignore operations faster than N milliseconds |
381
+ | `--min-count N` | 1 | Only advise on shapes seen at least N times |
382
+ | `--include-system` | off | Include internal `admin`/`config`/`local` namespaces |
383
+ | `--json` | | Machine-readable output |
384
+
385
+ Each recommendation carries a candidate key pattern, the evidence behind it, a
386
+ confidence level, caveats, and a validation step. mdbkit never advises dropping
387
+ an index — at most it flags an overlap to investigate.
388
+
389
+ ```bash
390
+ mdbkit advise mongod.log
391
+ mdbkit advise mongod.log --indexes indexes.json --schema schema.json
392
+ mdbkit advise mongod.log --ns shop.orders --limit 3
393
+ ```
394
+
395
+ ---
396
+
397
+ ### `mdbkit explain <file>`
398
+
399
+ Analyzes a saved `explain("executionStats")` document: the plan chain, the
400
+ examined-vs-returned math, plain-English verdicts, and — when the plan needs
401
+ help — a candidate index from the same advisor engine.
402
+
403
+ | Option | Description |
404
+ |---|---|
405
+ | `--indexes FILE` | Overlap check against existing indexes |
406
+ | `--schema FILE` | Field-type caveats |
407
+ | `--json` | Machine-readable output |
408
+
409
+ Produce the input with mongosh:
410
+ ```bash
411
+ mongosh --quiet --eval 'EJSON.stringify(db.orders.find({status:"open"}).sort({ts:-1}).explain("executionStats"))' > explain.json
412
+ mdbkit explain explain.json
413
+ ```
414
+
415
+ ---
416
+
417
+ ### `mdbkit triage <log>`
418
+
419
+ One-command incident snapshot. **Defaults to the last 60 minutes of log time.**
420
+
421
+ | Option | Default | Description |
422
+ |---|---|---|
423
+ | `--window N` | 60 | Analyze the last N minutes of log time; `0` = the whole file |
424
+ | `--dbpath PATH` | auto | Override the data directory used for the disk check |
425
+ | `--no-sysprobe` | off | Skip local disk/memory/CPU probes — use when analyzing a log copied off the host |
426
+ | `--json` | | Machine-readable output |
427
+
428
+ ```bash
429
+ mdbkit triage /var/log/mongodb/mongod.log
430
+ mdbkit triage mongod.log --window 30
431
+ mdbkit triage mongod.log --window 0 --no-sysprobe
432
+ ```
433
+
434
+ ---
435
+
436
+ ### `mdbkit export-script {schema|indexes}`
437
+
438
+ Prints a small `mongosh` script to stdout. **mdbkit never connects to your
439
+ database** — you run these yourself, so you can read exactly what they do
440
+ first. Both are read-only and export **field names and types only, never
441
+ document values**.
442
+
443
+ ```bash
444
+ mdbkit export-script indexes > export_indexes.js
445
+ mdbkit export-script schema > export_schema.js
446
+ ```
447
+
448
+ ---
449
+
450
+ ## Roadmap
451
+
452
+ Terminal output is and will remain first-class — this tool is built for the
453
+ Linux box the database actually runs on.
454
+
455
+ * **v0.2** — FTDC (`diagnostic.data`) decoding: offline summaries of the
456
+ metrics MongoDB already records on every node; election/failover timeline
457
+ from REPL events; per-shape drill-down.
458
+ * **v0.3** — shareable Markdown/HTML report export (for tickets and
459
+ post-incident reviews — a convenience layer, never a replacement for the
460
+ terminal).
461
+
462
+ mdbkit is validated against real-world structured logs (tens of thousands of
463
+ lines) in addition to its synthetic test fixtures.
464
+
465
+ ## Bugs, feature requests, questions
466
+
467
+ Please use [GitHub Issues](../../issues) — it keeps problems and fixes public
468
+ so the next person can find them. Real-world log lines that parse wrongly are
469
+ the most valuable bug reports of all (redact literals first!).
470
+
471
+ ## Security
472
+
473
+ mdbkit is offline by design: the codebase contains no network code, never
474
+ executes or evaluates input, and treats every log line as untrusted data
475
+ (strict JSON parsing only — shell constructors are never evaluated). See
476
+ [SECURITY.md](SECURITY.md) for the reporting process.
477
+
478
+ ## Non-affiliation
479
+
480
+ mdbkit is an independent community project. It is **not affiliated with,
481
+ endorsed by, or sponsored by MongoDB, Inc.** "MongoDB" is a registered
482
+ trademark of MongoDB, Inc., used here only to describe compatibility.
483
+
484
+ ## License
485
+
486
+ MIT — see [LICENSE](LICENSE).