Skip to content

Commit 57bdec5

Browse files
committed
Trace: Updated Tracing & Added Documentation #25
1 parent 7e43690 commit 57bdec5

File tree

7 files changed

+161
-21
lines changed

7 files changed

+161
-21
lines changed

docs/trace.md

Lines changed: 105 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,125 @@
1-
## StackDriver Trace Support
1+
# StackDriver Trace Integration
22

33
This package includes built in support for tracing important components to StackDriver Trace.
44

55
By default, this includes:
66
* Laravel startup
7+
* (currently doesn't render in the tree view properly)
78
* Laravel internals (including more granular startup).
89
* Application construct
910
* Request capture
1011
* Request handle
1112
* Response send
1213
* Request terminate (cleanup)
1314
* Application specific
14-
* Middleware
15+
* (soon) Middleware
1516
* Time in Router
1617
* Controller / Route-Closure Runtime
1718
* Blade view compile/render
1819
* External calls / RPC
1920
* memcached
20-
* redis
21+
* (soon) redis
2122
* MySQL
2223
* PDO
2324
* 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.

src/A1comms/GaeSupportLaravel/Trace/Integration/LaravelExtended.php renamed to src/A1comms/GaeSupportLaravel/Trace/Integration/LowLevel/LaravelExtended.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
namespace A1comms\GaeSupportLaravel\Trace\Integration;
3+
namespace A1comms\GaeSupportLaravel\Trace\Integration\LowLevel;
44

55
use OpenCensus\Trace\Integrations\IntegrationInterface;
66
use Illuminate\Foundation\Application as LaravelApplication;
@@ -35,7 +35,7 @@ public static function load()
3535
opencensus_trace_method(LaravelResponse::class, 'send', [self::class, 'handleResponseSend']);
3636
// TODO: Eventually we want to be able to remove this,
3737
// the "send" method in "LaravelResponse" is inherited from "BaseResponse"
38-
// but unfortunately the opensensus extension doesn't trigger for inherited methods.
38+
// but unfortunately the OpenCensus extension doesn't trigger for inherited methods.
3939
// https://github.com/census-instrumentation/opencensus-php/issues/201
4040
opencensus_trace_method(BaseResponse::class, 'send', [self::class, 'handleResponseSend']);
4141

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace A1comms\GaeSupportLaravel\Trace;
4+
5+
/**
6+
* Class to return the low level trace modules to load.
7+
*/
8+
class LowLevelLoader implements LowLevelLoaderInterface
9+
{
10+
/**
11+
* Static method to get the list of trace modules to load.
12+
13+
*/
14+
public static function getList()
15+
{
16+
return [
17+
// OpenCensus provides a basic Laravel trace adapter,
18+
// which covered Eloquent and view compilation.
19+
OpenCensus\Trace\Integrations\Laravel::class,
20+
// Also load our own extended Laravel trace set.
21+
A1comms\GaeSupportLaravel\Trace\Integration\LowLevel\LaravelExtended::class,
22+
// Trace our other basic functions...
23+
OpenCensus\Trace\Integrations\Mysql::class,
24+
OpenCensus\Trace\Integrations\PDO::class,
25+
OpenCensus\Trace\Integrations\Memcached::class,
26+
];
27+
}
28+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace A1comms\GaeSupportLaravel\Trace;
4+
5+
/**
6+
* Interface to implement for loading your own list
7+
* of low level trace modules.
8+
*/
9+
interface LowLevelLoaderInterface
10+
{
11+
/**
12+
* Static method to get the list of trace modules to load.
13+
*
14+
* For an example, see the default at LowLevelLoader.
15+
*/
16+
public static function getList();
17+
}

src/A1comms/GaeSupportLaravel/Trace/TraceServiceProvider.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public function boot()
1515

1616
// Create a span that starts from when Laravel first boots (public/index.php)
1717
// ---
18-
// TODO: Set parentSpanId to the rootSpan->spanId() from OpenSensus,
18+
// TODO: Set parentSpanId to the rootSpan->spanId() from OpenCensus,
1919
// to help it merge properly in the tree view.
2020
// Need to wait for rootSpan visibility to be changed to public.
2121
// https://github.com/census-instrumentation/opencensus-php/issues/199

src/config/gaesupport.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
|--------------------------------------------------------------------------
99
|
1010
| This is an array of classes to register for the StackDriver Trace integration,
11-
| defining runtime trace hooks via the opensensus PECL module,
11+
| defining runtime trace hooks via the OpenCensus PECL module,
1212
| so code changes inside the application aren't required.
1313
|
1414
| These should implement OpenCensus\Trace\Integrations\IntegrationInterface

src/preload.php

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,13 @@
1313
Tracer::start(new StackdriverExporter());
1414
}
1515

16-
// TODO: Different arrays for Laravel vs Lumen?
17-
$traceProviders = [
18-
// OpenSensus provides a basic Laravel trace adapter,
19-
// which covered Eloquent and view compilation.
20-
OpenCensus\Trace\Integrations\Laravel::class,
21-
// Also load our own extended Laravel trace set.
22-
A1comms\GaeSupportLaravel\Trace\Integration\LaravelExtended::class,
23-
// Trace our other basic functions...
24-
OpenCensus\Trace\Integrations\Mysql::class,
25-
OpenCensus\Trace\Integrations\PDO::class,
26-
OpenCensus\Trace\Integrations\Memcached::class,
27-
];
16+
$loaderInterface = 'App\\Trace\\LowLevelLoader';
17+
if (!class_exists($loaderInterface))
18+
{
19+
// TODO: Different default arrays for Laravel vs Lumen?
20+
$loaderInterface = A1comms\GaeSupportLaravel\Trace\LowLevelLoader::class;
21+
}
22+
$traceProviders = $loaderInterface::getList();
2823

2924
foreach ($traceProviders as $p) {
3025
$p::load();

0 commit comments

Comments
 (0)