Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Logs Explorer Laravel Package

laboiteacode/filament-logs-explorer

Read Laravel log files inside your Filament panel, grouped by channel with a slide-over viewer, in-file search, match navigation, keyboard shortcuts, large-file truncation, and file deletion behind authorization.

View on GitHub
Deep Wiki
Context7

Getting Started

1. Install and register the plugin. The package is a Filament panel plugin, so it goes in your panel provider, not in a service provider:

composer require laboiteacode/filament-logs-explorer
php artisan vendor:publish --tag="filament-logs-explorer-config"   # if a config is published
// app/Providers/Filament/AdminPanelProvider.php
use LaBoiteACode\FilamentLogsExplorer\FilamentLogsExplorerPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->plugins([
            FilamentLogsExplorerPlugin::make(),
        ]);
}

Verify the exact plugin FQCN and any make() options against the README for your installed version — the namespace follows the vendor prefix and has moved between releases of packages in this family.

If you cache Filament components, clear it after install or upgrade. php artisan filament:optimize caches the plugin/page registration, including which cluster a page was filed under. On v1.0.2 specifically, the cluster() option was fixed — but the fix only takes effect after you re-run php artisan filament:optimize. Until then you'll still see the old, unclustered registration and assume the update didn't work.

2. Look at two things first, not the UI. Before clicking around, open config/logging.php and confirm your default channel resolves to a file. The plugin reads channels from config rather than globbing storage/logs, so single, daily, and monolog stream handlers with a path/stream show up; stderr, syslog, errorlog, and PaaS-managed channels do not. Then check that the PHP user serving the panel can actually read storage/logs/*.log (ls -l, sudo -u www-data cat ...).

3. First real use case. The highest-value moment is: a user reports a 500, you have no SSH session handy, and you want the stack trace. Open the panel → Logs Explorer → pick the daily channel for today → press /, paste the exception class or the request ID from your log context → n to walk matches. That single loop replaces "tail the file over SSH, grep, scroll" for the majority of small incidents.

Implementation Patterns

Gate it before you ship it. Log files leak credentials, tokens, SQL, and personal data. Either register the plugin only on a restricted panel, or wrap it in an authorization check:

->plugins([
    ...(auth()->user()?->can('viewLogs') ? [FilamentLogsExplorerPlugin::make()] : []),
])

If the plugin exposes an authorization closure (check the README's config/API for authorize() or canAccess()), prefer that over conditional array spreading — it keeps the navigation entry defined but denied, which is easier to debug than a mysteriously missing menu item.

Make the channel grouping meaningful. The package's channel-aware listing is only as good as your logging config. If everything goes to the default stack, you get one giant file. Split by domain and you get navigable buckets:

// config/logging.php
'channels' => [
    'stack' => [
        'driver' => 'stack',
        'channels' => ['daily', 'payments', 'jobs'],
    ],
    'payments' => [
        'driver' => 'daily',
        'path' => storage_path('logs/payments.log'),
        'days' => 14,
    ],
    'jobs' => [
        'driver' => 'daily',
        'path' => storage_path('logs/jobs.log'),
        'days' => 7,
    ],
],
Log::channel('payments')->error('Gateway declined', ['order' => $order->id, 'code' => $code]);

Now an incident has a short list to check instead of one 400 MB file.

Add searchable context to every log line. The viewer's in-file search is a plain text match, so give it handles: request IDs, job UUIDs, user IDs. A small middleware plus a Log::withContext([...]) call makes / searches dramatically more useful:

Log::withContext([
    'request_id' => (string) Str::uuid(),
    'user_id' => auth()->id(),
]);

File it under a cluster on multi-panel apps. As of v1.0.2 the cluster() option actually works, via either the fluent method or the cluster config key:

FilamentLogsExplorerPlugin::make()
    ->cluster('System'),

The bug it fixes is worth knowing about because it shaped behaviour you may have relied on: the page used to register before the plugin could be resolved from its panel, so it landed unclustered — and on apps with several panels it could silently inherit the cluster configured on a different panel. If you previously worked around this by moving the resource or hacking the page class, remove the workaround and re-run the optimize cache command.

Use it as the fast path, not the record. Day to day this is the "what just happened" tool: check the newest daily file after a deploy, confirm a queued job's exception, verify a webhook handler logged what you expected. Keep your real observability (Sentry, Flare, or an aggregation stack) for history, alerting, and correlation across services — the package has no retention of its own beyond what LOG_DAILY_DAYS leaves on disk.

Pair it with the environment. Register it in local, staging, and a tightly-gated production panel; skip it entirely in CI. If you use a container platform where LOG_CHANNEL=stderr, the package will render an empty channel list on production even though logs exist — that's expected, not a bug.

Gotchas and Tips

  • Empty or missing file list. Almost always one of: default channel resolves to a non-file driver; the PHP-FPM/Octane user lacks read permission on storage/logs; or daily files are being written by a different process (queue worker as another user) into a directory you can't read. Check ownership, not just mode bits.
  • The current day's daily file may be empty. That's the healthy state. If you're hunting a recent error and the current file is blank, look at yesterday's — Monolog rotates on the date boundary, and long-running workers may still hold a handle to the previous file.
  • Big files are a browser problem. A multi-hundred-MB log will make in-file search and highlighting crawl or hang the slide-over. Practical mitigations: keep LOG_DAILY_DAYS low, split into per-domain channels as above, and treat any single log over a few tens of MB as a job for grep/rg on the server rather than the panel.
  • Log injection is a real surface. User-controlled data (user agents, referrers, form input) lands in log files verbatim. Ensure the viewer escapes output, and be aware that a crafted line containing your search token will match. Rotate and truncate logs containing untrusted input, and treat the viewer as an admin-only tool.
  • Download buttons export raw files. Whatever redaction you do upstream is bypassed here. If your logs contain PII or secrets, the authorization gate is the only real control — audit it, don't rely on obscurity of the navigation group.
  • Keyboard shortcuts need focus discipline. /, n, N, g are only safe when the slide-over owns the keyboard. If shortcuts feel dead, click inside the viewer first; if they fire while you're typing in a Livewire search field elsewhere, that's a conflict to report/disable rather than work around.
  • Stack channels only partially appear. A stack lists only its file-based members. If your stack is ['daily', 'stderr'], don't expect a stderr entry — there's no file to read.
  • Stale component cache after any plugin-config change. Editing plugins([...]), the cluster key, or the navigation methods has no visible effect until php artisan filament:optimize runs again (or you clear the cached file). Symptom: the page sits in the old nav group/cluster, or changes you made "revert". Add the optimize command to your deploy script rather than remembering it manually.
  • Navigation placement. Drop it under a system group and sort it last so it doesn't compete with daily-use resources: set the label/group/sort/cluster via the plugin's fluent methods (confirm names in the README) rather than editing the package's page class.
  • Extension points worth checking on install. Whether the page class is overridable, whether LogFile-style value objects are exposed for custom pages, and whether file resolution can be swapped for an S3/remote stream. If the package doesn't expose these, the supported extension is a custom Filament page that reuses your own reader — don't fork for it.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus