|
1 |
| -## StackDriver Trace Support |
| 1 | +# StackDriver Trace Integration |
2 | 2 |
|
3 | 3 | This package includes built in support for tracing important components to StackDriver Trace.
|
4 | 4 |
|
5 | 5 | By default, this includes:
|
6 | 6 | * Laravel startup
|
| 7 | + * (currently doesn't render in the tree view properly) |
7 | 8 | * Laravel internals (including more granular startup).
|
8 | 9 | * Application construct
|
9 | 10 | * Request capture
|
10 | 11 | * Request handle
|
11 | 12 | * Response send
|
12 | 13 | * Request terminate (cleanup)
|
13 | 14 | * Application specific
|
14 |
| - * Middleware |
| 15 | + * (soon) Middleware |
15 | 16 | * Time in Router
|
16 | 17 | * Controller / Route-Closure Runtime
|
17 | 18 | * Blade view compile/render
|
18 | 19 | * External calls / RPC
|
19 | 20 | * memcached
|
20 |
| - * redis |
| 21 | + * (soon) redis |
21 | 22 | * MySQL
|
22 | 23 | * PDO
|
23 | 24 | * Eloquent (Laravel)
|
24 |
| - * Datastore |
25 |
| - * Guzzle (HTTP(s)) |
| 25 | + * (soon) Datastore |
| 26 | + * (soon) Guzzle (HTTP(s)) |
| 27 | + |
| 28 | +It also allows you to register your own trace providers to be registered as the application boots, via the config file for this package (`trace_providers` in `gaesupport.php`). |
| 29 | + |
| 30 | +## Architecture |
| 31 | +There are two different levels of trace integration: |
| 32 | + |
| 33 | +* Low Level (to catch Laravel core boot) |
| 34 | +* Higher level (via Service Provider) |
| 35 | + |
| 36 | +All of the trace providers at all levels should implement the interface `OpenCensus\Trace\Integrations\IntegrationInterface`, which providers a static `load` method where the trace hooks are registered. |
| 37 | + |
| 38 | +### Low level |
| 39 | +To allow us to capture the startup of Laravel in more detail and to make sure the core is ready to be traced before any of it runs, we set up the OpenCensus trace library and register some trace hooks before loading Laravel. |
| 40 | + |
| 41 | +We do this by asking composer to include `src/preload.php` once it has set up the autoloader, the same way helper functions are initialised. |
| 42 | + |
| 43 | +`src/preload.php` will first include `src/helpers.php` to register our helper functions (which is done because composer can't guarantee load order if we specify an array of files to load in `composer.json` and we need our helper functions before the preload functions run). |
| 44 | + |
| 45 | +By default, the list of low level providers is provided by calling `A1comms\GaeSupportLaravel\Trace\LowLevelLoader`, but this can be overridden by creating your own `LowLevelLoader` that implements `A1comms\GaeSupportLaravel\Trace\LowLevelLoaderInterface` at `App\Trace\LowLevelLoader`, which we check for before loading the default. |
| 46 | + |
| 47 | +Example `app/Trace/LowLevelLoader.php` that just loads `Memcached` tracing: |
| 48 | + |
| 49 | +```php |
| 50 | +<?php |
| 51 | + |
| 52 | +namespace App\Trace; |
| 53 | + |
| 54 | +use A1comms\GaeSupportLaravel\Trace\LowLevelLoaderInterface; |
| 55 | + |
| 56 | +class LowLevelLoader implements LowLevelLoaderInterface |
| 57 | +{ |
| 58 | + public static function getList() |
| 59 | + { |
| 60 | + return [ |
| 61 | + OpenCensus\Trace\Integrations\Memcached::class, |
| 62 | + ]; |
| 63 | + } |
| 64 | +} |
| 65 | +``` |
| 66 | + |
| 67 | +### Higher Level |
| 68 | +For trace providers that can be registered after Laravel has loaded and during the service provider boot, when other service providers may already be running, we can register them via the `TraceServiceProvider` and have Laravel functionality available if required. |
| 69 | + |
| 70 | +Firstly, the `TraceServiceProvider` will register an event for `laravel/boostrap`, with a start time set to `LARAVEL_START` as set in the top of `public/index.php`, to document the point in execution when it was run, as an indication of when Laravel finished loading. |
| 71 | + |
| 72 | +Next, it will look in the application config for our service (`gaesupport.php`) and run the `load` function for any classes listed in the `trace_providers` array, allowing you to add trace hooks for your own application. |
| 73 | + |
| 74 | +As an example, to trace the `enqueue` function of a model class `CustomQueue`, I'd start by creating the file `app/Trace/CustomQueueModel.php` with the contents: |
| 75 | + |
| 76 | +```php |
| 77 | +<?php |
| 78 | + |
| 79 | +namespace App\Trace; |
| 80 | + |
| 81 | +use OpenCensus\Trace\Integrations\IntegrationInterface; |
| 82 | +use App\CustomQueue; |
| 83 | + |
| 84 | +class CustomQueueModel implements IntegrationInterface |
| 85 | +{ |
| 86 | + public static function load() |
| 87 | + { |
| 88 | + if (!extension_loaded('opencensus')) { |
| 89 | + trigger_error('opencensus extension required to load Laravel integrations.', E_USER_WARNING); |
| 90 | + return; |
| 91 | + } |
| 92 | + |
| 93 | + opencensus_trace_method(CustomQueue::class, 'enqueue', [self::class, 'handleEnqueue']); |
| 94 | + } |
| 95 | + |
| 96 | + public static function handleResponseSend($scope, $job) |
| 97 | + { |
| 98 | + return [ |
| 99 | + 'name' => 'model/CustomQueue/enqueue', |
| 100 | + 'attributes' => [ |
| 101 | + 'job' => $job, |
| 102 | + ] |
| 103 | + ]; |
| 104 | + } |
| 105 | +} |
| 106 | +``` |
| 107 | + |
| 108 | +To note here is the importance of the parameters passed to the callback function, with the first being the instance of the class as it was called, then all of the parameters to the function as it was called. |
| 109 | + |
| 110 | +For more information, see the OpenCensus PECL extension documentation. |
| 111 | + |
| 112 | +https://github.com/census-instrumentation/opencensus-php/blob/master/docs/content/using-the-extension.md |
| 113 | + |
| 114 | +Next, update your `gaesupport.php` configuration file to include that trace provider into the array: |
| 115 | + |
| 116 | +```php |
| 117 | + 'trace_providers' => [ |
| 118 | + App\Trace\CustomQueueModel:class, |
| 119 | + ], |
| 120 | +``` |
| 121 | + |
| 122 | +## Installation |
| 123 | +Since the low level trace setup is done as part of the composer autoloader initialisation, most of the installation is taken care of once you've installed the package, although for the higher level & custom trace providers, you'll need to make sure the `GaeSupportServiceProvider` and `TraceServiceProvider` are both loaded into Laravel. |
| 124 | + |
| 125 | +In Laravel 5.5, service providers are automatically discovered by default, so unless you've disabled this functionality, you shouldn't need to do anything else either. |
0 commit comments