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

Laravel Tracer Laravel Package

protonemedia/laravel-tracer

Laravel Tracer wraps every rendered Blade view in HTML comments showing that view's path, so you can inspect the page source in your browser and instantly find the template responsible for any markup. A small, handy debugging aid for apps with deeply nested views.

View on GitHub
Deep Wiki
Context7

Getting Started

Know what you're adopting first. protonemedia/laravel-tracer is an archived, single-purpose debugging package (4 stars, no dependents). The newest tag, v0.3.3, is a platform-support bump only — PHP 8.1 + Laravel 9 — with no feature or API changes, so nothing about how you use it has changed. It is not infrastructure you build on — it's a temporary instrument you install, point at a misbehaving model, and remove.

The v0.3.3 bump matters for one reason: it tells you exactly where the ceiling is. You can install cleanly on Laravel 9 / PHP 8.1+. You cannot on Laravel 10/11 — expect a composer.json constraint override, --ignore-platform-reqs, or a fork. And the PHP 8.1 floor means it won't go near an 8.0 app at all. If you're on L10+, budget for the fork before you start, and read the release note as "this is as far as it goes," not "maintenance resumed."

Minimal steps:

composer require protonemedia/laravel-tracer --dev
php artisan vendor:publish   # pick the Tracer provider from the list
php artisan migrate          # creates the tracer/audit table

Then look at, in this order:

  1. config/tracer.php — this is the whole package. It controls which models/events are recorded and what context is captured. Everything you'll actually tune lives here.
  2. The published migration — read the columns. They tell you exactly what you get back out (event name, model type/id, attribute diff, and — the point of the package — a trace of the code path that fired the event).
  3. The package's own model class — query it directly (Tracer::latest()->first()) rather than building a UI.

First use case: "Something is silently updating orders.status and nobody knows how." Enable tracing for that one model, reproduce the flow in local or staging, then read the newest rows: you get the event, the before/after attributes, and the file/line or stack that caused it. That is the entire value proposition — it answers where did this write come from, which neither laravel/telescope nor a plain observer answers cleanly.

If the constraint fight isn't worth it, the fallback is ~15 lines in a service provider (Model::updated(fn ($m) => Log::debug(class($m), ['trace' => debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 15)])) and you've reproduced 80% of the package. On L10/11 that fallback is usually the better trade — the v0.3.3 release note is a strong signal there won't be a v0.4 to save you.

Implementation Patterns

Scope it to one model, one environment. Tracing everything is how you take down a staging server. Turn it on per-model, and gate it behind an env flag so it can never accidentally run in production:

// config/tracer.php (shape per README)
'enabled' => env('TRACER_ENABLED', false),
'models'  => [\App\Models\Order::class],

Debug workflow that actually works:

  1. Reproduce the bug once with tracing enabled — one reproduction is enough; you're hunting a code path, not sampling.
  2. Query the newest rows for that model, ordered by id descending.
  3. Read the trace top-down until you hit your own App\ namespace frame — that frame is the culprit; everything below it is framework noise.
  4. Disable tracing, add a regression test that asserts the unwanted write no longer happens, then delete the package.

Pair it with a failing test, not with manual clicking. The trace tells you the origin; a test (Event::fake() / assertDatabaseHas) is what stops it coming back. The package is a diagnostic, not a safety net.

Use it to find hidden writers, which are usually one of: an observer/listener, a queued job replaying an old payload, a saving hook on a parent model, or a package (cashier, auditing, search indexers) touching attributes you didn't expect. Each of those shows up as a distinct trace shape — jobs tend to be short traces ending in CallQueuedHandler, observers end in your App\Observers\* file.

Complement, don't duplicate, your audit log. If you need permanent history (who changed what, shown to users), use owen-it/laravel-auditing or spatie/activitylog. Use tracer purely for the stack-trace dimension during a debugging session. Don't leave tracer enabled as a permanent audit trail — the table grows on every write and the trace payloads are bulky.

Truncate aggressively. Treat the table as scratch space: DB::table('tracers')->truncate() between reproductions, otherwise you're scrolling through your own noise.

Gotchas and Tips

  • Archived and effectively capped. v0.3.3 targets PHP 8.1 / Laravel 9 and there's no indication of L10/11 support. Pin the version, or fork it and fix the composer.json constraints yourself. Don't let it into a dependency graph you don't control.
  • PHP 8.1 is a hard floor. On 8.0 and below the package simply won't resolve. That's rarely the blocker in 2024, but it's the first thing to check if composer require fails before you start blaming Laravel constraints.
  • It only sees Eloquent events. Model::where(...)->update([...]), raw DB::update(), and bulk upserts fire nothing, so they produce no traces. If your mystery write is a mass update, tracer will look broken when it isn't. Reach for DB::listen() or MySQL's general log in that case.
  • saveQuietly(), withoutEvents(), and Model::withoutEvents() likewise bypass it — and are a common reason a row "changes by itself."
  • debug_backtrace() is expensive. Even scoped to one model, don't enable it on a hot write path in a load test and conclude your app got slower.
  • Transactions. If the tracer write shares your DB connection and the transaction rolls back, your trace disappears with it — precisely when you most want it. Check whether the package uses its own connection or queues the write; if not, reproduce outside a transaction or log to a file instead.
  • Recursion. If tracer itself dispatches model events (it has its own model), guard against tracing the tracer. Usually the package handles this, but verify by checking the row count doesn't explode after one save.
  • PII. Attribute diffs will capture emails, tokens, addresses, and remember_token-style columns verbatim. Never paste a full row into a ticket or a public Slack channel.
  • php artisan config:cache after every config edit — a stale cached config is the #1 cause of "I enabled it and nothing happened."
  • Silent no-op checklist when no rows appear: config cached, enabled false, model not listed, events disabled at the call site, or the write wasn't Eloquent.
  • Extension points are thin — realistically just swapping the published model/table name and adding your own columns to the migration. If you find yourself wanting more (retention policies, sampling, per-user context), that's the signal to fork or replace it with a 20-line observer you own.
  • Verdict for day-to-day use: still a one-off forensic tool, dev-dependency only, with a short expiry date. v0.3.3 improves installability on L9/PHP 8.1 but confirms the package has no forward path — which makes owning the equivalent ~15 lines yourself a more attractive trade than it was before, not less. Keep it in the toolbox only if you're on L9 today.
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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core