Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Opentelemetry Auto Class Symfony Laravel Package

eerzho/opentelemetry-auto-class-symfony

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install Dependencies: Ensure ext-opentelemetry is installed (PECL or via Docker) and PHP ≥8.2, Symfony ≥6.0.

    pecl install opentelemetry
    composer require eerzho/opentelemetry-auto-class-symfony
    
  2. Register Bundle: Add to config/bundles.php:

    return [
        OpenTelemetry\Contrib\Instrumentation\Class\Symfony\TraceableBundle::class => ['all' => true],
    ];
    
  3. Annotate a Service: Add #[Traceable] to a container-managed class:

    #[Traceable]
    class OrderService {
        public function create(array $items) { /* Auto-traced */ }
    }
    
  4. Verify Tracing: Trigger the method and check your OpenTelemetry backend (e.g., Jaeger) for spans named: App\Service\OrderService::create.

First Use Case

Debugging a Slow API Endpoint:

  1. Annotate the controller/service handling the endpoint with #[Traceable].
  2. Reproduce the slow request.
  3. Analyze the trace in Jaeger to identify bottlenecks (e.g., external API calls, database queries) without manual instrumentation.

Implementation Patterns

Core Workflows

  1. Attribute-Based Instrumentation:

    • Global Tracing: Annotate entire classes (#[Traceable]) for full method coverage.
    • Selective Tracing: Exclude methods/arguments:
      #[Traceable(exclude: ['healthCheck'])]
      class PaymentService { ... }
      
    • Custom Span Names:
      #[Traceable(name: "ProcessOrder")]
      class OrderProcessor { ... }
      
  2. Integration with Symfony Services:

    • Command Bus: Trace command handlers:
      #[Traceable]
      class ProcessOrderCommandHandler { ... }
      
    • Event Listeners: Instrument listeners for async workflows:
      #[Traceable]
      class OrderCreatedListener { ... }
      
    • Repositories: Trace Doctrine/QueryBuilder methods:
      #[Traceable]
      class OrderRepository { ... }
      
  3. Context Propagation:

    • Leverage OpenTelemetry’s context propagation for cross-service traces (e.g., HTTP clients, message queues).
    • Pair with symfony/http-client instrumentation for full request/response tracing.

Advanced Patterns

  1. Dynamic Tracing:

    • Use #[Arguments(exclude: [...])] to hide sensitive data (e.g., passwords, tokens) in spans.
    • Example:
      #[Arguments(exclude: ['creditCard'])]
      public function charge(CreditCard $card, float $amount) { ... }
      
  2. Conditional Instrumentation:

    • Disable tracing for specific environments via OTEL_PHP_DISABLED_INSTRUMENTATIONS=class.
    • Use Symfony’s %kernel.environment% to toggle via compiler passes:
      if ('prod' !== $container->getParameter('kernel.environment')) {
          $container->setParameter('otel.class.instrumentation.enabled', false);
      }
      
  3. Custom Span Attributes:

    • Extend spans programmatically by accessing the active tracer in methods:
      use OpenTelemetry\API\Trace\TracerInterface;
      
      #[Traceable]
      class AnalyticsService {
          public function __construct(private TracerInterface $tracer) {}
      
          public function trackEvent(string $event) {
              $span = $this->tracer->spanBuilder('track_event')->startSpan();
              $span->setAttribute('event.type', $event);
              // ...
          }
      }
      

Integration Tips

  1. Symfony Compiler Passes:

    • Extend the bundle’s compiler pass to add custom logic (e.g., dynamic attribute parsing):
      // src/Compiler/TraceablePass.php
      use OpenTelemetry\Contrib\Instrumentation\Class\Symfony\Compiler\TraceableCompilerPass;
      
      class CustomTraceablePass extends TraceableCompilerPass {
          public function process(ContainerConfigurator $container): void {
              // Custom logic (e.g., filter services by tag)
              $container->attributes()
                  ->loadFromConfig($this->findServicesToInstrument());
          }
      }
      
  2. OpenTelemetry Configuration:

    • Configure the PHP extension via opentelemetry.ini:
      opentelemetry.sampler = always_on
      opentelemetry.exporter = otlp
      opentelemetry.endpoint = "http://otel-collector:4317"
      
  3. Testing:

    • Mock the tracer in PHPUnit:
      use OpenTelemetry\API\Trace\TracerInterface;
      
      $tracer = $this->createMock(TracerInterface);
      $this->container->set(TracerInterface::class, $tracer);
      
    • Verify spans with:
      $tracer->expects($this->once())->method('spanBuilder')->with('App\Service\OrderService::create');
      

Gotchas and Tips

Pitfalls

  1. Extension Dependency:

    • Issue: ext-opentelemetry may not be available in shared hosting or CI environments.
    • Fix: Use Docker or local PECL installation. Add a CI check:
      php -m | grep opentelemetry || exit 1
      
  2. Container Compilation Errors:

    • Issue: Conflicts with other compiler passes (e.g., proxies, decorators).
    • Fix: Ensure TraceableBundle is loaded after conflicting passes in bundles.php.
  3. Attribute Reflection Overhead:

    • Issue: Scanning classes for #[Traceable] may slow container compilation.
    • Fix: Benchmark with symfony/var-dumper:
      php bin/console debug:container --env=prod --dump
      
  4. Span Name Collisions:

    • Issue: Default span names (e.g., App\Service\Method::name) may be too verbose.
    • Fix: Use name parameter:
      #[Traceable(name: "Order.Created")]
      
  5. Argument Serialization:

    • Issue: Complex objects (e.g., DTOs, collections) may not serialize cleanly.
    • Fix: Implement __toString() or use #[Arguments(exclude: [...])] for sensitive data.
  6. Symfony 7+ Changes:

    • Issue: Future Symfony versions may alter container compilation.
    • Fix: Monitor Symfony’s RFCs and update the bundle accordingly.

Debugging Tips

  1. Verify Instrumentation:

    • Check container parameters for traced methods:
      php bin/console debug:container --parameter=otel.class.instrumentation.methods
      
  2. Disable Tracing Temporarily:

    • Set environment variable:
      OTEL_PHP_DISABLED_INSTRUMENTATIONS=class bin/console your:command
      
  3. Log Spans:

    • Use OpenTelemetry’s console exporter for debugging:
      opentelemetry.exporter = console
      
  4. Check for Missing Spans:

    • Ensure the service is autowired (not manually instantiated):
      // ❌ Won't be traced (new instance)
      $service = new OrderService();
      
      // ✅ Will be traced (container-managed)
      $service = $container->get(OrderService::class);
      

Configuration Quirks

  1. Bundle Loading Order:

    • Load TraceableBundle after FrameworkBundle to avoid conflicts:
      return [
          Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
          OpenTelemetry\Contrib\Instrumentation\Class\Symfony\TraceableBundle::class => ['all' => true],
      ];
      
  2. Environment-Specific Tracing:

    • Disable in dev environment via compiler pass:
      if ('dev' === $container->getParameter('kernel.environment')) {
          $container->setParameter('otel.class.instrumentation.enabled', false);
      }
      
  3. Custom Attribute Parsing:

    • Extend the attribute class to add custom logic:
      namespace App\Attribute;
      
      use OpenTelemetry\Contrib\Instrumentation\Class\Attribute\Traceable as BaseTraceable;
      
      #[Attribute(Attribute::TARGET_CLASS)]
      class Traceable extends BaseTraceable {
          public function __construct(
              public array $customConfig = [],
              public bool $logArguments = true
          ) {}
      }
      

Extension Points

  1. Custom Compiler Pass:
    • Override the default pass to filter services dynamically:
      use OpenTelemetry\Contrib\Instrumentation\Class\Symfony\Compiler\TraceableCompilerPass;
      
      class CustomTraceablePass extends TraceableCompilerPass {
          protected function getServicesToInstrument
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
besmartand-pro/php-quality-config
sentix/ai-chatbot
codifyo/ts-generator-bundle
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor