Skip to content

Commit

Permalink
Merge cb70f50 into fa75bc3
Browse files Browse the repository at this point in the history
  • Loading branch information
gaelreyrol committed Mar 17, 2024
2 parents fa75bc3 + cb70f50 commit 6e9e0de
Show file tree
Hide file tree
Showing 22 changed files with 456 additions and 30 deletions.
25 changes: 25 additions & 0 deletions src/DependencyInjection/Compiler/HttpKernelTracerLocatorPass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class HttpKernelTracerLocatorPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
if ($container->has('open_telemetry.instrumentation.http_kernel.trace.event_subscriber')) {
$tracers = $container->findTaggedServiceIds('open_telemetry.tracer');

if (0 !== count($tracers)) {
$traceableHttpKernelEventSubscriber = $container->getDefinition('open_telemetry.instrumentation.http_kernel.trace.event_subscriber');
$traceableHttpKernelEventSubscriber->setArgument(
'$tracerLocator',
ServiceLocatorTagPass::register($container, $tracers),
);
}
}
}
}
32 changes: 32 additions & 0 deletions src/DependencyInjection/Compiler/SetInstrumentationTypePass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class SetInstrumentationTypePass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
if ($container->hasParameter('open_telemetry.instrumentation.console.type')) {
$consoleInstrumentationType = $container->getParameter('open_telemetry.instrumentation.console.type');
if ($container->hasDefinition('open_telemetry.instrumentation.console.trace.event_subscriber')) {
}
}

if ($container->hasParameter('open_telemetry.instrumentation.http_kernel.type')) {
$httpKernelInstrumentationType = $container->getParameter('open_telemetry.instrumentation.http_kernel.type');
if ($container->hasDefinition('open_telemetry.instrumentation.http_kernel.trace.event_subscriber')) {
$container->getDefinition('open_telemetry.instrumentation.http_kernel.trace.event_subscriber')
->addMethodCall('setInstrumentationType', [$httpKernelInstrumentationType]);
}
}

if ($container->hasParameter('open_telemetry.instrumentation.messenger.type')) {
$messengerInstrumentationType = $container->getParameter('open_telemetry.instrumentation.messenger.type');
if ($container->hasDefinition('open_telemetry.instrumentation.http_kernel.trace.event_subscriber')) {
}
}
}
}
14 changes: 14 additions & 0 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\DependencyInjection;

use FriendsOfOpenTelemetry\OpenTelemetryBundle\Instrumentation\InstrumentationTypeEnum;
use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\OtlpExporterCompressionEnum;
use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\OtlpExporterFormatEnum;
use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\OtlpExporterOptions;
Expand Down Expand Up @@ -84,6 +85,10 @@ private function addInstrumentationSection(ArrayNodeDefinition $node): void
->arrayNode('console')
->addDefaultsIfNotSet()
->children()
->enumNode('type')
->defaultValue(InstrumentationTypeEnum::Auto->value)
->values(array_map(fn (InstrumentationTypeEnum $type) => $type->value, InstrumentationTypeEnum::cases()))
->end()
->append($this->getTracingInstrumentationNode())
->append($this->getMeteringInstrumentationNode())
->end()
Expand All @@ -105,6 +110,10 @@ private function addInstrumentationSection(ArrayNodeDefinition $node): void
->arrayNode('http_kernel')
->addDefaultsIfNotSet()
->children()
->enumNode('type')
->defaultValue(InstrumentationTypeEnum::Auto->value)
->values(array_map(fn (InstrumentationTypeEnum $type) => $type->value, InstrumentationTypeEnum::cases()))
->end()
->append($this->getTracingInstrumentationNode())
->append($this->getMeteringInstrumentationNode())
->end()
Expand All @@ -119,6 +128,10 @@ private function addInstrumentationSection(ArrayNodeDefinition $node): void
->arrayNode('messenger')
->addDefaultsIfNotSet()
->children()
->enumNode('type')
->defaultValue(InstrumentationTypeEnum::Auto->value)
->values(array_map(fn (InstrumentationTypeEnum $type) => $type->value, InstrumentationTypeEnum::cases()))
->end()
->append($this->getTracingInstrumentationNode())
->append($this->getMeteringInstrumentationNode())
->end()
Expand Down Expand Up @@ -231,6 +244,7 @@ private function getTracingProvidersNode(): ArrayNodeDefinition
->isRequired()
->end()
->arrayNode('options')
->defaultValue([])
->scalarPrototype()->cannotBeEmpty()->end()
->end()
->end()
Expand Down
8 changes: 8 additions & 0 deletions src/DependencyInjection/OpenTelemetryExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\DependencyInjection;

use FriendsOfOpenTelemetry\OpenTelemetryBundle\Instrumentation\InstrumentationTypeEnum;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
use Symfony\Component\HttpKernel\DependencyInjection\ConfigurableExtension;

/**
* @phpstan-type InstrumentationConfig array{
* type?: string,
* tracing: TracingInstrumentationConfig,
* metering: MeteringInstrumentationConfig,
* }
Expand Down Expand Up @@ -77,6 +79,12 @@ private function loadInstrumentationParams(array $config, ContainerBuilder $cont
sprintf('open_telemetry.instrumentation.%s.tracing.enabled', $name),
$instrumentation['tracing']['enabled'],
);
if (isset($instrumentation['type'])) {
$container->setParameter(
sprintf('open_telemetry.instrumentation.%s.type', $name),
InstrumentationTypeEnum::from($instrumentation['type']),
);
}
$container->setParameter(
sprintf('open_telemetry.instrumentation.%s.tracing.tracer', $name),
$instrumentation['tracing']['tracer'] ?? 'default_tracer',
Expand Down
8 changes: 7 additions & 1 deletion src/DependencyInjection/OpenTelemetryTracesExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ public function __invoke(array $config, ContainerBuilder $container): void

if (null !== $defaultTracer) {
$this->container->setAlias('open_telemetry.traces.default_tracer', new Reference(sprintf('open_telemetry.traces.tracers.%s', $defaultTracer)));

// $container->registerAttributeForAutoconfiguration(Traceable::class, static function (ChildDefinition $definition, Traceable $attribute) {
// $tracer = null !== $attribute->tracer ? $attribute->tracer : 'open_telemetry.traces.default_tracer';
// $definition->addTag('open_telemetry.traceable', ['tracer' => new Reference($tracer)]);
// });
}
}

Expand Down Expand Up @@ -144,6 +149,7 @@ private function loadTraceTracer(string $name, array $tracer): void
->setArguments([
$tracer['name'] ?? $this->container->getParameter('open_telemetry.bundle.name'),
$tracer['version'] ?? $this->container->getParameter('open_telemetry.bundle.version'),
]);
])
->addTag('open_telemetry.tracer');
}
}
12 changes: 12 additions & 0 deletions src/Instrumentation/Attribute/Traceable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\Instrumentation\Attribute;

#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD)]
class Traceable
{
public function __construct(
public readonly ?string $tracer = null,
) {
}
}
9 changes: 9 additions & 0 deletions src/Instrumentation/InstrumentationTypeEnum.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\Instrumentation;

enum InstrumentationTypeEnum: string
{
case Auto = 'auto';
case Attribute = 'attribute';
}
8 changes: 8 additions & 0 deletions src/Instrumentation/InstrumentationTypeInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\Instrumentation;

interface InstrumentationTypeInterface
{
public function setInstrumentationType(InstrumentationTypeEnum $type): void;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?php

namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\Instrumentation\Symfony\Framework\Routing;

use FriendsOfOpenTelemetry\OpenTelemetryBundle\Instrumentation\Attribute\Traceable;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\Config\Loader\LoaderResolverInterface;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;

class TraceableRouteLoader implements LoaderInterface
{
public const DEFAULT_KEY = '_traceable';
public const TRACER_KEY = '_tracer';
public const OPTION_KEY = 'traceable';

public function __construct(private LoaderInterface $loader)
{
}

public function load(mixed $resource, ?string $type = null): RouteCollection
{
$routes = $this->loader->load($resource, $type);

/** @var Route $route */
foreach ($routes as $route) {
self::parseAttribute($route);

$traceable = $route->getOption(self::OPTION_KEY);
if (null !== $traceable) {
$route->addDefaults([
self::DEFAULT_KEY => $traceable,
self::TRACER_KEY => $route->getOption(self::TRACER_KEY),
]);
}
}

return $routes;
}

public function supports(mixed $resource, ?string $type = null): bool
{
return $this->loader->supports($resource, $type);
}

public function getResolver(): LoaderResolverInterface
{
return $this->loader->getResolver();
}

public function setResolver(LoaderResolverInterface $resolver): void
{
$this->loader->setResolver($resolver);
}

private static function parseAttribute(Route $route): void
{
try {
$controller = $route->getDefault('_controller');
if (true === str_contains($controller, '::')) {
$reflection = new \ReflectionMethod($controller);
} else {
$reflection = new \ReflectionClass($controller);
}
} catch (\ReflectionException) {
return;
}

$attribute = $reflection->getAttributes(Traceable::class)[0] ?? $reflection->getDeclaringClass()->getAttributes(Traceable::class)[0] ?? null;

if (null !== $attribute) {
$traceable = $attribute->newInstance();
$route->addOptions([
self::OPTION_KEY => true,
self::TRACER_KEY => $traceable->tracer ?? null,
]);
}
}
}
Loading

0 comments on commit 6e9e0de

Please sign in to comment.