Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
31 changes: 31 additions & 0 deletions examples/spansuppression/SemanticConventionResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\Example;

use OpenTelemetry\API\Trace\SpanKind;
use OpenTelemetry\API\Trace\SpanSuppression\SemanticConvention;

final class SemanticConventionResolver implements \OpenTelemetry\API\Trace\SpanSuppression\SemanticConventionResolver
{
#[\Override]
public function resolveSemanticConventions(string $name, ?string $version, ?string $schemaUrl): array
{
if ($schemaUrl === null || !\str_starts_with($schemaUrl, 'https://opentelemetry.io/schemas/')) {
return [];
}

return [
new SemanticConvention('span.azure.cosmosdb.client', SpanKind::KIND_CLIENT, ['db.operation.name'], ['azure.client.id', 'azure.cosmosdb.request.body.size', 'error.type', 'azure.cosmosdb.consistency.level', 'azure.cosmosdb.response.sub_status_code', 'az.namespace', 'azure.cosmosdb.connection.mode', 'azure.cosmosdb.operation.contacted_regions', 'azure.cosmosdb.operation.request_charge', 'user_agent.original', 'db.query.text', 'db.operation.batch.size', 'db.stored_procedure.name', 'server.address', 'db.query.parameter', 'db.namespace', 'db.collection.name', 'db.response.returned_rows', 'db.response.status_code', 'server.port', 'code.*']),
new SemanticConvention('span.cicd.pipeline.task.internal', SpanKind::KIND_INTERNAL, ['cicd.pipeline.task.name', 'cicd.pipeline.task.run.id', 'cicd.pipeline.task.run.url.full'], ['error.type', 'code.*']),
new SemanticConvention('span.db.client', SpanKind::KIND_CLIENT, ['db.system.name'], ['error.type', 'network.peer.address', 'network.peer.port', 'db.operation.batch.size', 'db.response.status_code', 'db.stored_procedure.name', 'db.operation.name', 'server.address', 'server.port', 'db.query.parameter', 'db.query.summary', 'db.query.text', 'db.collection.name', 'db.namespace', 'db.response.returned_rows', 'code.*']),
new SemanticConvention('span.db.elasticsearch.client', SpanKind::KIND_CLIENT, ['http.request.method', 'url.full', 'db.operation.name'], ['error.type', 'elasticsearch.node.name', 'db.operation.batch.size', 'server.address', 'server.port', 'db.collection.name', 'db.namespace', 'db.operation.parameter', 'db.query.text', 'db.response.status_code', 'code.*']),
new SemanticConvention('span.db.hbase.client', SpanKind::KIND_CLIENT, ['db.operation.name'], ['error.type', 'db.operation.batch.size', 'server.address', 'server.port', 'db.collection.name', 'db.namespace', 'db.response.status_code', 'code.*']),
new SemanticConvention('span.db.mongodb.client', SpanKind::KIND_CLIENT, ['db.collection.name', 'db.operation.name'], ['error.type', 'db.operation.batch.size', 'server.address', 'server.port', 'db.namespace', 'db.response.status_code', 'code.*']),
new SemanticConvention('span.db.redis.client', SpanKind::KIND_CLIENT, ['db.operation.name'], ['error.type', 'network.peer.port', 'network.peer.address', 'db.operation.batch.size', 'server.address', 'server.port', 'db.namespace', 'db.query.text', 'db.response.status_code', 'db.stored_procedure.name', 'code.*']),
new SemanticConvention('span.http.client', SpanKind::KIND_CLIENT, ['http.request.method', 'server.address', 'server.port', 'url.full'], ['network.peer.address', 'network.peer.port', 'error.type', 'http.request.body.size', 'http.request.header.*', 'http.request.method_original', 'http.request.resend_count', 'http.request.size', 'http.response.body.size', 'http.response.header.*', 'http.response.size', 'http.response.status_code', 'network.protocol.name', 'network.protocol.version', 'network.transport', 'user_agent.original', 'user_agent.synthetic.type', 'url.scheme', 'url.template', 'code.*']),
new SemanticConvention('span.http.server', SpanKind::KIND_SERVER, ['http.request.method', 'url.path', 'url.scheme'], ['network.peer.address', 'network.peer.port', 'error.type', 'http.request.body.size', 'http.request.method_original', 'http.request.size', 'http.response.body.size', 'http.response.header.*', 'http.response.size', 'http.response.status_code', 'network.protocol.name', 'network.protocol.version', 'network.transport', 'user_agent.synthetic.type', 'client.address', 'client.port', 'http.request.header.*', 'http.route', 'network.local.address', 'network.local.port', 'user_agent.original', 'server.address', 'server.port', 'url.query', 'code.*']),
];
}
}
69 changes: 69 additions & 0 deletions examples/spansuppression/semanticconventionssuppression-1.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\Example;

