Skip to content

Commit 6ecb85a

Browse files
authored
Add working example and tests for improvements (#331)
* Adjust exporters and exporter tests as necesasary * Make style fixes * Fix static analysis errors * Add PHPStan fix * Fix Psalm error
1 parent bbc09fb commit 6ecb85a

17 files changed

+202
-112
lines changed

composer.json

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,11 @@
66
"require": {
77
"php": "^7.3 || ^8.0",
88
"ext-json": "*",
9-
"guzzlehttp/guzzle": "^7.1.0",
10-
"psr/http-client": "^1.0",
11-
"php-http/guzzle7-adapter": "^0.1.1",
129
"promphp/prometheus_client_php": "^2.2.1",
1310
"grpc/grpc": "^1.30",
14-
"google/protobuf": "^v3.3.0"
11+
"google/protobuf": "^v3.3.0",
12+
"psr/http-client-implementation": "^1.0",
13+
"psr/http-factory-implementation": "^1.0"
1514
},
1615
"authors": [
1716
{
@@ -56,6 +55,10 @@
5655
"vimeo/psalm": "^4.0",
5756
"phpstan/phpstan": "^0.12.50",
5857
"phpstan/phpstan-phpunit": "^0.12.16",
59-
"psalm/plugin-phpunit": "^0.13.0"
58+
"psalm/plugin-phpunit": "^0.13.0",
59+
"guzzlehttp/guzzle": "^7.3",
60+
"guzzlehttp/psr7": "^2.0@RC",
61+
"symfony/http-client": "^5.2",
62+
"nyholm/psr7": "^1.4"
6063
}
61-
}
64+
}

contrib/Newrelic/Exporter.php

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44

55
namespace OpenTelemetry\Contrib\Newrelic;
66

7-
use GuzzleHttp\Psr7\Request;
8-
use Http\Adapter\Guzzle7\Client;
97
use InvalidArgumentException;
108
use OpenTelemetry\Sdk\Trace;
119
use OpenTelemetry\Trace as API;
1210
use Psr\Http\Client\ClientExceptionInterface;
1311
use Psr\Http\Client\ClientInterface;
1412
use Psr\Http\Client\NetworkExceptionInterface;
1513
use Psr\Http\Client\RequestExceptionInterface;
14+
use Psr\Http\Message\RequestFactoryInterface;
15+
use Psr\Http\Message\StreamFactoryInterface;
1616

1717
/**
1818
* Class NewrelicExporter - implements the export interface for data transfer via Newrelic protocol
@@ -57,14 +57,26 @@ class Exporter implements Trace\Exporter
5757
*/
5858
private $client;
5959

60+
/**
61+
* @var RequestFactoryInterface
62+
*/
63+
private $requestFactory;
64+
65+
/**
66+
* @var StreamFactoryInterface
67+
*/
68+
private $streamFactory;
69+
6070
private $dataFormatVersion;
6171

6272
public function __construct(
6373
$name,
6474
string $endpointUrl,
6575
string $licenseKey,
76+
ClientInterface $client,
77+
RequestFactoryInterface $requestFactory,
78+
StreamFactoryInterface $streamFactory,
6679
SpanConverter $spanConverter = null,
67-
ClientInterface $client = null,
6880
string $dataFormatVersion = Exporter::DATA_FORMAT_VERSION_DEFAULT
6981
) {
7082
$parsedDsn = parse_url($endpointUrl);
@@ -79,12 +91,15 @@ public function __construct(
7991
) {
8092
throw new InvalidArgumentException('Endpoint should have scheme, host, port and path');
8193
}
82-
$this->dataFormatVersion = $dataFormatVersion;
83-
$this->licenseKey = $licenseKey;
84-
$this->endpointUrl = $endpointUrl;
94+
8595
$this->name = $name;
86-
$this->client = $client ?? $this->createDefaultClient();
96+
$this->endpointUrl = $endpointUrl;
97+
$this->licenseKey = $licenseKey;
98+
$this->client = $client;
99+
$this->requestFactory = $requestFactory;
100+
$this->streamFactory = $streamFactory;
87101
$this->spanConverter = $spanConverter ?? new SpanConverter($name);
102+
$this->dataFormatVersion = $dataFormatVersion;
88103
}
89104

