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

Traceview Twig Laravel Package

appneta/traceview-twig

Twig extension for AppNeta TraceView that instruments template rendering, adding Twig template layers and render timings to PHP APM traces so you can see which templates are slow.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install the base instrumentation first. This package is only a Twig bridge; the actual tracing is done by the AppNeta TraceView PHP agent (a native traceview.so extension, not a Composer package). If the agent isn't loaded, appneta/traceview-twig will install and boot fine but emit nothing.

    composer require appneta/traceview-twig
    php -m | grep -i traceview   # must return the agent module
    
  2. Confirm your Twig stack. In Laravel this almost always means rcrowe/twigbridge. Check composer show | grep twig — this package predates Twig 3, so expect it to target Twig 1.x/2.x. Verify the constraint before you commit; a version conflict is the most likely reason you can't install it at all.

  3. Register the extension with the Twig environment. With TwigBridge, add the extension class to the extensions array in config/twigbridge.php:

    'extensions' => [
        // ...
        \AppNeta\TraceView\Twig\TraceViewExtension::class,
    ],
    

    If you build Twig manually, use $twig->addExtension(new TraceViewExtension()).

  4. Where to look first. Read the package's src/ for the extension class and any Twig_Extension/AbstractExtension subclass — that's the whole surface area. Then read the AppNeta PHP agent docs for layer naming and sampling, because that's where 90% of the actual behavior lives.

  5. First use case: open a page that renders several partials, and confirm in the TraceView UI that template rendering appears as a distinct layer/span under the request rather than being folded into generic PHP time. That single view — "which template is slow" — is the reason to install this.

Implementation Patterns

Instrument the render boundary, not every template. The useful signal is per-render (or per-partial) duration attributed to a named layer. Wrap your top-level render call so you get a span around the whole template, and let the extension handle the sub-template naming:

$html = traceview_wrap('twig.render', function () use ($twig, $name, $ctx) {
    return $twig->render($name, $ctx);
});

Use whatever the agent's actual span API is (check php -i | grep traceview for enabled functions); the shape above is the pattern, not literal API.

Name layers after the template, not after the controller. A layer called twig:partials/nav aggregates across every page that includes the nav, which is what you want for spotting a globally slow partial. Controller-based names fragment the data.

Environment-gate registration. Register the extension only when the agent is loaded and you're in an environment worth tracing, so local dev and CI don't pay the overhead:

if (extension_loaded('traceview') && app()->environment(['production', 'staging'])) {
    $twig->addExtension(new TraceViewExtension());
}

Note that TwigBridge's extensions config is not conditional out of the box — you'll need a service provider or a TwigBridge::extend() call to do this cleanly.

Pair it with a request-level span. Traces are far more readable when the Twig layer sits inside an entry span tagged with route name and a user/tenant identifier. Add a middleware that opens the span and sets the context, then let the Twig extension nest underneath.

Use it to adjudicate the view-vs-query argument. The recurring workflow is: a page is slow, is it N+1 queries or a pathological template loop? Having Twig time as its own layer turns that from a guess into a measurement. Make it a habit to check the layer breakdown before profiling.

For long-running workers (Octane, queue consumers), confirm the agent supports the process model before relying on template spans there — a native extension that assumes per-request lifecycle can produce misleading traces in a persistent worker.

Gotchas and Tips

  • No agent, no data, no error. The failure mode is silence, not an exception. If you see nothing in TraceView, check extension_loaded('traceview') and the agent log before you touch the Twig config.
  • This package is effectively unmaintained. Zero stars and zero dependents means no compatibility work has happened for years. Treat it as a reference implementation of "how to instrument Twig" rather than a dependency you'll get support on. Read the source (it's small) and be prepared to fork it.
  • Twig 1.x/2.x assumptions. Class names like Twig_Extension vs Twig\Extension\AbstractExtension, and the getName() requirement, changed in Twig 2/3. Expect to shim these if you're on a modern Twig.
  • TwigBridge's extension list runs through the container in some versions, so a plain new TraceViewExtension() may fail if the class has constructor dependencies — resolve via app() or register a binding.
  • Watch the overhead in hot loops. If the extension instruments every {% include %}, a page with hundreds of small partials generates a lot of spans. Enable sampling in the agent and check that p99 request latency hasn't moved after rollout.
  • AppNeta TraceView itself is a sunset product (the line was folded into SolarWinds after acquisition). Long-term, the OpenTelemetry PHP SDK plus a Twig decorator gives you the same layer data with a live ecosystem. Use this package as the template for that decorator if you migrate.
  • Debugging tip: log the extension's registration and layer names at boot in staging. Half the "it's not working" cases are the extension never being added to the environment that actually serves traffic.
  • Extension points worth knowing: the Twig extension itself (add your own span around render()), TwigBridge's TwigBridge::extend() hook (conditional registration), and the agent's custom-layer API if this package's naming doesn't match your conventions.
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.
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels