Skip to content
This repository was archived by the owner on Oct 3, 2023. It is now read-only.

Commit d685620

Browse files
authored
Fix Guzzle integrations (#104)
* Add tests for guzzle integrations * Add phpdoc for skipReporting option
1 parent 82d1dea commit d685620

10 files changed

Lines changed: 191 additions & 14 deletions

File tree

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
"squizlabs/php_codesniffer": "2.*",
2323
"google/cloud-trace": "^0.4",
2424
"twig/twig": "~2.0",
25-
"symfony/yaml": "~3.3"
25+
"symfony/yaml": "~3.3",
26+
"guzzlehttp/guzzle": "~5.3"
2627
},
2728
"conflict": {
2829
"ext-opencensus": "< 0.1.0"

src/Trace/Integrations/Guzzle/EventSubscriber.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ public function getEvents()
8585
public function onBefore(BeforeEvent $event)
8686
{
8787
$request = $event->getRequest();
88-
if ($context = Tracer::context()) {
89-
$request->setHeader($this->propagator->key(), $this->propagator->formatter->serialize($context));
88+
if ($context = Tracer::spanContext()) {
89+
$request->setHeader($this->propagator->key(), $this->propagator->formatter()->serialize($context));
9090
}
9191
$span = Tracer::startSpan([
9292
'name' => 'GuzzleHttp::request',

src/Trace/Integrations/Guzzle/Middleware.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@
4141
*/
4242
class Middleware
4343
{
44-
const DEFAULT_HEADER_NAME = 'X-Cloud-Trace-Context';
45-
4644
/**
4745
* @var PropagatorInterface
4846
*/
@@ -69,7 +67,7 @@ public function __construct(PropagatorInterface $propagator = null)
6967
public function __invoke(callable $handler)
7068
{
7169
return function (RequestInterface $request, $options) use ($handler) {
72-
if ($context = Tracer::context()) {
70+
if ($context = Tracer::spanContext()) {
7371
$request = $request->withHeader(
7472
$this->propagator->key(),
7573
$this->propagator->formatter()->serialize($context)

src/Trace/Propagator/HttpHeaderPropagator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,6 @@ public function formatter()
9797
*/
9898
public function key()
9999
{
100-
return $this->header();
100+
return $this->header;
101101
}
102102
}

src/Trace/RequestHandler.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ class RequestHandler
6969
* for the other available options.
7070
*
7171
* @type array $headers Optional array of headers to use in place of $_SERVER
72+
* @type bool $skipReporting If true, skips registering of onExit handler.
7273
* }
7374
*/
7475
public function __construct(
@@ -111,7 +112,9 @@ public function __construct(
111112
$this->rootSpan = $this->tracer->startSpan($spanOptions);
112113
$this->scope = $this->tracer->withSpan($this->rootSpan);
113114

114-
register_shutdown_function([$this, 'onExit']);
115+
if (!array_key_exists('skipReporting', $options) || !$options['skipReporting']) {
116+
register_shutdown_function([$this, 'onExit']);
117+
}
115118
}
116119

117120
/**

src/Trace/Tracer.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,4 +225,14 @@ public static function addAttribute($attribute, $value, $options = [])
225225
{
226226
return self::$instance->addAttribute($attribute, $value, $options);
227227
}
228+
229+
/**
230+
* Returns the current span context.
231+
*
232+
* @return SpanContext
233+
*/
234+
public static function spanContext()
235+
{
236+
return self::$instance->tracer()->spanContext();
237+
}
228238
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
/**
3+
* Copyright 2018 OpenCensus Authors
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
namespace OpenCensus\Tests\Unit\Trace\Integrations\Guzzle;
19+
20+
use OpenCensus\Core\Context;
21+
use GuzzleHttp\Client;
22+
use GuzzleHttp\Subscriber\Mock;
23+
use GuzzleHttp\Subscriber\History;
24+
use GuzzleHttp\Message\Response;
25+
use OpenCensus\Trace\Tracer;
26+
use OpenCensus\Trace\Exporter\ExporterInterface;
27+
use OpenCensus\Trace\Integrations\Guzzle\EventSubscriber;
28+
use Prophecy\Argument;
29+
30+
/**
31+
* @group trace
32+
*/
33+
class EventSubscriberTest extends \PHPUnit_Framework_TestCase
34+
{
35+
private $exporter;
36+
37+
public function setUp()
38+
{
39+
$this->exporter = $this->prophesize(ExporterInterface::class);
40+
if (extension_loaded('opencensus')) {
41+
opencensus_trace_clear();
42+
} else {
43+
Context::reset();
44+
}
45+
}
46+
47+
public function testAddsSpanContextHeader()
48+
{
49+
$this->exporter->report(Argument::that(function ($tracer) {
50+
$spans = $tracer->spans();
51+
return count($spans) == 3 && $spans[2]->name() == 'GuzzleHttp::request';
52+
}))->shouldBeCalled();
53+
54+
$rt = Tracer::start($this->exporter->reveal(), [
55+
'skipReporting' => true
56+
]);
57+
58+
$client = new Client();
59+
$subscriber = new EventSubscriber();
60+
$history = new History();
61+
$mock = new Mock([
62+
new Response(200, ['X-Foo' => 'Bar'])
63+
]);
64+
65+
$client->getEmitter()->attach($mock);
66+
$client->getEmitter()->attach($history);
67+
$client->getEmitter()->attach($subscriber);
68+
69+
Tracer::inSpan(['name' => 'parentSpan', 'spanId' => '1234'], function () use ($client) {
70+
$client->get('/');
71+
});
72+
73+
$request = $history->getLastRequest();
74+
$headers = $request->getHeaders();
75+
$this->assertArrayHasKey('HTTP_X_CLOUD_TRACE_CONTEXT', $headers);
76+
$this->assertRegExp('/[0-9a-f]+\/4660;o=1/', $headers['HTTP_X_CLOUD_TRACE_CONTEXT'][0]);
77+
78+
$rt->onExit();
79+
}
80+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
/**
3+
* Copyright 2018 OpenCensus Authors
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
namespace OpenCensus\Tests\Unit\Trace\Integrations\Guzzle;
19+
20+
use OpenCensus\Core\Context;
21+
use OpenCensus\Trace\Tracer;
22+
use OpenCensus\Trace\Exporter\ExporterInterface;
23+
use OpenCensus\Trace\Integrations\Guzzle\Middleware;
24+
use Prophecy\Argument;
25+
use Psr\Http\Message\RequestInterface;
26+
use Psr\Http\Message\ResponseInterface;
27+
28+
/**
29+
* @group trace
30+
*/
31+
class MiddlewareTest extends \PHPUnit_Framework_TestCase
32+
{
33+
private $exporter;
34+
35+
public function setUp()
36+
{
37+
$this->exporter = $this->prophesize(ExporterInterface::class);
38+
if (extension_loaded('opencensus')) {
39+
opencensus_trace_clear();
40+
} else {
41+
Context::reset();
42+
}
43+
}
44+
45+
public function testAddsSpanContextHeader()
46+
{
47+
$this->exporter->report(Argument::that(function ($tracer) {
48+
$spans = $tracer->spans();
49+
return count($spans) == 3 && $spans[2]->name() == 'GuzzleHttp::request';
50+
}))->shouldBeCalled();
51+
52+
$rt = Tracer::start($this->exporter->reveal(), [
53+
'skipReporting' => true
54+
]);
55+
56+
$handler = function ($request, $options) {
57+
$response = $this->prophesize(ResponseInterface::class);
58+
return $response->reveal();
59+
};
60+
61+
$middleware = new Middleware();
62+
$stack = $middleware($handler);
63+
$req = $this->prophesize(RequestInterface::class);
64+
$req->getMethod()->willReturn('GET')->shouldBeCalled();
65+
$req->getUri()->willReturn('/')->shouldBeCalled();
66+
$req->withHeader('HTTP_X_CLOUD_TRACE_CONTEXT', Argument::that(function ($val) {
67+
return preg_match('/[0-9a-f]+\/4660;o=1/', $val);
68+
}))->willReturn($req->reveal())->shouldBeCalled();
69+
$request = $req->reveal();
70+
71+
$response = Tracer::inSpan(['name' => 'parentSpan', 'spanId' => '1234'], function () use ($stack, $request) {
72+
return $stack($request, []);
73+
});
74+
75+
$rt->onExit();
76+
}
77+
}

tests/unit/Trace/RequestHandlerTest.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,10 @@ public function testCanTrackContext()
5050
$rt = new RequestHandler(
5151
$this->reporter->reveal(),
5252
$this->sampler->reveal(),
53-
new HttpHeaderPropagator()
53+
new HttpHeaderPropagator(),
54+
[
55+
'skipReporting' => true
56+
]
5457
);
5558
$rt->inSpan(['name' => 'inner'], function () {});
5659
$rt->onExit();
@@ -74,7 +77,8 @@ public function testCanParseParentContext()
7477
[
7578
'headers' => [
7679
'HTTP_X_CLOUD_TRACE_CONTEXT' => '12345678901234567890123456789012/5555;o=1'
77-
]
80+
],
81+
'skipReporting' => true
7882
]
7983
);
8084
$span = $rt->tracer()->spans()[0];
@@ -92,7 +96,8 @@ public function testForceEnabledContextHeader()
9296
[
9397
'headers' => [
9498
'HTTP_X_CLOUD_TRACE_CONTEXT' => '12345678901234567890123456789012;o=1'
95-
]
99+
],
100+
'skipReporting' => true
96101
]
97102
);
98103
$tracer = $rt->tracer();
@@ -109,7 +114,8 @@ public function testForceDisabledContextHeader()
109114
[
110115
'headers' => [
111116
'HTTP_X_CLOUD_TRACE_CONTEXT' => '12345678901234567890123456789012;o=0'
112-
]
117+
],
118+
'skipReporting' => true
113119
]
114120
);
115121
$tracer = $rt->tracer();

tests/unit/Trace/TracerTest.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ public function setUp()
3838
public function testForceDisabled()
3939
{
4040
$rt = Tracer::start($this->reporter->reveal(), [
41-
'sampler' => new NeverSampleSampler()
41+
'sampler' => new NeverSampleSampler(),
42+
'skipReporting' => true
4243
]);
4344
$tracer = $rt->tracer();
4445

@@ -49,7 +50,8 @@ public function testForceDisabled()
4950
public function testForceEnabled()
5051
{
5152
$rt = Tracer::start($this->reporter->reveal(), [
52-
'sampler' => new AlwaysSampleSampler()
53+
'sampler' => new AlwaysSampleSampler(),
54+
'skipReporting' => true
5355
]);
5456
$tracer = $rt->tracer();
5557

0 commit comments

Comments
 (0)