From d87616972907c1b835fdbfef74554bca5d4a6452 Mon Sep 17 00:00:00 2001 From: macbre Date: Thu, 9 Jan 2020 10:26:00 +0100 Subject: [PATCH 1/4] IT-2038 | initial commit for transactions sampling --- README.md | 1 + config/elastic-apm.php | 3 +++ src/Providers/ElasticApmServiceProvider.php | 6 ++++++ 3 files changed, 10 insertions(+) diff --git a/README.md b/README.md index d411126..485e171 100644 --- a/README.md +++ b/README.md @@ -115,6 +115,7 @@ The following environment variables are supported in the default configuration: |APM_BACKTRACEDEPTH | Defaults to `25`. Depth of backtrace in query span. | |APM_RENDERSOURCE | Defaults to `true`. Include source code in query span. | |APM_HTTPLOG | Defaults to `true`. Will record HTTP requests performed via GuzzleHttp. | +|APM_SAMPLING | Defaults to `100`. Sets the percentage of transactions that will be reported to APM (ranges from 0 to 100). You may also publish the `elastic-apm.php` configuration file to change additional settings: diff --git a/config/elastic-apm.php b/config/elastic-apm.php index a1be827..afc8e7f 100644 --- a/config/elastic-apm.php +++ b/config/elastic-apm.php @@ -4,6 +4,9 @@ // Sets whether the apm reporting should be active or not 'active' => env('APM_ACTIVE', true), + // Applies sampling of transactions to be reported to APM, defaults to 100% + 'sampling' => env('APM_SAMPLING', 100), + 'app' => [ // The app name that will identify your app in Kibana / Elastic APM 'appName' => env('APM_APPNAME', 'Laravel'), diff --git a/src/Providers/ElasticApmServiceProvider.php b/src/Providers/ElasticApmServiceProvider.php index 46991b3..acb821e 100644 --- a/src/Providers/ElasticApmServiceProvider.php +++ b/src/Providers/ElasticApmServiceProvider.php @@ -28,6 +28,9 @@ class ElasticApmServiceProvider extends ServiceProvider /** @var float */ private static $lastHttpRequestStart; + /** @var bool */ + private static $isSampled = true; + /** * Bootstrap the application services. * @@ -89,6 +92,9 @@ public function register() $this->app->alias(Agent::class, 'elastic-apm'); $this->app->instance('apm-spans-log', $collection); + // apply transactions reporting sampling + $samplingRate = intval(config('elastic-apm.sampling')) ?: 100; + self::$isSampled = $samplingRate > mt_rand(0, 100); } /** From 00854356cfee67732f6e7d9b99ea6dba8f3cad10 Mon Sep 17 00:00:00 2001 From: macbre Date: Thu, 9 Jan 2020 11:26:42 +0100 Subject: [PATCH 2/4] ElasticApmServiceProvider: make APM inactive when sampling is not enabled --- src/Providers/ElasticApmServiceProvider.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Providers/ElasticApmServiceProvider.php b/src/Providers/ElasticApmServiceProvider.php index acb821e..92a8182 100644 --- a/src/Providers/ElasticApmServiceProvider.php +++ b/src/Providers/ElasticApmServiceProvider.php @@ -62,6 +62,10 @@ public function register() 'elastic-apm' ); + // apply transactions reporting sampling + $samplingRate = intval(config('elastic-apm.sampling')) ?: 100; + self::$isSampled = $samplingRate > mt_rand(0, 100); + $this->app->singleton(Agent::class, function ($app) { return new Agent( array_merge( @@ -70,7 +74,7 @@ public function register() 'frameworkVersion' => app()->version(), ], [ - 'active' => config('elastic-apm.active'), + 'active' => config('elastic-apm.active') && self::$isSampled, 'httpClient' => config('elastic-apm.httpClient'), ], $this->getAppConfig(), @@ -91,10 +95,6 @@ public function register() $this->app->alias(Agent::class, 'elastic-apm'); $this->app->instance('apm-spans-log', $collection); - - // apply transactions reporting sampling - $samplingRate = intval(config('elastic-apm.sampling')) ?: 100; - self::$isSampled = $samplingRate > mt_rand(0, 100); } /** From 1935cc5fad2db71c9bc647da7caf9068dd5123c7 Mon Sep 17 00:00:00 2001 From: macbre Date: Thu, 9 Jan 2020 11:32:03 +0100 Subject: [PATCH 3/4] ElasticApmServiceProvider: do not register database query and HTTP request spans when the current transaction is not sampled --- src/Providers/ElasticApmServiceProvider.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Providers/ElasticApmServiceProvider.php b/src/Providers/ElasticApmServiceProvider.php index 92a8182..97c669c 100644 --- a/src/Providers/ElasticApmServiceProvider.php +++ b/src/Providers/ElasticApmServiceProvider.php @@ -44,7 +44,7 @@ public function boot() ], 'config'); } - if (config('elastic-apm.active') === true && config('elastic-apm.spans.querylog.enabled') !== false) { + if (config('elastic-apm.active') === true && config('elastic-apm.spans.querylog.enabled') !== false && self::$isSampled) { $this->listenForQueries(); } } @@ -233,8 +233,8 @@ function(RequestInterface $request, array $options) { self::$lastHttpRequestStart = microtime(true); }, function (RequestInterface $request, array $options, PromiseInterface $promise) { - // leave early if monitoring is disabled - if (config('elastic-apm.active') !== true || config('elastic-apm.spans.httplog.enabled') !== true) { + // leave early if monitoring is disabled or when this transaction is not sampled + if (config('elastic-apm.active') !== true || config('elastic-apm.spans.httplog.enabled') !== true || !self::$isSampled) { return; } From 78e6f95b6f4b9f2254101d3421d03cf1bfaa63bb Mon Sep 17 00:00:00 2001 From: macbre Date: Thu, 9 Jan 2020 11:49:25 +0100 Subject: [PATCH 4/4] Update README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 485e171..b1e6a85 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ composer require bethinkpl/elastic-apm-laravel ## Additional features * `X-Requested-By` HTTP request header value is set as `labels.requested_by` APM transaction field (`end-user-ajax` value is used when `X-Requested-With: XMLHttpRequest` is set) +* sampling of transactions reported to APM * tracking of HTTP requests performed using GuzzleHttp library. Simply add the following middleware to your Guzzle client: ```php