use OpenTelemetry\API\Common\Time\Clock;
use OpenTelemetry\API\Trace\SpanKind;
use OpenTelemetry\Contrib\Otlp\SpanExporter;
use OpenTelemetry\SDK\Common\Export\Stream\StreamTransportFactory;
use OpenTelemetry\SDK\Resource\ResourceInfoFactory;
use OpenTelemetry\SDK\Trace\SpanProcessor\BatchSpanProcessor;
use OpenTelemetry\SDK\Trace\SpanSuppression\SemanticConventionSuppressionStrategy\SemanticConventionSuppressionStrategy;
use OpenTelemetry\SDK\Trace\TracerProviderBuilder;

require_once __DIR__ . '/../../vendor/autoload.php';
require_once __DIR__ . '/SemanticConventionResolver.php';

// Two nested http client instrumentations

$tp = (new TracerProviderBuilder())
->setResource(ResourceInfoFactory::emptyResource())
->addSpanProcessor(new BatchSpanProcessor(new SpanExporter((new StreamTransportFactory())->create('php://stdout', 'application/x-ndjson')), Clock::getDefault()))
->setSpanSuppressionStrategy(new SemanticConventionSuppressionStrategy([
new SemanticConventionResolver(),
]))
->build()
;

$t = $tp->getTracer('test');
$c1 = $tp
->getTracer('instrumentation-1', schemaUrl: 'https://opentelemetry.io/schemas/1.33.0')
->spanBuilder('GET')
->setSpanKind(SpanKind::KIND_CLIENT)
->setAttributes([
'http.request.method' => 'GET',
'server.address' => 'http://example.com',
'server.port' => '80',
'url.full' => 'http://example.com',
])
->startSpan();
$s1 = $c1->activate();

try {
$c2 = $tp
->getTracer('instrumentation-2', schemaUrl: 'https://opentelemetry.io/schemas/1.31.0')
->spanBuilder('GET')
->setSpanKind(SpanKind::KIND_CLIENT)
->setAttributes([
'http.request.method' => 'GET',
'server.address' => 'http://example.com',
'server.port' => '80',
'url.full' => 'http://example.com',
])
->startSpan();
$s2 = $c2->activate();

try {
// ...
} finally {
$s2->detach();
$c2->end();
}
} finally {
$s1->detach();
$c1->end();
}

$tp->shutdown();
71 changes: 71 additions & 0 deletions examples/spansuppression/semanticconventionssuppression-2.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\Example;

use OpenTelemetry\API\Common\Time\Clock;
use OpenTelemetry\API\Trace\SpanKind;
use OpenTelemetry\Contrib\Otlp\SpanExporter;
use OpenTelemetry\SDK\Common\Export\Stream\StreamTransportFactory;
use OpenTelemetry\SDK\Resource\ResourceInfoFactory;
use OpenTelemetry\SDK\Trace\SpanProcessor\BatchSpanProcessor;
use OpenTelemetry\SDK\Trace\SpanSuppression\SemanticConventionSuppressionStrategy\SemanticConventionSuppressionStrategy;
use OpenTelemetry\SDK\Trace\TracerProviderBuilder;

require_once __DIR__ . '/../../vendor/autoload.php';
require_once __DIR__ . '/SemanticConventionResolver.php';

// Elasticsearch client instrumentation that uses an instrumented http client

$tp = (new TracerProviderBuilder())
->setResource(ResourceInfoFactory::emptyResource())
->addSpanProcessor(new BatchSpanProcessor(new SpanExporter((new StreamTransportFactory())->create('php://stdout', 'application/x-ndjson')), Clock::getDefault()))
->setSpanSuppressionStrategy(new SemanticConventionSuppressionStrategy([
new SemanticConventionResolver(),
]))
->build()
;

$t = $tp->getTracer('test');

