Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OTLP/GRPC Exporter Implementation #272

Merged
merged 37 commits into from
May 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
dc64b04
Adding Proto to opentelemetry-php
riticksingh Nov 11, 2020
dfe7b26
Updated the script for generating proto folder in root
riticksingh Nov 13, 2020
7205339
Moved shell file in script folder
riticksingh Nov 13, 2020
dc6fe75
Removed opentelemetry-proto
riticksingh Nov 14, 2020
09a405a
Bug fixed
riticksingh Nov 15, 2020
3444fb9
added docker-compose.proto.yaml
riticksingh Nov 17, 2020
ffae565
Update docker-compose.proto.yaml
riticksingh Nov 17, 2020
1cc76d4
Updated README.md
riticksingh Nov 17, 2020
7a3fdcd
Merge remote-tracking branch 'upstream/master'
riticksingh Nov 21, 2020
d536ec8
OtlpGrpc
riticksingh Nov 21, 2020
40bf96f
Added Request-response
riticksingh Nov 22, 2020
e02b931
Example Updated
riticksingh Nov 24, 2020
b691299
Updated Span Converter
riticksingh Nov 26, 2020
912584d
small fixes
riticksingh Dec 16, 2020
9bb160f
modified: SpanConvertor.php
riticksingh Dec 16, 2020
cf54582
(WIP): Partially working OTLP/GRPC Exporter
SeanHood Mar 4, 2021
354853f
Fixed traceid and spanid hacks; Now supports Events
SeanHood Mar 8, 2021
7f9530c
Use localhost:4317 for the default host; + cleanup
SeanHood Mar 12, 2021
8c63f52
Merge remote-tracking branch 'origin/main' into otlp-grpc
SeanHood Mar 12, 2021
580acf8
Split code between Exporter.php and SpanConverter.php; Beginnings of …
SeanHood Mar 17, 2021
b8469e6
More progress on tests, array's now correctly get converted. Also ran…
SeanHood Mar 19, 2021
2c5ccf4
* Ironed out passing in headers. Could not figure out how best to val…
SeanHood Mar 31, 2021
844ebf2
Add (failing) test for converting SDK Span to OTLP Span
SeanHood Apr 6, 2021
621175c
Further progress on Tests for the Exporter
SeanHood Apr 6, 2021
5c54d21
SpanConverter now translates attrs on Events
SeanHood Apr 9, 2021
49fa87d
Add opentelemtry-proto files
SeanHood Apr 13, 2021
996b473
Ran `make style' on proto. Do we want this?
SeanHood Apr 13, 2021
5dd3dd9
Few changes in this one..
SeanHood Apr 13, 2021
03a767a
Fix some of the complaints from static analysis
SeanHood Apr 21, 2021
40ce35f
Merge branch 'main' of github.com:SeanHood/opentelemetry-php into otl…
SeanHood Apr 21, 2021
0eb6cfd
Revert "Ran `make style' on proto. Do we want this?"
SeanHood Apr 21, 2021
469afde
make style
SeanHood Apr 21, 2021
06b68f7
Static analysis fixes
SeanHood Apr 22, 2021
1b2c91a
Hopefully this adds the grpc extension
SeanHood Apr 22, 2021
b46f981
Hopefully this adds the grpc extension
SeanHood Apr 24, 2021
a0fd792
Some Psalm fixes
SeanHood Apr 26, 2021
f68a7f1
Added a few comments; disable testing of InstrumentationLibrary until…
SeanHood May 5, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
php-version: ${{ matrix.php-versions }}
coverage: xdebug
tools: php-cs-fixer
extensions: ast
extensions: ast, grpc

