Skip to content

Commit

Permalink
Add Span InMemoryExporter (#775)
Browse files Browse the repository at this point in the history
* Add InMemoryExporter
  • Loading branch information
tidal authored Jul 17, 2022
1 parent 90036b1 commit d3facad
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 1 deletion.
43 changes: 43 additions & 0 deletions examples/traces/features/exporters/in_memory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);
require __DIR__ . '/../../../../vendor/autoload.php';

use OpenTelemetry\SDK\Trace\SpanDataInterface;
use OpenTelemetry\SDK\Trace\SpanExporter\InMemoryExporter;
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
use OpenTelemetry\SDK\Trace\TracerProvider;

// Create an ArrayObject as the storage for the spans
$storage = new ArrayObject();

// Boilerplate setup to create a new tracer with an in-memory exporter
$tracer = (new TracerProvider(
new SimpleSpanProcessor(
new InMemoryExporter($storage)
)
))->getTracer('io.opentelemetry.contrib.php');

// This creates a span and sets it as the current parent (and root) span
$rootSpan = $tracer->spanBuilder('foo')->startSpan();
$rootScope = $rootSpan->activate();

// This creates child spans
$childSpan1 = $tracer->spanBuilder('bar')->startSpan();
$childSpan2 = $tracer->spanBuilder('bar')->startSpan();

// This closes all spans
$childSpan2->end();
$childSpan1->end();
$rootSpan->end();

/** @var SpanDataInterface $span */
foreach ($storage as $span) {
echo PHP_EOL . sprintf(
'TRACE: "%s", SPAN: "%s", PARENT: "%s"',
$span->getTraceId(),
$span->getSpanId(),
$span->getParentSpanId()
);
}
echo PHP_EOL;
3 changes: 2 additions & 1 deletion src/SDK/Trace/ExporterFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class ExporterFactory

private const KNOWN_EXPORTERS = [
'console' => '\OpenTelemetry\SDK\Trace\SpanExporter\ConsoleSpanExporter',
'memory' => '\OpenTelemetry\SDK\Trace\SpanExporter\InMemoryExporter',
'logger+file' => '\OpenTelemetry\SDK\Trace\SpanExporter\LoggerExporter',
'jaeger+http' => '\OpenTelemetry\Contrib\Jaeger\Exporter',
'zipkin+http' => '\OpenTelemetry\Contrib\Zipkin\Exporter',
Expand Down Expand Up @@ -47,7 +48,7 @@ public function __construct(string $serviceName = self::DEFAULT_SERVICE_NAME)
*/
public function fromConnectionString(string $connectionString): SpanExporterInterface
{
if (in_array($connectionString, ['console', 'otlp+http'])) {
if (in_array($connectionString, ['console', 'memory', 'otlp+http'])) {
return self::buildExporter($connectionString);
}

Expand Down
45 changes: 45 additions & 0 deletions src/SDK/Trace/SpanExporter/InMemoryExporter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\SDK\Trace\SpanExporter;

use ArrayObject;
use OpenTelemetry\SDK\Trace\Behavior\SpanExporterTrait;
use OpenTelemetry\SDK\Trace\SpanExporterInterface;

class InMemoryExporter implements SpanExporterInterface
{
use SpanExporterTrait;

private ArrayObject $storage;

public function __construct(?ArrayObject $storage = null)
{
$this->storage = $storage ?? new ArrayObject();
}

public static function fromConnectionString(string $endpointUrl = null, string $name = null, $args = null)
{
return new self();
}

protected function doExport(iterable $spans): int
{
foreach ($spans as $span) {
$this->storage[] = $span;
}

return SpanExporterInterface::STATUS_SUCCESS;
}

public function getSpans(): array
{
return (array) $this->storage;
}

public function getStorage(): ArrayObject
{
return $this->storage;
}
}
2 changes: 2 additions & 0 deletions tests/Unit/SDK/Trace/ExporterFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use OpenTelemetry\Contrib;
use OpenTelemetry\SDK\Trace\ExporterFactory;
use OpenTelemetry\SDK\Trace\SpanExporter\ConsoleSpanExporter;
use OpenTelemetry\SDK\Trace\SpanExporter\InMemoryExporter;
use PHPUnit\Framework\TestCase;

/**
Expand Down Expand Up @@ -50,6 +51,7 @@ public function endpointProvider(): array
'otlp+grpc' => ['test.otlpgrpc', 'otlp+grpc://otlp:4317', Contrib\OtlpGrpc\Exporter::class],
'zipkintonewrelic' => ['test.zipkintonewrelic', 'zipkintonewrelic+https://trace-api.newrelic.com/trace/v1?licenseKey=abc23423423', Contrib\ZipkinToNewrelic\Exporter::class],
'console' => ['test.console', 'console', ConsoleSpanExporter::class],
'memory' => ['test.memory', 'memory', InMemoryExporter::class],
];
}

Expand Down
71 changes: 71 additions & 0 deletions tests/Unit/SDK/Trace/SpanExporter/InMemoryExporterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\Tests\Unit\SDK\Trace\SpanExporter;

use ArrayObject;
use Generator;
use OpenTelemetry\SDK\Trace\SpanDataInterface;
use OpenTelemetry\SDK\Trace\SpanExporter\InMemoryExporter;
use PHPUnit\Framework\TestCase;

/**
* @covers \OpenTelemetry\SDK\Trace\SpanExporter\InMemoryExporter
*/
class InMemoryExporterTest extends TestCase
{
/**
* @dataProvider provideSpans
*/
public function test_export(iterable $spans): void
{
$instance = new InMemoryExporter();

$instance->export($spans);

$this->assertSame(
$spans,
$instance->getSpans()
);
}

public function test_from_connection_string(): void
{
$this->assertInstanceOf(
InMemoryExporter::class,
InMemoryExporter::fromConnectionString()
);
}

public function test_get_storage(): void
{
$storage = new ArrayObject();

$this->assertSame(
$storage,
(new InMemoryExporter($storage))->getStorage()
);
}

public function test_get_spans(): void
{
$storage = new ArrayObject();

$this->assertSame(
(array) $storage,
(new InMemoryExporter($storage))->getSpans()
);
}

public function provideSpans(): Generator
{
$spans = [];

for ($x = 0; $x < 3; $x++) {
$spans[] = $this->createMock(SpanDataInterface::class);

yield $x => [$spans];
}
}
}

0 comments on commit d3facad

Please sign in to comment.