• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

FriendsOfOpenTelemetry / opentelemetry-bundle / 24234674108

10 Apr 2026 08:46AM UTC coverage: 91.721% (+0.04%) from 91.68%
24234674108

Pull #209

github

web-flow
Merge 1cd270985 into c221a1e0c
Pull Request #209: feat(OpenTelemetry/Transport): replace Guzzle with Symfony HTTP Client and Nyholm PSR-7/17

30 of 30 new or added lines in 9 files covered. (100.0%)

7 existing lines in 1 file now uncovered.

2271 of 2476 relevant lines covered (91.72%)

59.4 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.6
/src/DependencyInjection/OpenTelemetryExtension.php
1
<?php
2

3
namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\DependencyInjection;
4

5
use Doctrine\Bundle\DoctrineBundle\DoctrineBundle;
6
use FriendsOfOpenTelemetry\OpenTelemetryBundle\Instrumentation\InstrumentationTypeEnum;
7
use Symfony\Bundle\TwigBundle\TwigBundle;
8
use Symfony\Component\Cache\CacheItem;
9
use Symfony\Component\Config\FileLocator;
10
use Symfony\Component\Console\Command\Command;
11
use Symfony\Component\DependencyInjection\ContainerBuilder;
12
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
13
use Symfony\Component\HttpClient\HttpClient;
14
use Symfony\Component\HttpKernel\DependencyInjection\ConfigurableExtension;
15
use Symfony\Component\Mailer\MailerInterface;
16
use Symfony\Component\Messenger\Envelope;
17

18
/**
19
 * @phpstan-type InstrumentationConfig array{
20
 *     type?: string,
21
 *     tracing: TracingInstrumentationConfig,
22
 *     metering: MeteringInstrumentationConfig,
23
 * }
24
 * @phpstan-type TracingInstrumentationConfig array{
25
 *     enabled: bool,
26
 *     tracer: ?string,
27
 *     exclude_paths?: string[],
28
 *     exclude_commands?: string[]
29
 * }
30
 * @phpstan-type MeteringInstrumentationConfig array{
31
 *     enabled: bool,
32
 *     meter: ?string,
33
 * }
34
 */