90105
/**
@@ -113,12 +128,15 @@ public function export(iterable $spans): int
113128
'spans' => $convertedSpans, ]];
114129

115130
try {
116-
$json = json_encode($payload);
117-
$headers = ['content-type' => 'application/json',
118-
'Api-Key' => $this->licenseKey,
119-
'Data-Format' => Exporter::DATA_FORMAT,
120-
'Data-Format-Version' => $this->dataFormatVersion, ];
121-
$request = new Request('POST', $this->endpointUrl, $headers, $json);
131+
$body = $this->streamFactory->createStream(json_encode($payload));
132+
$request = $this->requestFactory
133+
->createRequest('POST', $this->endpointUrl)
134+
->withBody($body)
135+
->withHeader('content-type', 'application/json')
136+
->withAddedHeader('Api-Key', $this->licenseKey)
137+
->withAddedHeader('Data-Format', Exporter::DATA_FORMAT)
138+
->withAddedHeader('Data-Format-Version', $this->dataFormatVersion);
139+
122140
$response = $this->client->sendRequest($request);
123141
} catch (RequestExceptionInterface $e) {
124142
return Trace\Exporter::FAILED_NOT_RETRYABLE;
@@ -149,11 +167,4 @@ public function shutdown(): void
149167
{
150168
$this->running = false;
151169
}
152-
153-
protected function createDefaultClient(): ClientInterface
154-
{
155-
return Client::createWithConfig([
156-
'timeout' => 30,
157-
]);
158-
}
159170
}

contrib/Otlp/Exporter.php

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,21 @@
44

55
namespace OpenTelemetry\Contrib\Otlp;
66

7-
use GuzzleHttp\Psr7\Request;
8-
use Http\Adapter\Guzzle7\Client;
97
use OpenTelemetry\Sdk\Trace;
108
use OpenTelemetry\Trace as API;
119
use Psr\Http\Client\ClientExceptionInterface;
1210
use Psr\Http\Client\ClientInterface;
1311
use Psr\Http\Client\NetworkExceptionInterface;
1412
use Psr\Http\Client\RequestExceptionInterface;
13+
use Psr\Http\Message\RequestFactoryInterface;
14+
use Psr\Http\Message\StreamFactoryInterface;
1515

1616
class Exporter implements Trace\Exporter
1717
{
1818
/**
1919
* @var string
2020
*/
21-
private $endpointURL;
21+
private $endpointUrl;
2222

2323
/**
2424
* @var string
@@ -62,29 +62,43 @@ class Exporter implements Trace\Exporter
6262
/**
6363
* @var ClientInterface
6464
*/
65-
6665
private $client;
6766

67+
/**
68+
* @var RequestFactoryInterface
69+
*/
70+
private $requestFactory;
71+
72+
/**
73+
* @var StreamFactoryInterface
74+
*/
75+
private $streamFactory;
76+
6877
/**
6978
* Exporter constructor.
7079
* @param string $serviceName
7180
*/
7281
public function __construct(
7382
$serviceName,
74-
ClientInterface $client=null
83+
ClientInterface $client,
84+
RequestFactoryInterface $requestFactory,
85+
StreamFactoryInterface $streamFactory,
86+
SpanConverter $spanConverter = null
7587
) {
7688

7789
// Set default values based on presence of env variable
78-
$this->endpointURL = getenv('OTEL_EXPORTER_OTLP_ENDPOINT') ?: 'localhost:55681';
90+
$this->endpointUrl = getenv('OTEL_EXPORTER_OTLP_ENDPOINT') ?: 'localhost:55681';
7991
$this->protocol = getenv('OTEL_EXPORTER_OTLP_PROTOCOL') ?: 'json';
8092
$this->insecure = getenv('OTEL_EXPORTER_OTLP_INSECURE') ?: 'false';
8193
$this->certificateFile = getenv('OTEL_EXPORTER_OTLP_CERTIFICATE') ?: 'none';
8294
$this->headers[] = getenv('OTEL_EXPORTER_OTLP_HEADERS') ?: 'none';
8395
$this->compression = getenv('OTEL_EXPORTER_OTLP_COMPRESSION') ?: 'none';
8496
$this->timeout =(int) getenv('OTEL_EXPORTER_OTLP_TIMEOUT') ?: 10;
8597

86-
$this->client = $client ?? $this->createDefaultClient();
87-
$this->spanConverter = new SpanConverter($serviceName);
98+
$this->client = $client;
99+
$this->requestFactory = $requestFactory;
100+
$this->streamFactory = $streamFactory;
101+
$this->spanConverter = $spanConverter ?? new SpanConverter($serviceName);
88102
}
89103

