1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
|
<?php
namespace Wikimedia\Telemetry;
use GuzzleHttp\Psr7\Utils;
use Psr\Http\Client\ClientExceptionInterface;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestFactoryInterface;
use Psr\Log\LoggerInterface;
/**
* An {@link ExporterInterface} that exports collected data over HTTP, serialized in OTLP JSON format.
*
* @since 1.43
* @internal
*/
class OtlpHttpExporter implements ExporterInterface {
private ClientInterface $client;
private RequestFactoryInterface $requestFactory;
private LoggerInterface $logger;
/**
* URI of the OTLP receiver endpoint to send data to.
* @var string
*/
private string $endpoint;
/**
* Descriptive name used to identify this service in traces.
* @var string
*/
private string $serviceName;
/**
* The host name of this server to be reported in traces.
* @var string
*/
private string $hostName;
public function __construct(
ClientInterface $client,
RequestFactoryInterface $requestFactory,
LoggerInterface $logger,
string $uri,
string $serviceName,
string $hostName
) {
$this->client = $client;
$this->requestFactory = $requestFactory;
$this->logger = $logger;
$this->endpoint = $uri;
$this->serviceName = $serviceName;
$this->hostName = $hostName;
}
/** @inheritDoc */
public function export( TracerState $tracerState ): void {
$spanContexts = $tracerState->getSpanContexts();
if ( count( $spanContexts ) === 0 ) {
return;
}
$resourceInfo = array_filter( [
'service.name' => $this->serviceName,
'host.name' => $this->hostName,
"server.socket.address" => $_SERVER['SERVER_ADDR'] ?? null,
] );
$data = [
'resourceSpans' => [
[
'resource' => [
'attributes' => OtlpSerializer::serializeKeyValuePairs( $resourceInfo )
],
'scopeSpans' => [
[
'scope' => [
'name' => 'org.wikimedia.telemetry',
],
'spans' => $spanContexts
]
]
]
]
];
$request = $this->requestFactory->createRequest( 'POST', $this->endpoint )
->withHeader( 'Content-Type', 'application/json' )
->withBody( Utils::streamFor( json_encode( $data ) ) );
try {
$response = $this->client->sendRequest( $request );
if ( $response->getStatusCode() !== 200 ) {
$this->logger->error( 'Failed to export trace data' );
}
} catch ( ClientExceptionInterface $e ) {
$this->logger->error( 'Failed to connect to exporter', [ 'exception' => $e ] );
}
// Clear out finished spans after exporting them.
$tracerState->clearSpanContexts();
}
}
|