jackiedo/log-reader
A Laravel package for reading and browsing application log files from PHP. It parses log entries, filters by level, paginates results, and makes it easy to surface logs in admin panels or dashboards without leaving your app.
Architecture fit
The package is a self-contained, in-process Laravel add-on: a service provider registers a config file, a facade (LogReader), a handful of routes, controllers, and Blade views. It reads files from storage/logs (or configured paths), parses Monolog's default line format with regex, and renders a paginated browser UI with download and delete actions. There is no database dependency, no queue, no external service — so architectural fit is high for a Laravel monolith or a small multi-tenant app that has no centralized logging stack. It is explicitly not an observability platform: it is a convenience shim over the filesystem, and should be scoped that way. If a TPM frames this as "replace Datadog/Loki," the evaluation fails; framed as "give support engineers a read-only log console without SSH," it passes.
Release 2.3.0 does not change the architecture — no new surface area, no new dependency, no migration. It changes two things that matter to a TPM: the package now claims Laravel 10.x support, and it no longer breaks on Alpine Linux. Both are credibility signals rather than capability changes.
Integration feasibility
Low effort. composer require + config publish + route/middleware wiring is measured in minutes, not sprints. The real integration work is governance, not code: gating the routes behind authentication and authorization, deciding whether delete/download are enabled at all, and confirming the log-file pattern matches the actual channel layout (single vs. daily vs. stack). The facade also allows programmatic access, which is the more interesting extension point — a TPM could expose curated log health signals (error counts, recent exception files) through a first-party admin endpoint rather than shipping the vendor UI.
The Alpine fix (GLOB_BRACE unavailable under musl, issue #46) materially improves integration feasibility for container-first teams. The failure mode it removes was ugly: an undefined-constant error or empty listing on any php:*-alpine or Alpine-based image, which is a common base for slim Laravel containers. It also confirms the package globs the log directory rather than hardcoding laravel.log, which is evidence (not proof) that daily-rotated channels are supported.
Technical risk
storage/logs/laravel.log assumes the default Monolog line formatter. Any team using JSON formatters, custom channel formatters, or non-standard stack output will get partially parsed or unparsed entries. This remains the single most likely source of "the tool is broken" tickets, and 2.3.0 does not touch it.Key questions
composer.json?GLOB_BRACE failure.Stack fit
Best fit: single-region Laravel 8–10 monolith on a VM or container with a persistent storage/logs volume, small platform team, no existing log aggregation. Laravel 10 is now explicitly in scope, and Alpine-based container images — previously a poor fit due to the GLOB_BRACE bug — are now supported, provided we pin ≥2.3.0. Still a poor fit: serverless/ephemeral containers (logs vanish with the instance), multi-node clusters (you see one node's logs), or anything with a compliance requirement around log data residency and access auditing.
Migration path
Non-breaking by construction — it is additive and reads files it does not own. Sequence: install in a non-production environment at version ^2.3 → validate parser output against real log samples from each channel → publish and pin the config → wrap routes in the application's existing auth middleware → ship to staging behind a feature flag → enable in production for an internal-only route group. The only sequencing change from the prior assessment is that the Alpine compatibility question is closed and the Laravel 10 question is closed, so the spike can focus purely on the parser and the log-file glob behavior.
Compatibility
Verify three things before committing: (a) that composer update resolves against our constraint set — 2.3.0 claims Laravel 10.x, so if we are on 8/9/10 this should be frictionless, and if we are on 11+ expect a fork conversation; (b) that the glob pattern config covers our daily-rotated files (strongly implied by the GLOB_BRACE fix, but confirm empirically with a rotated laravel-YYYY-MM-DD.log corpus); (c) that view publishing does not conflict with any existing admin layout. Pin ^2.3 rather than a floating constraint, purely so the Alpine fix is guaranteed present in every environment. Because the package is small and MIT, an incompatible constraint remains a fork-and-patch conversation, not a blocker.
Sequencing
Keep it strictly out of the critical path — no application code should depend on LogReader beyond optional admin tooling, so removal is a config revert.
Maintenance
Effectively zero ongoing operating cost, but non-zero stewardship cost. The 2.3.0 release slightly improves the stewardship outlook: an issue was reported and fixed, and a community PR was merged, so we are not the sole maintainers the day we install it. However, a single release after a long gap is not a cadence. Budget a recurring review at each Laravel major upgrade to confirm the package still installs and the parser still matches our log format. Keep the vendor-the-source option open but no longer default to it — vendor only if we hit a major upgrade with no upstream response, since that converts an unmaintained dependency into owned, auditable code at real cost.
Support
Support load is front-loaded: the first month generates "log not showing," "entries cut off," and "wrong format" tickets, all traceable to parser/pattern mismatch. The most common environmental cause — Alpine/musl — is now fixed, which should reduce first-month noise for containerized deployments. After that it is quiet. Document the tool's limits explicitly in the internal runbook — that it shows local files only, that truncation and rotation affect results, that it is not a source of truth for alerting, and that a minimum version of 2.3.0 is required for Alpine hosts.
Scaling
Unchanged and still the weakest dimension. Reading is file-based with chunked reads and pagination, so a few hundred megabytes is tolerable and multi-gigabyte files on a busy production node will be slow and memory-hungry, particularly when a user pages deep or triggers a download. There is no index and no search backend, so every query re-scans. Rotated log retention is bounded by whatever logrotate/Laravel daily settings already exist — the tool does not extend retention and will not surface logs that have been rotated away. Concurrency is also unmanaged: multiple engineers paging the same large file on the same node means repeated full scans. Nothing in 2.3.0 addresses any of this, and it is not the sort of thing a patch release would.
Failure modes
Ramp-up
Hours, not days. Any Laravel developer can read the source in one sitting, and the UI is self-explanatory for non-engineers. The ramp-up risk is not learning the tool — it is engineers over-trusting it, treating a file-scoped viewer as authoritative during incidents when the real signal lives in an aggregator. Counter that with a short runbook note and a deliberate framing of the tool as a convenience layer, not a monitoring system.
How can I help you explore Laravel packages today?