$c1 = $tp
->getTracer('elasticsearch-instrumentation', schemaUrl: 'https://opentelemetry.io/schemas/1.33.0')
->spanBuilder('SELECT')
->setSpanKind(SpanKind::KIND_CLIENT)
->setAttributes([
'http.request.method' => 'GET',
'server.address' => 'http://example.com',
'server.port' => '80',
'url.full' => 'http://example.com',
'db.operation.name' => 'SELECT',
])
->startSpan();
$s1 = $c1->activate();

try {
$c2 = $tp
->getTracer('httpclient-instrumentation', schemaUrl: 'https://opentelemetry.io/schemas/1.33.0')
->spanBuilder('GET')
->setSpanKind(SpanKind::KIND_CLIENT)
->setAttributes([
'http.request.method' => 'GET',
'server.address' => 'http://example.com',
'server.port' => '80',
'url.full' => 'http://example.com',
])
->startSpan();
$s2 = $c2->activate();

try {
// ...
} finally {
$s2->detach();
$c2->end();
}
} finally {
$s1->detach();
$c1->end();
}

$tp->shutdown();
64 changes: 64 additions & 0 deletions examples/spansuppression/semanticconventionssuppression-3.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\Example;

use OpenTelemetry\API\Common\Time\Clock;
use OpenTelemetry\API\Trace\SpanKind;
use OpenTelemetry\API\Trace\SpanSuppression\SemanticConvention;
use OpenTelemetry\Contrib\Otlp\SpanExporter;
use OpenTelemetry\SDK\Common\Export\Stream\StreamTransportFactory;
use OpenTelemetry\SDK\Resource\ResourceInfoFactory;
use OpenTelemetry\SDK\Trace\SpanProcessor\BatchSpanProcessor;
use OpenTelemetry\SDK\Trace\SpanSuppression\SemanticConventionSuppressionStrategy\SemanticConventionSuppressionStrategy;
use OpenTelemetry\SDK\Trace\TracerProviderBuilder;

require_once __DIR__ . '/../../vendor/autoload.php';

// Nested Twig template rendering

$tp = (new TracerProviderBuilder())
->setResource(ResourceInfoFactory::emptyResource())
->addSpanProcessor(new BatchSpanProcessor(new SpanExporter((new StreamTransportFactory())->create('php://stdout', 'application/x-ndjson')), Clock::getDefault()))
->setSpanSuppressionStrategy(new SemanticConventionSuppressionStrategy([
new class() implements \OpenTelemetry\API\Trace\SpanSuppression\SemanticConventionResolver {
#[\Override]
public function resolveSemanticConventions(string $name, ?string $version, ?string $schemaUrl): array
{
if ($name !== 'io.open-telemetry.php.twig') {
return [];
}

return [
new SemanticConvention('io.open-telemetry.php.twig.template.render', SpanKind::KIND_INTERNAL, ['twig.template.name'], []),
];
}
},
]))
->build()
;

$t = $tp->getTracer('io.open-telemetry.php.twig');
$c1 = $t->spanBuilder('render index.html.twig')->setAttribute('twig.template.name', 'index.html.twig')->startSpan();
$s1 = $c1->activate();

try {
$c2 = $t->spanBuilder('render header.html.twig')->setAttribute('twig.template.name', 'header.html.twig')->startSpan();
$s2 = $c2->activate();

try {
for ($i = 0; $i < 5; $i++) {
$t->spanBuilder('render meta.html.twig')->setAttribute('twig.template.name', 'meta.html.twig')->startSpan()->end();
}
// ...
} finally {
$s2->detach();
$c2->end();
}
} finally {
$s1->detach();
$c1->end();
}

$tp->shutdown();
44 changes: 44 additions & 0 deletions examples/spansuppression/spankindsuppression.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\Example;

use OpenTelemetry\API\Common\Time\Clock;
use OpenTelemetry\API\Trace\SpanKind;
use OpenTelemetry\Contrib\Otlp\SpanExporter;
use OpenTelemetry\SDK\Common\Export\Stream\StreamTransportFactory;
use OpenTelemetry\SDK\Resource\ResourceInfoFactory;
use OpenTelemetry\SDK\Trace\SpanProcessor\BatchSpanProcessor;
use OpenTelemetry\SDK\Trace\SpanSuppression\SpanKindSuppressionStrategy\SpanKindSuppressionStrategy;
use OpenTelemetry\SDK\Trace\TracerProviderBuilder;

require_once __DIR__ . '/../../vendor/autoload.php';

