intouch/laravel-newrelic
intouch/laravel-newrelic integrates New Relic APM with Laravel, providing transaction, exception, query, and job monitoring out of the box. Configure custom instrumentation and metrics with minimal setup for clearer production performance insights.
Install:
composer require intouch/laravel-newrelic
Register (pre-Laravel 5.5): add the service provider and facade to config/app.php:
InTouch\LaravelNewrelic\Providers\NewRelicServiceProvider::class,
'aliases' => [
'NewRelic' => InTouch\LaravelNewrelic\Facades\NewRelic::class,
],
On Laravel 5.5–Laravel 7 it auto-discovers; verify the provider actually loads on your version (see Gotchas — the last release is from 2019).
Prerequisite: the NewRelic PHP agent extension must be installed on the server (newrelic.so). The package is a thin wrapper — without the extension loaded, calls silently no-op. Confirm with:
php -m | grep newrelic
Where to look first: read the package's NewRelic class source (usually src/NewRelic.php) — it's short and simply proxies the newrelic_* PHP functions. That class defines the full API surface you'll call through the facade.
First use case: drop an error notice into Laravel's exception reporter so production exceptions show up in APM:
// app/Exceptions/Handler.php
public function report(Exception $e)
{
\NewRelic::noticeError($e);
parent::report($e);
}
Then wrap one expensive operation in a custom tracer and confirm it appears in the NewRelic APM "Transactions" view — that's the fastest way to verify the wiring is actually working.
Naming transactions via middleware. The most valuable day-to-day integration is meaningful transaction names — otherwise NewRelic groups everything as /{route} or cli. Register a middleware that calls NewRelic::nameTransaction() with a route-aware name and place it early in the web/api stack.
Custom tracers around known-slow work. Wrap external API clients, report generators, or anything you can't see as a SQL/Redis segment:
NewRelic::addCustomTracer('Report:Generate', function () use ($request) {
return $this->generator->run($request);
});
Custom events for business metrics. Use NewRelic::recordCustomEvent('OrderPlaced', ['value' => $order->total]) in domain events — these feed NewRelic's NRQL dashboards without you having to write log parsing.
Queue/Artisan instrumentation. Long-running queue workers hold one transaction per worker process by default, which makes NewRelic useless for jobs. In queue jobs, open a named transaction per job (or wrap handle()), and end it in a finally. For Artisan commands, set the app name / transaction name at command start so they don't collide with cli aggregates.
Enriching transactions. Use NewRelic::addCustomParameter($key, $value) in middleware or jobs to attach user IDs, tenant IDs, or feature flags — these become filterable attributes in the APM UI.
Integration tip: don't duplicate work. If your newrelic.ini already enables auto-instrumentation of Laravel/PDO, this package is what adds business-level context on top — custom parameters, custom events, transaction naming, and explicit error notices. Reach for it when auto-instrumentation is too coarse.
composer.json constraints may not include laravel/framework ^8|^9|^10, and auto-discovery may not be present. Expect to fork/bump or --ignore-platform-reqs if you're on a modern Laravel. Check composer.json before installing on Laravel 8+.abort_unless(extension_loaded('newrelic'), 'NewRelic agent not loaded') on boot.newrelic.ini newrelic.appname wins over per-request setAppName unless you explicitly call setAppName with license key. Prefer configuring app name in newrelic.ini (or the agent env vars) — per-request overrides are easy to get inconsistent across web/queue/CLI.laravel auto-instrumentation if you have it) already report exceptions — calling noticeError() yourself can produce duplicates. Confirm whether exceptions appear twice before adding your own handler.recordCustomEvent is sampled (default ~10k/60s window). Don't build billing or audit logic on top of it — treat it as observability data, not a durable store.finally.$this->app->bind(NewRelic::class, NoopNewRelic::class);
so test suites don't hit the extension (or fail when it's absent).newrelic_* function. When you need something the package doesn't expose (agent status, distributed tracing headers), don't fight it — call the underlying newrelic_* function directly, or extend the facade.How can I help you explore Laravel packages today?