Problem: How to build transaction name for NewRelic in Lumen.
Description: NewRelic tries to group similar transaction into group, to be able easier watch for them later on Extra-Problem: NewRelic has an issue and becuase of that they can not group following transactions:
- /orders/zzZfN0kZ6F1PtFdQ4Baq
- /orders/aaZDd0k43D1GtFeG5cCe ...
In the same time
- /users/75
- /users/32
Will be automatically grouped into one /users/*
Decision: It means we need to be able call our transactions like we want. Solution: Start using router for this purpose, by adding extra element into array argument:
$app->get('profile', [
'as' => 'profile',
'uses' => 'UserController@showProfile',
'transaction' => 'MyCoolTransactionName' // you can call that array element like you want
]);
Implementation:
- Fill in routes.php with appropriated data (see example above)
- Then put into your
CoolController::__construct
method following code:
$this->middleware(
LumenNewrelicMiddleware::class
);
Q:
Why we need to register middleware here and not in app.php?
A:
In time when global middlewares (registered via app.php) handle current request, Lumen knows nothing about current route yet.
- Create LumenNewrelicMiddleware in appropriated place (usually it's
App\Http\Middleware
folder) - Put into that file following code:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class LumenNewrelicMiddleware
{
public function handle(Request $request, Closure $next)
{
$config = app('config');
if (true === $config->get('newrelic.auto_name_transactions')) {
app('newrelic')->nameTransaction($this->getTransactionName());
}
$response = $next($request);
return $response;
}
/**
* Build the transaction name
*
* @return string
*/
public function getTransactionName()
{
$currenRoute = call_user_func(app('request')->getRouteResolver());
$method = app('request')->getMethod();
$path = app('request')->getPathInfo();
if (isset($currenRoute[1]['transaction'])) {
$path = $currenRoute[1]['transaction'];
}
$name = str_replace(
[
'{method}',
'{path}',
'{uri}',
],
[
$method,
$path,
app('request')->getUri(),
],
app('config')->get('newrelic.name_provider')
);
\Log::debug('Transaction name: ' . $name);
return $name;
}
}
As you saw it here: app('request')->getRouteResolver()
, It's a Closure where Lumen keeps appropriated section from the routes.php
configuration file.
Have fun!