A small PHP tool that groups and summarises PHP log errors: exception type (when detectable), normalised message, occurrence count, first/last timestamps, and collapsed duplicate stack traces per group.
It supports two input styles:
- Laravel-style (default) — Monolog lines like
[YYYY-MM-DD HH:MM:SS] channel.LEVEL: …with multi-line exception bodies. Best forstorage/logs/laravel*.log. - Generic PHP — Plain
PHP Warning:,PHP Fatal error:,Uncaught …,SQLSTATE[…], etc. Lines are batched from each “error” line until the next error. Handy for php-fpm/CLI or mixederror_logoutput that is not Laravel-blocked.
Reports: text (default), JSON, Markdown, or HTML. Write to a file with -o.
Follow these steps to get started with summarizing your PHP logs using devkit-log-summariser.
You have two options to install the tool:
-
Option 1: Install as a dependency in your project (recommended for production use):
composer require devkit/log-summariser
The binary will be available as
vendor/bin/devkit-log-summarise. -
Option 2: Clone and use locally (for testing or development):
git clone https://github.com/your-repo/devkit-log-summariser.git cd devkit-log-summariser composer installUse
php bin/devkit-log-summariseinstead ofvendor/bin/devkit-log-summariserin the commands below.
- Ensure you have access to a log file you want to summarize.
- For Laravel applications, use files like
storage/logs/laravel.logorstorage/logs/laravel-*.log. - For generic PHP logs, use files like
/var/log/php-fpm-error.logor any error log containing PHP warnings, fatal errors, or exceptions.
Run the tool on your log file to get a summary of grouped errors:
vendor/bin/devkit-log-summarise storage/logs/laravel.logThis will output a text-based summary to the console, showing grouped errors with occurrence counts, timestamps, and collapsed stack traces.
Choose the output format that suits your needs:
- Text (default): Human-readable summary in the console.
- JSON: Machine-readable format for scripts or further processing.
- Markdown: Formatted for documentation or tickets.
- HTML: Interactive web page with tabs and filtering.
Examples:
# JSON output
vendor/bin/devkit-log-summarise -f json storage/logs/laravel.log
# Markdown output saved to a file
vendor/bin/devkit-log-summarise -f md -o summary.md storage/logs/laravel.log
# HTML output
vendor/bin/devkit-log-summarise -f html -o report.html storage/logs/laravel.logThe tool supports two log formats:
- Laravel-style (default): Monolog-formatted logs with timestamps like
[YYYY-MM-DD HH:MM:SS]. - Generic PHP: Plain PHP error logs without the Laravel prefix.
For generic logs, specify the parser:
vendor/bin/devkit-log-summarise -p generic /var/log/php-fpm-error.logFor a deeper analysis, enable flow grouping to see related log entries as "flows" (requests, jobs, etc.):
# Generate HTML report with flows
vendor/bin/devkit-log-summarise --flows -f html -o flows.html storage/logs/laravel.log- Filter by flow type:
--flow-type=queue-job - Force grouping by a key:
--group-by=request_id - Include flow details in text output:
--flow-detail
See the "Flow Grouping" section below for more details.
- Console output: View directly in your terminal.
- File output: Use
-o filenameto save to a file. - HTML reports: Open in a web browser for interactive exploration.
- JSON/Markdown: Integrate into scripts, dashboards, or documentation.
The tool can group related log entries into "flows" — sequences of log entries that belong to the same request, job, command, or process. Flows help identify the full lifecycle of issues rather than isolated errors.
Flows are detected using identifiers like:
request_id,correlation_id,trace_idjob_uuid,batch_id,job.classcommandnamerouteorurl- Close timestamps for related entries
Each flow includes:
- Flow type:
request,queue-job,command,webhook,import,unknown - Start/end times and duration
- Entry count and log levels
- Main error and suggested action
- Confidence score (high/medium/low)
| Option | Description |
|---|---|
--flows |
Include flow grouping (requires --format=html) |
--flow-detail |
Include detailed flow entries in text output |
--flow-type |
Filter flows by type (request, queue-job, command, webhook, import, unknown) |
--group-by |
Force grouping by a specific key (request_id, correlation_id, trace_id, job_uuid, batch_id, command, route, user_id, tenant_id) |
# HTML report with flows
vendor/bin/devkit-log-summarise --flows --format=html -o report.html storage/logs/laravel.log
# Only queue job flows
vendor/bin/devkit-log-summarise --flows --format=html --flow-type=queue-job storage/logs/laravel.log
# Force grouping by user_id
vendor/bin/devkit-log-summarise --flows --format=html --group-by=user_id storage/logs/laravel.log
# Text output with flow details
vendor/bin/devkit-log-summarise --flows --flow-detail storage/logs/laravel.logThe HTML report provides interactive filtering, searching, and flow expansion with full details.
- PHP 8.3+
- Composer
From the project root (after dependencies are installed):
cd /path/to/devkit-log-summariser
composer install1. Laravel-style sample (timestamp blocks, stacks):
php bin/devkit-log-summarise tests/fixtures/logs/typeerror_repeat.log
php bin/devkit-log-summarise tests/fixtures/logs/sqlstate_repeat.log2. Generic PHP sample (no local.ERROR prefix):
php bin/devkit-log-summarise --parser=generic tests/fixtures/logs/generic_php.log3. JSON / Markdown (e.g. for scripts or a ticket):
php bin/devkit-log-summarise -f json tests/fixtures/logs/sqlstate_repeat.log
php bin/devkit-log-summarise --parser=generic -f md -o /tmp/summary.md tests/fixtures/logs/generic_php.log4. Run the test suite / quality checks (optional):
composer run tests
composer run standards:checkcomposer require devkit/log-summariserThe binary is published as vendor/bin/devkit-log-summarise when this package is required in another project.
vendor/bin/devkit-log-summarise [options] <log-file> [<log-file> ...]| Option | Short | Description |
|---|---|---|
--parser |
-p |
laravel (default) or generic |
--format |
-f |
text (default), json, md, markdown, or html |
--output |
-o |
Write the report to this file instead of stdout |
--flows |
Include flow grouping (requires --format=html or --flow-detail) |
|
--flow-detail |
Include detailed flow entries in text output | |
--flow-type |
Filter flows by type | |
--group-by |
Force grouping by a specific key |
Examples:
vendor/bin/devkit-log-summarise storage/logs/laravel.log
vendor/bin/devkit-log-summarise -p generic /var/log/php-fpm-error.log
vendor/bin/devkit-log-summarise -f json -o report.json app1.log app2.log
vendor/bin/devkit-log-summarise --flows --format=html -o flows.html storage/logs/laravel.log- Laravel / Monolog: each entry is expected to start with a line beginning
[YYYY-MM-DD HH:MM:SS]. The following lines belong to the same entry until the next such line. - Generic: a new group starts on lines that look like PHP or framework errors (e.g.
PHP Warning:,PHP Fatal error:,SQLSTATE[,Uncaught,*Exception:, or messages containingUndefined array key/Undefined indexwhen not prefixed withPHP Warning). Non-matching lines are skipped until the next error starter; continuation lines (stack#0,thrown in, etc.) are kept with the preceding error.
TypeError: Return value must be of type int, string returned in /app/Foo.php:10 — 3 occurrences
First: 2024-01-10 10:00:01 Last: 2024-01-10 12:00:00
Stack (most common duplicate):
#0 /app/Bar.php(5): Foo->x()
…
composer install
composer run tests
composer run standards:checkMIT