90104
/**
@@ -109,15 +123,14 @@ public function export(iterable $spans): int
109123
}
110124

111125
try {
112-
$json = json_encode($convertedSpans);
113-
114-
$this->headers[] = '';
126+
$body = $this->streamFactory->createStream(json_encode($convertedSpans));
127+
$request = $this->requestFactory
128+
->createRequest('POST', $this->endpointUrl)
129+
->withBody($body);
115130

116131
if ($this->protocol == 'json') {
117-
$this->headers = ['content-type' => 'application/json'];
132+
$request->withHeader('content-type', 'application/json');
118133
}
119-
120-
$request = new Request('POST', $this->endpointURL, $this->headers, $json);
121134
$response = $this->client->sendRequest($request);
122135
} catch (RequestExceptionInterface $e) {
123136
return Trace\Exporter::FAILED_NOT_RETRYABLE;
@@ -140,11 +153,4 @@ public function shutdown(): void
140153
{
141154
$this->running = false;
142155
}
143-
144-
protected function createDefaultClient(): ClientInterface
145-
{
146-
return Client::createWithConfig([
147-
'timeout' => 30,
148-
]);
149-
}
150156
}

contrib/Zipkin/Exporter.php

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44

55
namespace OpenTelemetry\Contrib\Zipkin;
66

7-
use GuzzleHttp\Psr7\Request;
8-
use Http\Adapter\Guzzle7\Client;
97
use InvalidArgumentException;
108
use OpenTelemetry\Sdk\Trace;
119
use OpenTelemetry\Trace as API;
1210
use Psr\Http\Client\ClientExceptionInterface;
1311
use Psr\Http\Client\ClientInterface;
1412
use Psr\Http\Client\NetworkExceptionInterface;
1513
use Psr\Http\Client\RequestExceptionInterface;
14+
use Psr\Http\Message\RequestFactoryInterface;
15+
use Psr\Http\Message\StreamFactoryInterface;
1616

1717
/**
1818
* Class ZipkinExporter - implements the export interface for data transfer via Zipkin protocol
@@ -39,12 +39,18 @@ class Exporter implements Trace\Exporter
3939
* @var ClientInterface
4040
*/
4141
private $client;
42+
43+
private $requestFactory;
44+
45+
private $streamFactory;
4246

4347
public function __construct(
4448
$name,
4549
string $endpointUrl,
46-
SpanConverter $spanConverter = null,
47-
ClientInterface $client = null
50+
ClientInterface $client,
51+
RequestFactoryInterface $requestFactory,
52+
StreamFactoryInterface $streamFactory,
53+
SpanConverter $spanConverter = null
4854
) {
4955
$parsedDsn = parse_url($endpointUrl);
5056

@@ -62,7 +68,9 @@ public function __construct(
6268
}
6369

6470
$this->endpointUrl = $endpointUrl;
65-
$this->client = $client ?? $this->createDefaultClient();
71+
$this->client = $client;
72+
$this->requestFactory = $requestFactory;
73+
$this->streamFactory = $streamFactory;
6674
$this->spanConverter = $spanConverter ?? new SpanConverter($name);
6775
}
6876

@@ -88,9 +96,12 @@ public function export(iterable $spans): int
8896
}
8997

9098
try {
91-
$json = json_encode($convertedSpans);
92-
$headers = ['content-type' => 'application/json'];
93-
$request = new Request('POST', $this->endpointUrl, $headers, $json);
99+
$body = $this->streamFactory->createStream(json_encode($convertedSpans));
100+
$request = $this->requestFactory
101+
->createRequest('POST', $this->endpointUrl)
102+
->withBody($body)
103+
->withHeader('content-type', 'application/json');
104+
94105
$response = $this->client->sendRequest($request);
95106
} catch (RequestExceptionInterface $e) {
96107
return Trace\Exporter::FAILED_NOT_RETRYABLE;
@@ -113,11 +124,4 @@ public function shutdown(): void
113124
{
114125
$this->running = false;
115126
}
116-
117-
protected function createDefaultClient(): ClientInterface
118-
{
119-
return Client::createWithConfig([
120-
'timeout' => 30,
121-
]);
122-
}
123127
}

0 commit comments

Comments
 (0)