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

FriendsOfOpenTelemetry / opentelemetry-bundle / 7707420518

30 Jan 2024 06:55AM UTC coverage: 66.178% (+1.7%) from 64.527%
7707420518

Pull #38

github

gaelreyrol
wip
Pull Request #38: Refactor services injection

145 of 148 new or added lines in 9 files covered. (97.97%)

27 existing lines in 6 files now uncovered.

1444 of 2182 relevant lines covered (66.18%)

11.91 hits per line

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

98.55
/src/DependencyInjection/OpenTelemetryMetricsExtension.php
1
<?php
2

3
namespace FriendsOfOpenTelemetry\OpenTelemetryBundle\DependencyInjection;
4

5
use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterDsn;
6
use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Exporter\ExporterOptionsInterface;
7
use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MeterProvider\ExemplarFilterEnum;
8
use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MeterProvider\MeterProviderEnum;
9
use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MeterProvider\MeterProviderFactoryInterface;
10
use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Metric\MetricExporter\MetricExporterEnum;
11
use OpenTelemetry\SDK\Metrics\MeterProviderInterface;
12
use Symfony\Component\DependencyInjection\ChildDefinition;
13
use Symfony\Component\DependencyInjection\ContainerBuilder;
14
use Symfony\Component\DependencyInjection\Reference;
15

16
/**
17
 * @phpstan-import-type ExporterOptions from ExporterOptionsInterface
18
 */
19
final class OpenTelemetryMetricsExtension
20
{
21
    /**
22
     * @var array<string, mixed>
23
     */
24
    private array $config;
25

26
    private ContainerBuilder $container;
27

28
    /**
29
     * @param array{
30
     *     default_meter?: string,
31
     *     meters: array<string, mixed>,
32
     *     exporters: array<string, mixed>,
33
     *     providers: array<string, mixed>
34
     * }|array<string, mixed> $config
35
     */
36
    public function __invoke(array $config, ContainerBuilder $container): void
37
    {
38
        $this->config = $config;
12✔
39
        $this->container = $container;
12✔
40

41
        foreach ($this->config['exporters'] as $name => $exporter) {
12✔
42
            $this->loadMetricExporter($name, $exporter);
2✔
43
        }
44

45
        foreach ($this->config['providers'] as $name => $provider) {
12✔
46
            $this->loadMetricProvider($name, $provider);
6✔
47
        }
48

49
        foreach ($this->config['meters'] as $name => $meter) {
12✔
50
            $this->loadMetricMeter($name, $meter);
12✔
51
        }
52

53
        $defaultMeter = null;
12✔
54
        if (0 < count($this->config['meters'])) {
12✔
55
            $defaultMeter = array_key_first($this->config['meters']);
12✔
56
        }
57

58
        if (null !== $defaultMeter) {
12✔
59
            $this->container->setAlias('open_telemetry.metrics.default_meter', new Reference(sprintf('open_telemetry.metrics.meters.%s', $defaultMeter)));
12✔
60
        }
61
    }
62

63
    /**
64
     * @param array{
65
     *     dsn: string,
66
     *     options?: ExporterOptions
67
     * } $options
68
     */
69
    private function loadMetricExporter(string $name, array $options): void
70
    {
71
        $exporterId = sprintf('open_telemetry.metrics.exporters.%s', $name);
2✔
72
        $dsn = ExporterDsn::fromString($options['dsn']);
2✔
73
        $exporter = MetricExporterEnum::from($dsn->getExporter());
2✔
74

75
        $exporterDefinitionsFactory = new ExporterDefinitionsFactory($this->container);
2✔
76

77
        $this->container
2✔
78
            ->setDefinition($exporterId, new ChildDefinition('open_telemetry.metrics.exporter'))
2✔
79
            ->setClass($exporter->getClass())
2✔
80
            ->setFactory([$exporter->getFactoryClass(), 'createExporter'])
2✔
81
            ->setArguments([
2✔
82
                '$dsn' => $exporterDefinitionsFactory->createExporterDsnDefinition($options['dsn']),
2✔
83
                '$options' => $exporterDefinitionsFactory->createExporterOptionsDefinition(
2✔
84
                    $options['options'] ?? [],
2✔
85
                    'open_telemetry.exporter_options.metric',
2✔
86
                    ExporterDefinitionsFactory::METRIC_EXPORTER_OPTIONS,
2✔
87
                ),
2✔
88
            ]);
2✔
89
    }
90

91
    /**
92
     * @param array{
93
     *     type: string,
94
     *     exporter?: string,
95
     *     filter?: string
96
     * } $provider
97
     */
98
    private function loadMetricProvider(string $name, array $provider): void
99
    {
100
        $providerId = sprintf('open_telemetry.metrics.providers.%s', $name);
6✔
101
        $options = $this->getMetricProviderOptions($provider);
6✔
102

103
        $this->container
6✔
104
            ->setDefinition($providerId, new ChildDefinition('open_telemetry.metrics.provider'))
6✔
105
            ->setClass($options['class'])
6✔
106
            ->setFactory([$options['factory'], 'createProvider'])
6✔
107
            ->setArguments([
6✔
108
                '$exporter' => $options['exporter'],
6✔
109
                '$filter' => $options['filter'],
6✔
110
            ]);
6✔
111
    }
112

113
    /**
114
     * @param array{
115
     *     type: string,
116
     *     exporter?: string,
117
     *     filter?: string,
118
     * } $provider
119
     *
120
     * @return array{
121
     *     factory: class-string<MeterProviderFactoryInterface>,
122
     *     class: class-string<MeterProviderInterface>,
123
     *     exporter: ?Reference,
124
     *     filter: ?Reference,
125
     * }
126
     */
127
    private function getMetricProviderOptions(array $provider): array
128
    {
129
        $providerEnum = MeterProviderEnum::from($provider['type']);
6✔
130
        $options = [
6✔
131
            'factory' => $providerEnum->getFactoryClass(),
6✔
132
            'class' => $providerEnum->getClass(),
6✔
133
            'exporter' => null,
6✔
134
            'filter' => null,
6✔
135
        ];
6✔
136

137
        if (MeterProviderEnum::Default === $providerEnum) {
6✔
138
            if (!isset($provider['exporter'])) {
2✔
UNCOV
139
                throw new \InvalidArgumentException('Exporter is not set');
×
140
            }
141
            $options['exporter'] = new Reference(sprintf('open_telemetry.metrics.exporters.%s', $provider['exporter']));
2✔
142
        }
143

144
        $filter = isset($provider['filter']) ? ExemplarFilterEnum::from($provider['filter']) : ExemplarFilterEnum::All;
6✔
145
        $options['filter'] = match ($filter) {
6✔
146
            ExemplarFilterEnum::WithSampledTrace => new Reference('open_telemetry.metrics.exemplar_filters.with_sampled_trace'),
6✔
147
            ExemplarFilterEnum::All => new Reference('open_telemetry.metrics.exemplar_filters.all'),
6✔
148
            ExemplarFilterEnum::None => new Reference('open_telemetry.metrics.exemplar_filters.none'),
6✔
149
        };
6✔
150

151
        return $options;
6✔
152
    }
153

154
    /**
155
     * @param array{
156
     *     provider: string,
157
     *     name?: string,
158
     *     version?: string,
159
     * } $meter
160
     */
161
    private function loadMetricMeter(string $name, array $meter): void
162
    {
163
        $meterId = sprintf('open_telemetry.metrics.meters.%s', $name);
12✔
164

165
        $this->container
12✔
166
            ->setDefinition($meterId, new ChildDefinition('open_telemetry.metrics.meter'))
12✔
167
            ->setPublic(true)
12✔
168
            ->setFactory([
12✔
169
                new Reference(sprintf('open_telemetry.metrics.providers.%s', $meter['provider'])),
12✔
170
                'getMeter',
12✔
171
            ])
12✔
172
            ->setArguments([
12✔
173
                $meter['name'] ?? $this->container->getParameter('open_telemetry.bundle.name'),
12✔
174
                $meter['version'] ?? $this->container->getParameter('open_telemetry.bundle.version'),
12✔
175
            ]);
12✔
176
    }
177
}
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