35
final class OpenTelemetryExtension extends ConfigurableExtension
36
{
37
    protected function loadInternal(array $mergedConfig, ContainerBuilder $container): void
38
    {
39
        $loader = new PhpFileLoader($container, new FileLocator(dirname(__DIR__).'/Resources/config'));
92✔
40
        $loader->load('services.php');
92✔
41

42
        $channels = $container->hasParameter('monolog.additional_channels')
92✔
43
            ? $container->getParameter('monolog.additional_channels')
28✔
44
            : [];
64✔
45
        $channels[] = 'open_telemetry';
92✔
46
        $container->setParameter('monolog.additional_channels', array_unique($channels));
92✔
47

48
        $loader->load('services_transports.php');
92✔
49
        $loader->load('services_logs.php');
92✔
50
        $loader->load('services_metrics.php');
92✔
51
        $loader->load('services_traces.php');
92✔
52
        $loader->load('services_tracing_instrumentation.php');
92✔
53
        $loader->load('services_metering_instrumentation.php');
92✔
54

55
        $this->registerService($mergedConfig['service'], $container);
92✔
56
        $this->registerInstrumentation($mergedConfig['instrumentation'], $container);
92✔
57

58
        (new OpenTelemetryTracesExtension())($mergedConfig['traces'], $container);
92✔
59
        (new OpenTelemetryMetricsExtension())($mergedConfig['metrics'], $container);
88✔
60
        (new OpenTelemetryLogsExtension())($mergedConfig['logs'], $container);
84✔
61
    }
62

63
    /**
64
     * @param array{
65
     *     namespace: string,
66
     *     name: string,
67
     *     version: string,
68
     *     environment: string
69
     * } $config
70
     */
71
    private function registerService(array $config, ContainerBuilder $container): void
72
    {
73
        $container->setParameter('open_telemetry.service.namespace', $config['namespace']);
92✔
74
        $container->setParameter('open_telemetry.service.name', $config['name']);
92✔
75
        $container->setParameter('open_telemetry.service.version', $config['version']);
92✔
76
        $container->setParameter('open_telemetry.service.environment', $config['environment']);
92✔
77

78
        $container->getDefinition('open_telemetry.resource_info')
92✔
79
            ->setArguments([
92✔
80
                $config['namespace'],
92✔
81
                $config['name'],
92✔
82
                $config['version'],
92✔
83
                $config['environment'],
92✔
84
            ]);
92✔
85
    }
86

87
    /**
88
     * @param array{
89
     *     cache: InstrumentationConfig,
90
     *     console: InstrumentationConfig,
91
     *     doctrine: InstrumentationConfig,
92
     *     http_client: InstrumentationConfig,
93
     *     http_kernel: InstrumentationConfig,
94
     *     mailer: InstrumentationConfig,
95
     *     messenger: InstrumentationConfig,
96
     *     twig: InstrumentationConfig,
97
     * } $config
98
     */
99
    private function registerInstrumentation(array $config, ContainerBuilder $container): void
100
    {
101
        $this->registerCacheTracingInstrumentationConfiguration($container, $config['cache']);
92✔
102

103
        $this->registerConsoleTracingInstrumentationConfiguration($container, $config['console']);
92✔
104
        $this->registerConsoleMeteringInstrumentationConfiguration($container, $config['console']);
92✔
105

106
        $this->registerDoctrineTracingInstrumentationConfiguration($container, $config['doctrine']);
92✔
107
        $this->registerHttpClientTracingInstrumentationConfiguration($container, $config['http_client']);
92✔
108

109
        $this->registerHttpKernelTracingInstrumentationConfiguration($container, $config['http_kernel']);
92✔
110
        $this->registerHttpKernelMeteringInstrumentationConfiguration($container, $config['http_kernel']);
92✔
111

112
        $this->registerMailerTracingInstrumentationConfiguration($container, $config['mailer']);
92✔
113
        $this->registerMessengerTracingInstrumentationConfiguration($container, $config['messenger']);
92✔
114
        $this->registerTwigTracingInstrumentationConfiguration($container, $config['twig']);
92✔
115
    }
116

117
    /**
118
     * @param InstrumentationConfig $config
119
     */
120
    private function registerCacheTracingInstrumentationConfiguration(ContainerBuilder $container, array $config): void
121
    {
122
        $isConfigEnabled = $this->isConfigEnabled($container, $config['tracing']);
92✔
123

124
        if ($isConfigEnabled && !class_exists(CacheItem::class)) {
92✔
UNCOV
125
            throw new \LogicException('Cache instrumentation cannot be enabled because the symfony/cache package is not installed.');
×
126
        }
127

128
        if (!$isConfigEnabled) {
92✔
129
            $container->removeDefinition('open_telemetry.instrumentation.cache.trace.adapter');
64✔
130
            $container->removeDefinition('open_telemetry.instrumentation.cache.trace.tag_aware_adapter');
64✔
131
        }
132

133
        $this->setTracingInstrumentationParams($container, 'cache', $config, $isConfigEnabled);
92✔
134
    }
135

136
    /**
137
     * @param InstrumentationConfig $config
138
     */
139
    private function registerConsoleTracingInstrumentationConfiguration(ContainerBuilder $container, array $config): void
140
    {
141
        $isConfigEnabled = $this->isConfigEnabled($container, $config['tracing']);
92✔
142

143
        if ($isConfigEnabled && !class_exists(Command::class)) {
92✔
UNCOV
144
            throw new \LogicException('Console instrumentation cannot be enabled because the symfony/console package is not installed.');
×
145
        }
146

147
        if (!$isConfigEnabled) {
92✔
148
            $container->removeDefinition('open_telemetry.instrumentation.console.trace.event_subscriber');
64✔
149
        }
150

151
        $this->setTracingInstrumentationParams($container, 'console', $config, $isConfigEnabled);
92✔
152
    }
153

154
    /**
155
     * @param InstrumentationConfig $config
156
     */
157
    private function registerConsoleMeteringInstrumentationConfiguration(ContainerBuilder $container, array $config): void
158
    {
159
        $isConfigEnabled = $this->isConfigEnabled($container, $config['metering']);
92✔
160

161
        if ($isConfigEnabled && !class_exists(Command::class)) {
92✔
UNCOV
162
            throw new \LogicException('Console instrumentation cannot be enabled because the symfony/console package is not installed.');
×
163
        }
164

165
        if (!$isConfigEnabled) {
92✔
166
            $container->removeDefinition('open_telemetry.instrumentation.console.metric.event_subscriber');
64✔
167
        }
168
    }
169

170
    /**
171
     * @param InstrumentationConfig $config
172
     */
173
    private function registerDoctrineTracingInstrumentationConfiguration(ContainerBuilder $container, array $config): void
174
    {
175
        $isConfigEnabled = $this->isConfigEnabled($container, $config['tracing']);
92✔
176

177
        if ($isConfigEnabled && !class_exists(DoctrineBundle::class)) {
92✔
178
            throw new \LogicException('DBAL tracing support cannot be enabled because the doctrine/doctrine-bundle Composer package is not installed.');
×
179
        }
180

181
        if (!$isConfigEnabled) {
92✔
182
            $container->removeDefinition('open_telemetry.instrumentation.doctrine.trace.middleware');
68✔
183
        }
184

185
        $this->setTracingInstrumentationParams($container, 'doctrine', $config, $isConfigEnabled);
92✔
186
    }
187

188
    /**
189
     * @param InstrumentationConfig $config
190
     */
191
    private function registerHttpClientTracingInstrumentationConfiguration(ContainerBuilder $container, array $config): void
192
    {
193
        $isConfigEnabled = $this->isConfigEnabled($container, $config['tracing']);
92✔
194

195
        if ($isConfigEnabled && !class_exists(HttpClient::class)) {
92✔
UNCOV
196
            throw new \LogicException('Http client tracing support cannot be enabled because the symfony/http-client Composer package is not installed.');
×
197
        }
198

199
        if (!$isConfigEnabled) {
92✔
200
            $container->removeDefinition('open_telemetry.instrumentation.http_client.trace.client');
64✔
201
        }
202

203
        $this->setTracingInstrumentationParams($container, 'http_client', $config, $isConfigEnabled);
92✔
204
    }
205

206
    /**
207
     * @param InstrumentationConfig $config
208
     */
209
    private function registerHttpKernelTracingInstrumentationConfiguration(ContainerBuilder $container, array $config): void
210
    {
211
        $isConfigEnabled = $this->isConfigEnabled($container, $config['tracing']);
92✔
212

213
        if (!$isConfigEnabled) {
92✔
214
            $container->removeDefinition('open_telemetry.instrumentation.http_kernel.trace.event_subscriber');
64✔
215
            $container->removeDefinition('open_telemetry.instrumentation.http_kernel.trace.route_loader');
64✔
216
        }
217

218
        $this->setTracingInstrumentationParams($container, 'http_kernel', $config, $isConfigEnabled);
92✔
219
    }
220

221
    /**
222
     * @param InstrumentationConfig $config
223
     */
224
    private function registerHttpKernelMeteringInstrumentationConfiguration(ContainerBuilder $container, array $config): void
225
    {
226
        $isConfigEnabled = $this->isConfigEnabled($container, $config['metering']);
92✔
227

228
        if (!$isConfigEnabled) {
92✔
229
            $container->removeDefinition('open_telemetry.instrumentation.http_kernel.metric.event_subscriber');
64✔
230
        }
231
    }
232

233
    /**
234
     * @param InstrumentationConfig $config
235
     */
236
    private function registerMailerTracingInstrumentationConfiguration(ContainerBuilder $container, array $config): void
237
    {
238
        $isConfigEnabled = $this->isConfigEnabled($container, $config['tracing']);
92✔
239

240
        if ($isConfigEnabled && !interface_exists(MailerInterface::class)) {
92✔
UNCOV
241
            throw new \LogicException('Mailer instrumentation cannot be enabled because the symfony/mailer package is not installed.');
×
242
        }
243

244
        if (!$isConfigEnabled) {
92✔
245
            $container->removeDefinition('open_telemetry.instrumentation.mailer.trace.transports');
64✔
246
            $container->removeDefinition('open_telemetry.instrumentation.mailer.trace.default_transport');
64✔
247
            $container->removeDefinition('open_telemetry.instrumentation.mailer.trace.mailer');
64✔
248
        }
249

250
        $this->setTracingInstrumentationParams($container, 'mailer', $config, $isConfigEnabled);
92✔
251
    }
252

253
    /**
254
     * @param InstrumentationConfig $config
255
     */
256
    private function registerMessengerTracingInstrumentationConfiguration(ContainerBuilder $container, array $config): void
257
    {
258
        $isConfigEnabled = $this->isConfigEnabled($container, $config['tracing']);
92✔
259

260
        if ($isConfigEnabled && !class_exists(Envelope::class)) {
92✔
UNCOV
261
            throw new \LogicException('Messenger instrumentation cannot be enabled because the symfony/messenger package is not installed.');
×
262
        }
263

264
        if (!$isConfigEnabled) {
92✔
265
            $container->removeAlias('messenger.transport.open_telemetry_tracer.factory');
64✔
266
            $container->removeAlias('messenger.middleware.open_telemetry_tracer');
64✔
267
            $container->removeDefinition('open_telemetry.instrumentation.messenger.trace.transport');
64✔
268
            $container->removeDefinition('open_telemetry.instrumentation.messenger.trace.transport_factory');
64✔
269
            $container->removeDefinition('open_telemetry.instrumentation.messenger.trace.middleware');
64✔
270
        }
271

272
        $this->setTracingInstrumentationParams($container, 'messenger', $config, $isConfigEnabled);
92✔
273
    }
274

275
    /**
276
     * @param InstrumentationConfig $config
277
     */
278
    private function registerTwigTracingInstrumentationConfiguration(ContainerBuilder $container, array $config): void
279
    {
280
        $isConfigEnabled = $this->isConfigEnabled($container, $config['tracing']);
92✔
281

282
        if ($isConfigEnabled && !class_exists(TwigBundle::class)) {
92✔
UNCOV
283
            throw new \LogicException('Twig instrumentation cannot be enabled because the symfony/twig-bundle package is not installed.');
×
284
        }
285

286
        if (!$isConfigEnabled) {
92✔
287
            $container->removeDefinition('open_telemetry.instrumentation.twig.trace.extension');
64✔
288
        }
289

290
        $this->setTracingInstrumentationParams($container, 'twig', $config, $isConfigEnabled);
92✔
291
    }
292

293
    /**
294
     * @param InstrumentationConfig $config
295
     */
296
    private function setTracingInstrumentationParams(ContainerBuilder $container, string $name, array $config, bool $enabled): void
297
    {
298
        $container->setParameter(sprintf('open_telemetry.instrumentation.%s.tracing.enabled', $name), $enabled);
92✔
299
        if (isset($config['type'])) {
92✔
300
            $container->setParameter(
92✔
301
                sprintf('open_telemetry.instrumentation.%s.type', $name),
92✔
302
                InstrumentationTypeEnum::from($config['type']),
92✔
303
            );
92✔
304
        }
305

306
        if ('http_kernel' === $name) {
92✔
307
            if (isset($config['tracing']['exclude_paths'])
92✔
308
                && 0 < \count($config['tracing']['exclude_paths'])
92✔
309
            ) {
310
                $container->setParameter(
12✔
311
                    sprintf('open_telemetry.instrumentation.%s.tracing.exclude_paths', $name),
12✔
312
                    $config['tracing']['exclude_paths'],
12✔
313
                );
12✔
314
            }
315
        }
316

317
        if ('console' === $name) {
92✔
318
            if (isset($config['tracing']['exclude_commands'])
92✔
319
                && 0 < \count($config['tracing']['exclude_commands'])
92✔
320
            ) {
321
                $container->setParameter(
12✔
322
                    sprintf('open_telemetry.instrumentation.%s.tracing.exclude_commands', $name),
12✔
323
                    $config['tracing']['exclude_commands'],
12✔
324
                );
12✔
325
            }
326
        }
327

328
        $container->setParameter(
92✔
329
            sprintf('open_telemetry.instrumentation.%s.tracing.tracer', $name),
92✔
330
            $config['tracing']['tracer'] ?? 'default_tracer',
92✔
331
        );
92✔
332
    }
333
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc