dotswan/eagle-eye-filament
Filament plugin integrating Dotswan Eagle Eye, adding a zoomable image viewer field so you can inspect and preview images directly inside Filament forms and admin panels.
dotswan/eagle-eye-filament is the admin UI layer, not the engine. The core dotswan/eagle-eye package does the capture, storage and querying; this package gives you Filament 5 pages, charts and widgets on top of it. Budget for installing both, in that order.
Prerequisites
dotswan/eagle-eye at 1.0.0-beta.1 or newer — the Filament package will not work against older core versions.Install
composer require dotswan/eagle-eye:^1.0@beta dotswan/eagle-eye-filament:^1.0@beta
Both constraints need @beta (or minimum-stability: beta in composer.json) because no stable tag exists yet. Pin both to the same beta line and bump them together — see Gotchas.
Then, in rough order
Publish and run the core package's migrations/config (php artisan vendor:publish --tag=... then migrate). The Filament package is a read layer; it has nothing to show until events exist.
Register the plugin on your admin panel in app/Providers/Filament/AdminPanelProvider.php:
->plugin(\Dotswan\EagleEyeFilament\EagleEyeFilamentPlugin::make())
Confirm the exact FQCN from the package README — pre-1.0 namespaces have moved before.
Publish the Filament assets (php artisan filament:assets) and, if you use a custom theme, rebuild it so the package views pick up your Tailwind config.
Define who can see it. Do this before you demo it to anyone — the pages expose request payloads, actor identities and field-level diffs.
First use case: open the Activity overview and read the KPI cards and channel/severity charts to establish a baseline, then jump into the Activity explorer and filter to a single channel and a 24-hour window. That two-minute path tells you whether your capture pipeline is emitting what you think it is, which is the fastest way to validate the whole install.
Where to look first: the core package's config (channels, severity mapping, retention), then the Filament package's config for reveal policies and Livewire capture, then your AuthServiceProvider/policies.
Panel plugin, not a route file. Everything hangs off the panel plugin registration. Put it on your admin/staff panel only; registering it on a customer-facing panel is the fastest way to leak internals. If you run multiple panels, register per-panel and vary config through the panel's ->plugin(...) chain rather than global config where possible.
Gate the surface, then gate the detail. Two layers:
// Coarse: who can open the pages at all
public function canAccess(): bool
{
return $this->user?->hasRole('support-lead') ?? false;
}
// Fine: policy-gated reveal of field-level changes / payloads
Gate::define('viewEagleEyePayload', fn (User $u, $event) => $u->isAdmin());
Coarse gating via the plugin/panel keeps the navigation clean; the per-event reveal policy is what stops a support agent from reading a password-reset token out of a payload diff. Wire both, and write a test asserting the 403 — this is the one place where a silent regression is a security incident.
Dashboard widgets on the panel, history on resources. KPI cards, sparklines and the actor heatmap are panel widgets — register them in the panel's widgets([...]) or discoverWidgets. The record history and recent-traces blocks are more useful embedded next to the thing they describe: drop them onto a resource view page or as a tab so an agent debugging "why did this order change" never leaves the order screen. Keep the dashboard for aggregate triage and the resource page for per-record forensics.
Structured token search is the power feature — teach it. The explorer's token syntax (channel:, severity:, plus whatever actor/trace tokens the package exposes — check the in-UI field reference, not the release notes) is what separates this from a log viewer. Bake the syntax into onboarding docs and saved links. Facets and tokens should agree; if a facet click produces a filter the token bar can't reproduce, that's worth reporting upstream.
Traces are only as good as your propagation. The trace timeline and stream view correlate events by trace/request ID. That ID has to be injected by you — middleware that generates a ULID per request and pushes it into the core package's context, plus job/middleware propagation for queues. Without that, the trace view renders single-event timelines and looks broken.
Livewire interaction capture needs scoping. Turning it on gives you readable Filament page/action titles instead of raw component classes, which is genuinely useful for "what did the admin actually click". But it is high-volume and it captures user behaviour. Enable it for admin/support panels, not the whole app; filter out noisy polling components; and check whether payloads are captured or only titles before you enable it in production.
Seed realistic data locally. You cannot evaluate the charts against three fixture rows. Write a seeder or artisan command that pushes a few thousand synthetic events through the core package across several channels, severities and trace IDs, with a minority of events carrying field-level changes. This also gives you a dataset for checking chart query performance.
1.0.0-beta.1 and the notes explicitly say the API may change. Pin exact versions (1.0.0-beta.1, not ^1.0@beta) in composer.lock, read CHANGELOG.md before every bump, and expect at least one breaking change to plugin registration or config keys before 1.0.0. Do not build internal tooling that hard-depends on package internals.>= 1.0.0-beta.1. Upgrading one and not the other produces confusing failures — typically a missing method or an empty page rather than a clean exception.filament:assets alone is not enough if you ship a Vite/Tailwind theme.reveal gate actually protects — titles only, or arguments too.vendor:publish for branding, and config-level channel/severity labels for domain vocabulary. Avoid subclassing package pages — those are the classes most likely to change pre-1.0.How can I help you explore Laravel packages today?