- name: Validate composer.json and composer.lock
run: composer validate
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ vendor
coverage.clover
tests/coverage
.php_cs.cache
proto/*

# W3C Test Service build artifacts
tests/TraceContext/W3CTestService/test_app
Expand Down
2 changes: 2 additions & 0 deletions .phan/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@
// to `exclude_analysis_directory_list`.
'exclude_analysis_directory_list' => [
'vendor/',
'proto/',
],

// Enable this to enable checks of require/include statements referring to valid paths.
Expand Down Expand Up @@ -360,6 +361,7 @@
'Context',
'sdk',
'contrib',
'proto',
'vendor/composer/xdebug-handler/src',
'vendor/guzzlehttp',
'vendor/psr',
Expand Down
1 change: 1 addition & 0 deletions .php_cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
$finder = PhpCsFixer\Finder::create()
->exclude('vendor')
->exclude('var/cache')
->exclude('proto')
->in(__DIR__);

return PhpCsFixer\Config::create()
Expand Down
14 changes: 12 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
"guzzlehttp/guzzle": "^7.1.0",
"psr/http-client": "^1.0",
"php-http/guzzle7-adapter": "^0.1.1",
"promphp/prometheus_client_php": "^2.2.1"
"promphp/prometheus_client_php": "^2.2.1",
"grpc/grpc": "^1.30",
"google/protobuf": "^v3.3.0"
},
"authors": [
{
Expand All @@ -30,7 +32,15 @@
"OpenTelemetry\\Context\\": "Context",
"OpenTelemetry\\": "api",
"OpenTelemetry\\Sdk\\": "sdk",
"OpenTelemetry\\Contrib\\": "contrib"
"OpenTelemetry\\Contrib\\": "contrib",
"Opentelemetry\\Proto\\Collector\\Trace\\V1\\": "proto/Opentelemetry/Proto/Collector/Trace/V1",
"Opentelemetry\\Proto\\Trace\\V1\\":"proto/Opentelemetry/Proto/Trace/V1",
"Opentelemetry\\Proto\\Common\\V1\\":"proto/Opentelemetry/Proto/Common/V1",
"Opentelemetry\\Proto\\Resource\\V1\\":"proto/Opentelemetry/Proto/Resource/V1",
"GPBMetadata\\Opentelemetry\\Proto\\Collector\\Trace\\V1\\": "proto/GPBMetadata/Opentelemetry/Proto/Collector/Trace/V1",
"GPBMetadata\\Opentelemetry\\Proto\\Trace\\V1\\":"proto/GPBMetadata/Opentelemetry/Proto/Trace/V1",
"GPBMetadata\\Opentelemetry\\Proto\\Common\\V1\\":"proto/GPBMetadata/Opentelemetry/Proto/Common/V1",
"GPBMetadata\\Opentelemetry\\Proto\\Resource\\V1\\":"proto/GPBMetadata/Opentelemetry/Proto/Resource/V1"
}
},
"autoload-dev": {
Expand Down
204 changes: 204 additions & 0 deletions contrib/OtlpGrpc/Exporter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\Contrib\OtlpGrpc;

use grpc;
use InvalidArgumentException;
use Opentelemetry\Proto\Collector\Trace\V1\ExportTraceServiceRequest;
use Opentelemetry\Proto\Collector\Trace\V1\TraceServiceClient;
use OpenTelemetry\Sdk\Trace;
use OpenTelemetry\Trace as API;

class Exporter implements Trace\Exporter
{
/**
* @var string
*/
private $endpointURL;

/**
* @var string
*/
private $protocol;

/**
* @var bool|string
*/
private $insecure;

/**
* @var string
*/
private $certificateFile;

/**
* @var string
*/
private $headers;

/**
* @var bool|string
*/
private $compression;

/**
* @var int
*/
private $timeout;
/**
* @var SpanConverter
*/
private $spanConverter;

private $metadata;

/**
* @var bool
*/
private $running = true;

/**
* @var TraceServiceClient
*/

private $client;

