Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save esilvajr/9ded67cce1f9d23c540bbce337b1f993 to your computer and use it in GitHub Desktop.
Save esilvajr/9ded67cce1f9d23c540bbce337b1f993 to your computer and use it in GitHub Desktop.

Lumen and naming transactions into NewRelic

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:

  1. Fill in routes.php with appropriated data (see example above)
  2. 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.

  1. Create LumenNewrelicMiddleware in appropriated place (usually it's App\Http\Middleware folder)
  2. 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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment