From 38fa1471bad3213401ad1d7d831c7f52b2f3c78a Mon Sep 17 00:00:00 2001 From: indifferentketchup Date: Fri, 1 May 2026 05:41:36 +0000 Subject: [PATCH] Expand README with worked example and architecture overview Replaces the four-line stub with a usable landing page: install line, end-to-end PHP example showing how a caller goes from a log file to analysed insights, sample (placeholder-laden) output, a one-diagram architecture summary, and a per-game support table. Sends interested readers to CLAUDE.md for the extension guide and developer setup so this file stays focused on consumers. The example uses Project Zomboid because that is the in-tree reference implementation. Output is illustrated with placeholder identifiers (, , ) rather than copied real-log content. --- README.md | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f98287b..dc3b537 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,97 @@ # IndifferentKetchup Codex -A generic PHP log parsing and analysis framework. Provides interfaces and base implementations for reading log files, detecting log types, parsing entries into structured form, analysing them for problems and information, and printing results. +Generic PHP log parsing and analysis framework. Reads a log file, detects which log type it is, parses entries (including multi-line records like Java stack traces), runs the type-specific analysers, and returns structured `Information` and `Problem` insights with attached `Solution`s where applicable. -## Installation +Originally a fork of [`aternos/codex`](https://github.com/aternosorg/codex); the framework is intentionally game-agnostic. The reference implementation in this tree is Project Zomboid server logs. + +## Install ``` composer require indifferentketchup/codex ``` +Requires PHP `>=8.4`. No third-party runtime dependencies. + +## Quick start + +Given a Project Zomboid `DebugLog-server.txt`: + +```php +setLogFile(new PathLogFile('2026-04-30_14-00_DebugLog-server.txt')); + +$log = $detective->detect(); +$log->parse(); +$analysis = $log->analyse(); + +echo $log->getTitle(), "\n\n"; + +foreach ($analysis->getInformation() as $info) { + echo "[INFO] ", $info->getMessage(), "\n"; +} + +foreach ($analysis->getProblems() as $problem) { + echo "[PROBLEM] ", $problem->getMessage(), "\n"; + foreach ($problem->getSolutions() as $solution) { + echo " -> ", $solution->getMessage(), "\n"; + } +} +``` + +For a session with mod issues and a server-side exception, output looks roughly like: + +``` +Project Zomboid Debug Server Log + +[INFO] Engine version: 42.16.3 (build , ) +[INFO] Mod loaded: +[INFO] Mod loaded: +[PROBLEM] Required mod "" not found. + -> Subscribe to mod "" or remove its ID from the Mods= line in serverconfig.ini. +[PROBLEM] Exception thrown: java.nio.file.NoSuchFileException +``` + +If the log content arrives without a filesystem path (clipboard paste, web upload, stream), use `StringLogFile` or `StreamLogFile` instead of `PathLogFile`. The detective falls back to content signatures when the filename hint is absent. + +## Architecture + +``` +LogFile → Log → parse() → Entry[] of Line[] → analyse() → Analysis of Insight[] + └── Information | Problem(+Solutions) +``` + +- **`Detective`** ranks candidate `Log` subclasses by running each candidate's static `getDetectors()` and picking the highest-scoring result. Each game ships its own `Detective` that pre-registers its log classes. +- **`PatternParser`** is regex-driven; lines that don't match the entry-start regex append to the previous `Entry`, which is how multi-line records (Java stack traces, indented warnings) are kept intact. +- **Analysers** come in two flavours: configured `PatternAnalyser` instances for per-entry pattern matching, and custom subclasses of `Analyser` for cross-entry logic (pairing events, sliding-window thresholds, snapshot comparisons). +- **Insights** are either `Information` (label + value) or `Problem` (with attached `Solution`s). Equal insights coalesce via a counter, so repeated patterns don't produce duplicate output. + +Patterns live as plain `string` constants under `src/Pattern//` — there is no `PatternInterface`. Each game adds files under `src///` (components-outer, game-suffixed). Full extension guide and conventions in [`CLAUDE.md`](CLAUDE.md). + +## Game support + +| Game | State | +|---|---| +| Project Zomboid | Full: 11 log subclasses across all the file types a server emits; analysers covering engine version, mod loading, server exceptions, PvP combat, admin audit, connection failures, item duplication, skill progression anomalies | +| Minecraft | Stub only — `MinecraftDetective` skeleton, no log subclasses yet | +| Hytale | Stub only | +| Seven Days To Die | Stub only | + +The framework itself is generic — adding a new game means writing the same shape of files Project Zomboid demonstrates, not modifying anything in `src/{Analyser,Analysis,Detective,Log,Parser,Printer,Pattern}/` outside the new game's subdirectory. + +## Developing + +`composer test` runs the suite. PHP and Composer are not required on the host — invocations wrap in the official `composer:latest` Docker image (PHP 8.5). See [`CLAUDE.md`](CLAUDE.md) for the wrapped command, file layout, and the workflow conventions used in this repo. + ## Source + +## License + +MIT — see [`LICENSE`](LICENSE).