/**
* OTLP GRPC Exporter Constructor
*/
public function __construct(
string $endpointURL = 'localhost:4317',
bool $insecure = true,
string $certificateFile = '',
string $headers = '',
bool $compression = false,
int $timeout = 10,
TraceServiceClient $client = null
) {

// Set default values based on presence of env variable
SeanHood marked this conversation as resolved.
Show resolved Hide resolved
$this->endpointURL = getenv('OTEL_EXPORTER_OTLP_ENDPOINT') ?: $endpointURL;
$this->protocol = getenv('OTEL_EXPORTER_OTLP_PROTOCOL') ?: 'grpc'; // I guess this is redundant?
$this->insecure = getenv('OTEL_EXPORTER_OTLP_INSECURE') ?: $insecure;
$this->certificateFile = getenv('OTEL_EXPORTER_OTLP_CERTIFICATE') ?: $certificateFile;
$this->headers = getenv('OTEL_EXPORTER_OTLP_HEADERS') ?: $headers;
$this->compression = getenv('OTEL_EXPORTER_OTLP_COMPRESSION') ?: $compression;
$this->timeout =(int) getenv('OTEL_EXPORTER_OTLP_TIMEOUT') ?: $timeout;

$this->spanConverter = new SpanConverter();

$this->metadata = $this->metadataFromHeaders($this->headers);

$opts = [
SeanHood marked this conversation as resolved.
Show resolved Hide resolved
'update_metadata' => function () {
return $this->metadata;
},
'timeout' => $this->timeout,
];

if (!$this->insecure && !$this->certificateFile) {
// Assumed default
$opts['credentials'] = Grpc\ChannelCredentials::createSsl('');
} elseif (!$this->insecure && $this->certificateFile !== '') {
// Should we validate more?
$opts['credentials'] = Grpc\ChannelCredentials::createSsl(file_get_contents($certificateFile));
} else {
$opts['credentials'] = Grpc\ChannelCredentials::createInsecure();
}

if ($this->compression) {
// gzip is the only specified compression method for now
$opts['grpc.default_compression_algorithm'] = 2;
}

$this->client = $client ?? new TraceServiceClient($this->endpointURL, $opts);
}

/**
* Exports the provided Span data via the OTLP protocol
*
* @param iterable<API\Span> $spans Array of Spans
* @return int return code, defined on the Exporter interface
*/
public function export(iterable $spans): int
{
if (!$this->running) {
return Exporter::FAILED_NOT_RETRYABLE;
}

if (empty($spans)) {
return Trace\Exporter::SUCCESS;
}

$resourcespans = [$this->spanConverter->as_otlp_resource_span($spans)];

$request = new ExportTraceServiceRequest([
'resource_spans' => $resourcespans,
]);

list($response, $status) = $this->client->Export($request)->wait();

if ($status->code == \Grpc\STATUS_OK) {
return Trace\Exporter::SUCCESS;
}

if (in_array($status->code, [
\Grpc\STATUS_CANCELLED,
\Grpc\STATUS_DEADLINE_EXCEEDED,
\Grpc\STATUS_PERMISSION_DENIED,
\Grpc\STATUS_RESOURCE_EXHAUSTED,
\Grpc\STATUS_ABORTED,
\Grpc\STATUS_OUT_OF_RANGE,
\Grpc\STATUS_UNAVAILABLE,
\Grpc\STATUS_DATA_LOSS,
\Grpc\STATUS_UNAUTHENTICATED,
])) {
return Trace\Exporter::FAILED_RETRYABLE;
}

return Trace\Exporter::FAILED_NOT_RETRYABLE;
}

public function setHeader($key, $value)
{
$this->metadata[$key] = [$value];
}

public function getHeaders()
{
return $this->metadata;
}

public function metadataFromHeaders($headers): array
{
if (is_array($headers)) {
throw new InvalidArgumentException('Configuring Headers Via');
}

$pairs = explode(',', $headers);

if (!array_key_exists(1, $pairs)) {
return [];
}

$metadata = [];
foreach ($pairs as $pair) {
list($key, $value) = explode('=', $pair, 2);
$metadata[$key] = [$value];
}

return $metadata;
}

public function shutdown(): void
{
$this->running = false;
}

// public function getHeaders()
// {
// return $this->metadataFromHeaders($this->headers);
// }
}
Loading