fdekker/log-viewer-bundle
A Laravel log viewer bundle for browsing, searching, and filtering application log files from a web interface. Quickly inspect errors and stack traces, filter by level or date, and debug production issues without opening log files on the server.
Start with the compatibility check, not the install. fdekker/log-viewer-bundle is a Symfony bundle for Symfony 6+. Laravel has no concept of bundles — there is no bundles.php, no bundle bootstrapping, and Composer's type: symfony-bundle will install the files but nothing will register. Running composer require fdekker/log-viewer-bundle in a Laravel app gets you a dead dependency and a few hundred KB in vendor/.
So the first question is which of these you actually are:
opcodesio/log-viewer (or rap2hpoutre/laravel-log-viewer for something minimal). They are the Laravel-native equivalents and will take ten minutes instead of a day.If you're in case 1, minimal steps:
composer require fdekker/log-viewer-bundleconfig/bundles.php (Symfony Flex may do this for you)config/routes/fdekker_log_viewer.yaml or an explicit resource: '@LogViewerBundle/...' entryphp bin/console config:dump-reference <bundle_alias>) to find the log path and route prefix keys — don't guess them from the README alonesecurity.access_control rule before you open the URL in a browserWhere to look first in the repo: the DependencyInjection/Configuration.php (authoritative list of config keys), the routing definition (default prefix), and the controller(s) that read files off disk. The README will be thinner than the code.
Pattern A — read-only sidecar (the only sane way to get this UI into a Laravel shop). Run a throwaway Symfony skeleton as a container alongside your Laravel app, mount the Laravel storage/logs directory into it read-only, and point the bundle at that mount:
docker-compose service, no public port; expose only through your existing reverse proxy with auth in frontvolumes: - ./storage/logs:/var/log/app:ro — the :ro matters.envPattern B — port the concept to Laravel. The bundle's value is mostly its parsing and level-filtering logic. In Laravel you'd build:
LogFileRepository that lists and resolves files under storage_path('logs'), with a hard allowlist of extensions and a realpath() containment checksingle, daily) that yields structured entries — this is the piece worth borrowingauth middleware groupThis is roughly a day of work and gives you something you own, with no Symfony runtime.
Pattern C — native Symfony use. If the app really is Symfony, the everyday workflow is: open the route, filter by channel/level/date, and follow the request ID through. The integration tips that matter are gating the route with a firewall and keeping the bundle out of prod unless it's behind real auth. Use Symfony's DI decoration on the bundle's log-reader/parser service if you need custom path resolution (e.g. a per-tenant log directory) rather than forking.
Pattern D — multi-channel mapping. Laravel writes laravel.log, laravel-2024-01-01.log, plus any custom channels. If you're mapping these into a viewer, treat "channel" as a first-class filter derived from the filename, and normalize the two on-disk formats early. Most viewer bugs come from mixing stack-trace continuation lines into the previous entry.
Integration tip that applies to all of the above: put the viewer behind your SSO/forward-auth layer, not behind app-level auth. Log files contain database credentials, API tokens pasted into exceptions, and user PII. A viewer that inherits a weak session cookie is a data breach with a nice UI.
php artisan command. There is no amount of config publishing that makes this work in Laravel. Budget for this being a "no" before you budget for anything else.composer.json, commit composer.lock, and assume you may need to fork. Don't put it on a critical path you can't patch yourself./_log-viewer, /logs, etc.). If you install and immediately browse to it "just to test" on a public host, you may have already leaked. Configure the firewall/access_control first, enable second.[2024-01-01 12:00:00] production.ERROR: message ... with a multi-line stack trace below it. A viewer written against Symfony's default Monolog line format will either drop these or mis-group the trace. Test with a real Laravel log file, not a fixture.file_get_contents. A 500 MB laravel.log after an incident loop will OOM the viewer process, and that's exactly when you need it. Look for tail/offset support; if absent, add a size cap in config.:z/:Z). Symptom is a silent empty file list, not an exception — check the viewer's own log.bin/console cache:clear in prod. This trips people up constantly when the "log path change didn't take."daily channels, the file the viewer opened at page load may be renamed mid-request. Resolve the path per-request, not at container boot.LogParser interface in a service provider — design for that from the start so you can swap formats per channel.APP_ENV !== 'production' or a separate admin hostname.How can I help you explore Laravel packages today?