Lookout
000 015 030 045 060 075 090 105 120 135 150 165 180 195 210 225 240 255 270 285 300 315 330 345 360
2 min read Tom Shafer

Tracing Blade views (and the anonymous-component fix)

Adding a view.render span collector to the tracing SDK so Blade templates show up as traced operations — plus the 1.2.1 and 1.3.0 fixes it took to get right.

Three SDK releases in one day — lookout/tracing 1.2.0, 1.2.1, and 1.3.0 — all chasing one feature: the Views watcher.

The idea

A request trace already shows controllers, queries, cache, and HTTP calls. What was missing: where the rendering time goes. Blade templates can be a surprising chunk of a slow request — a deeply nested partial, an N+1 hiding inside a @foreach that lazy-loads a relation per row. So I added a view.render span collector: every Blade view becomes a traced operation with its name and duration.

Why it took three releases

Shipping a collector is easy. Shipping a correct one is three releases:

  • 1.2.0 — the collector itself, hooking Laravel's view events to open/close a view.render span per template.
  • 1.2.1Fix view collector registration. The collector wasn't registering reliably depending on boot order. Instrumentation that only sometimes runs is worse than none — it makes the data lie. Fixed the registration so it's deterministic.
  • 1.3.0Record anonymous Blade components in view collector. Anonymous components (`<section class="@container flex flex-col p-3 sm:p-6 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 rounded-xl shadow-sm ring-1 ring-gray-900/5 default:col-span-full default:lg:col-span-6 default:row-span-1" x-data="{ loading: false, init() { } }"
` with no class) don't fire the same events as regular views, so they were invisible — exactly the lightweight, heavily-reused components you'd want to see. 1.3.0 catches them too.

The lesson

Instrumentation has a brutal correctness bar. A dashboard widget can be slightly wrong and you shrug. But if your tracing is wrong — missing spans, double-counting, registering half the time — it actively misleads you during the one moment you're relying on it: an incident. "Mostly works" isn't a passing grade for a collector.

That's why each fix shipped as its own release with its own version bump. The release tracking I'd just added made that painless.

Next session: an operator admin panel so I can actually support the people using this.

build-in-public tracing laravel blade