$tp = (new TracerProviderBuilder())
->setResource(ResourceInfoFactory::emptyResource())
->addSpanProcessor(new BatchSpanProcessor(new SpanExporter((new StreamTransportFactory())->create('php://stdout', 'application/x-ndjson')), Clock::getDefault()))
->setSpanSuppressionStrategy(new SpanKindSuppressionStrategy())
->build()
;

$t = $tp->getTracer('test');
$c1 = $t->spanBuilder('client-1')->setSpanKind(SpanKind::KIND_CLIENT)->startSpan();
$s1 = $c1->activate();

try {
$c2 = $t->spanBuilder('client-2')->setSpanKind(SpanKind::KIND_CLIENT)->startSpan();
$s2 = $c2->activate();

try {
// ...
} finally {
$s2->detach();
$c2->end();
}
} finally {
$s1->detach();
$c1->end();
}

$tp->shutdown();
2 changes: 1 addition & 1 deletion src/API/Trace/Span.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ final public function activate(): ScopeInterface

/** @inheritDoc */
#[\Override]
final public function storeInContext(ContextInterface $context): ContextInterface
public function storeInContext(ContextInterface $context): ContextInterface
{
if (LocalRootSpan::isLocalRoot($context)) {
$context = LocalRootSpan::store($context, $this);
Expand Down
22 changes: 22 additions & 0 deletions src/API/Trace/SpanSuppression/SemanticConvention.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\API\Trace\SpanSuppression;

/**
* @experimental
*/
final class SemanticConvention
{
/**
* @param list<string> $samplingAttributes
*/
public function __construct(
public readonly string $name,
public readonly int $spanKind,
public readonly array $samplingAttributes,
public readonly array $attributes,
) {
}
}
16 changes: 16 additions & 0 deletions src/API/Trace/SpanSuppression/SemanticConventionResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\API\Trace\SpanSuppression;

/**
* @experimental
*/
interface SemanticConventionResolver
{
/**
* @return list<SemanticConvention>
*/
public function resolveSemanticConventions(string $name, ?string $version, ?string $schemaUrl): array;
}
2 changes: 1 addition & 1 deletion src/API/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
},
"extra": {
"branch-alias": {
"dev-main": "1.4.x-dev"
"dev-main": "1.7.x-dev"
},
"spi": {
"OpenTelemetry\\API\\Instrumentation\\AutoInstrumentation\\HookManagerInterface": [
Expand Down
13 changes: 12 additions & 1 deletion src/SDK/Trace/Span.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
use OpenTelemetry\SDK\Common\Exception\StackTraceFormatter;
use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
use OpenTelemetry\SDK\Resource\ResourceInfo;
use OpenTelemetry\SDK\Trace\SpanSuppression\NoopSuppressionStrategy\NoopSuppression;
use OpenTelemetry\SDK\Trace\SpanSuppression\SpanSuppression;
use Throwable;

final class Span extends API\Span implements ReadWriteSpanInterface
Expand Down Expand Up @@ -44,6 +46,7 @@ private function __construct(
private array $links,
private int $totalRecordedLinks,
private readonly int $startEpochNanos,
private readonly SpanSuppression $spanSuppression,
) {
$this->status = StatusData::unset();
}
Expand Down Expand Up @@ -73,6 +76,7 @@ public static function startSpan(
array $links,
int $totalRecordedLinks,
int $startEpochNanos,
SpanSuppression $spanSuppression = new NoopSuppression(),
): self {
$span = new self(
$name,
Expand All @@ -86,7 +90,8 @@ public static function startSpan(
$attributesBuilder,
$links,
$totalRecordedLinks,
$startEpochNanos !== 0 ? $startEpochNanos : Clock::getDefault()->now()
$startEpochNanos !== 0 ? $startEpochNanos : Clock::getDefault()->now(),
$spanSuppression,
);

// Call onStart here to ensure the span is fully initialized.
Expand All @@ -111,6 +116,12 @@ public static function formatStackTrace(Throwable $e, ?array &$seen = null): str
return StackTraceFormatter::format($e);
}

#[\Override]
public function storeInContext(ContextInterface $context): ContextInterface
{
return $this->spanSuppression->suppress(parent::storeInContext($context));
}

/** @inheritDoc */
#[\Override]
public function getContext(): API\SpanContextInterface
Expand Down
Loading
Loading