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

Nova Logs Laravel Package

php-junior/nova-logs

A Laravel Nova tool for browsing and reading your application's log files directly from the Nova dashboard. View, filter, and follow logs without SSH access, inspect errors, and debug production issues faster. Simple to install and use, it brings everyday log inspection into your admin panel.

View on GitHub
Deep Wiki
Context7

Getting Started

Confirm the substrate before you type composer require. This is a Nova Tool, not a standalone viewer — if composer show laravel/nova doesn't resolve, you're done here. Last release was October 2022, so the presumed target is Nova 4 / Laravel 8–9. A throwaway branch with a bare require against your actual PHP/Laravel/Nova versions is the go/no-go gate. Do that first; everything below assumes it passed.

composer require php-junior/nova-logs
php artisan vendor:publish --list          # find the package's tag/service provider
php artisan vendor:publish --provider="PHPJunior\NovaLogs\ToolServiceProvider"
php artisan nova:publish                   # publishes the tool's Vue bundle

Register it as a tool, not a resource. Nova tools live in NovaServiceProvider::tools():

public function tools()
{
    return [
        \PHPJunior\NovaLogs\Tool::make(),
    ];
}

Verify the exact class name and namespace in vendor/php-junior/nova-logs/src — this package is small and lightly documented, and a wrong FQCN is the most common first-five-minutes failure.

Gate it in the same commit you install it. Nova's own auth is not an authorization model for raw log files. The Tool base class carries AuthorizedToSee, so canSee() should work; if it doesn't, subclass the tool and apply canSee there.

// AuthServiceProvider
Gate::define('viewLogs', fn (User $user) => $user->hasRole('ops'));

// NovaServiceProvider
\PHPJunior\NovaLogs\Tool::make()
    ->canSee(fn ($request) => $request->user()?->can('viewLogs')),

Read the source before you trust it. vendor/php-junior/nova-logs/src is a handful of files. Find four things: the config key controlling the log path, the controller that streams file contents, whether download/delete endpoints exist, and whether those endpoints sit behind any check beyond Nova's own middleware. That half-hour is your entire security review and it tells you what is actually configurable.

First real use case — the one that pays for the install. Support reports a 500 twenty minutes ago. Nova → Logs → pick laravel.log → search the customer ID, the route, or the exception class. Stack trace in the browser. No ssh + tail -f + grep relay. Internalise that as the scope of the tool: what is in this file right now. Don't over-invest beyond it.

Implementation Patterns

Environment-flagged registration. Ship to staging first, hide in production until you've validated it against real log volume:

public function tools()
{
    return array_filter([
        config('services.nova_logs.enabled')
            ? \PHPJunior\NovaLogs\Tool::make()
                ->canSee(fn ($r) => $r->user()?->can('viewLogs'))
            : null,
    ]);
}

Default to read-only. If the tool exposes delete or download, disable them, or restrict them behind a tighter gate than viewing. On a shared Nova instance "delete log file" is one misclick away from destroying the evidence you're mid-incident on. Retention is the log channel's job (LOG_DAILY_DAYS), not a UI button's.

Make the logs searchable by design. The viewer does literal substring matching over a flat file — no index, no query language, no case-insensitivity guarantee. Your triage quality is therefore a direct function of what you write into context:

// AppServiceProvider::boot() or a middleware
Log::withContext([
    'request_id' => $requestId,
    'user_id'    => auth()->id(),
    'tenant_id'  => tenant('id'),
]);

Then "search this request ID" is a repeatable workflow instead of a lucky one. Also log stable, greppable business identifiers (order number, email, job class) at the points where support actually calls in.

Run bounded daily channels. single produces one unbounded file that this tool has to parse in-request. daily with sane retention keeps files small, fast, and safe to render. If you're still on single, installing this package is the moment that decision starts hurting.

Wire it into a triage chain, not as the sole tool.

  1. Alert or customer report → Nova Logs, search the contextual identifier.
  2. Exact exception + timestamp → Telescope for the request/query/job that produced it, or Horizon for queue failures.
  3. Nova Logs answers what's in the file; Telescope answers which request made it. Document both in the runbook so nobody treats the viewer as a substitute.

Give support a curated path. Once the Gate exists, a second role that can view but not download or delete is a cheap self-serve win — support triages "known 500, fix ships Thursday" without paging on-call. Write down two or three named searches (by order ID, by email, by route) so non-engineers aren't guessing at a syntax the tool doesn't implement.

Treat nova:publish as a deploy step. CI's composer install won't republish the Vue bundle. Put php artisan nova:publish in the pipeline or your next deploy silently ships a blank/stale tool panel.

Pin, name an owner, budget a fork. "php-junior/nova-logs": "1.x.x" in composer.json with composer.lock committed, a named engineer, and a fork branch you can patch. Quarterly composer audit. Single maintainer, zero dependents, no vendor, no SLA — assume you own the code the day you install it.

Gotchas and Tips

Parsing happens in-request. No streaming, no index. A 100MB laravel.log can blow memory_limit or hit the gateway timeout and take down the Nova route precisely when you need it mid-incident. Test against a production-sized file in staging, and cap file size independently via your channel config.

Multi-node coverage is silently partial. In containers or an autoscaling group, storage/logs is per-instance and ephemeral. A viewer showing you one node's logs during an incident is worse than no viewer, because operators will trust it and stop looking elsewhere. Past one app server, centralise instead — Sentry, Datadog, Loki/ELK, or at minimum opcodesio/log-viewer for local dev.

Composer resolution failures against laravel/nova are auth problems, not package bugs. Check auth.json / COMPOSER_AUTH for the private Nova repo credentials before debugging the package.

"Permission denied" usually means rotation touched ownership. Logs written by www-data (web) and by the deploy user (queue workers, artisan) can end up with different owners and modes. ls -l storage/logs before you blame config.

Verify path traversal is impossible. If file selection or the log path is influenced by request input at all, read the serving code and confirm it resolves against a fixed base directory. This is the one thing worth a written note in your PR.

Deleting the active log file misleads you. The writing process holds the handle; the file may appear gone or empty until the next write recreates it. Confusing mid-incident. Prefer channel-based rotation; if you allow deletion at all, restrict it to archived files.

Logs are not scrubbed by the viewer — and the viewer widens the audience. Stack traces leak .env values, DSNs, bearer tokens, PII. That's a log-hygiene problem, but the tool converts "someone with shell access" exposure into "anyone with a Nova login" exposure. Review what you log before you widen who can see it.

Test the search behaviour once, explicitly. Literal, likely case-sensitive, no regex. Run a known token through it and record the result, so you don't promise support a query syntax that doesn't exist.

Timezone drift will cost you fifteen minutes of the wrong window. Laravel log timestamps vs. app timezone vs. server timezone vs. the customer's reported time. Establish which one you're reading on the first incident, not the third.

Fork deliberately rather than reactively. The codebase is small enough that redaction, an audit table of who viewed what, or a hard file-size cap is roughly a day of work. Decide up front whether you need those, instead of discovering it the week Nova 5 lands and the package doesn't follow.

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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource