• 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

90.91
/src/DependencyInjection/OpenTelemetryLogsExtension.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\Log\LogExporter\LogExporterEnum;
8
use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LoggerProvider\LoggerProviderEnum;
9
use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LoggerProvider\LoggerProviderFactoryInterface;
10
use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LogProcessor\LogProcessorEnum;
11
use FriendsOfOpenTelemetry\OpenTelemetryBundle\OpenTelemetry\Log\LogProcessor\LogProcessorFactoryInterface;
12
use OpenTelemetry\SDK\Logs\LoggerProviderInterface;
13
use OpenTelemetry\SDK\Logs\LogRecordProcessorInterface;
14
use Symfony\Component\DependencyInjection\ChildDefinition;
15
use Symfony\Component\DependencyInjection\ContainerBuilder;
16
use Symfony\Component\DependencyInjection\Reference;
17

18
/**
19
 * @phpstan-import-type ExporterOptions from ExporterOptionsInterface
20
 */
21
final class OpenTelemetryLogsExtension
22
{
23
    /**
24
     * @var array<string, mixed>
25
     */
26
    private array $config;
27
    private ContainerBuilder $container;
28

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

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

46
        foreach ($this->config['processors'] as $name => $processor) {
12✔
47
            $this->loadLogProcessor($name, $processor);
2✔
48
        }
49

50
        foreach ($this->config['providers'] as $name => $provider) {
12✔
51
            $this->loadLogProvider($name, $provider);
6✔
52
        }
53

54
        foreach ($this->config['loggers'] as $name => $logger) {
12✔
55
            $this->loadLogLogger($name, $logger);
12✔
56
        }
57

58
        $defaultLogger = null;
12✔
59
        if (0 < count($this->config['loggers'])) {
12✔
60
            $defaultLogger = array_key_first($this->config['loggers']);
12✔
61
        }
62

63
        if (null !== $defaultLogger) {
12✔
64
            $this->container->setAlias('open_telemetry.logs.default_logger', new Reference(sprintf('open_telemetry.logs.loggers.%s', $defaultLogger)));
12✔
65
        }
66
    }
67

68
    /**
69
     * @param array{
70
     *      dsn: string,
71
     *      options?: ExporterOptions
72
     *  } $options
73
     */
74
    private function loadLogExporter(string $name, array $options): void
75
    {
76
        $exporterId = sprintf('open_telemetry.logs.exporters.%s', $name);
2✔
77
        $dsn = ExporterDsn::fromString($options['dsn']);
2✔
78
        $exporter = LogExporterEnum::from($dsn->getExporter());
2✔
79

80
        $exporterDefinitionsFactory = new ExporterDefinitionsFactory($this->container);
2✔
81

82
        $this->container
2✔
83
            ->setDefinition($exporterId, new ChildDefinition('open_telemetry.logs.exporter'))
2✔
84
            ->setClass($exporter->getClass())
2✔
85
            ->setFactory([$exporter->getFactoryClass(), 'createExporter'])
2✔
86
            ->setArguments([
2✔
87
                '$dsn' => $exporterDefinitionsFactory->createExporterDsnDefinition($options['dsn']),
2✔
88
                '$options' => $exporterDefinitionsFactory->createExporterOptionsDefinition($options['options'] ?? []),
2✔
89
            ]);
2✔
90
    }
91

92
    /**
93
     * @param array{
94
     *      type: string,
95
     *      processors?: string[],
96
     *      exporter?: string
97
     *  } $processor
98
     */
99
    private function loadLogProcessor(string $name, array $processor): void
100
    {
101
        $processorId = sprintf('open_telemetry.logs.processors.%s', $name);
2✔
102
        $options = $this->getLogProcessorOptions($processor);
2✔
103

104
        $this->container
2✔
105
            ->setDefinition($processorId, new ChildDefinition('open_telemetry.logs.processor'))
2✔
106
            ->setClass($options['class'])
2✔
107
            ->setFactory([$options['factory'], 'createProcessor'])
2✔
108
            ->setArguments([
2✔
109
                '$processors' => $options['processors'],
2✔
110
                '$exporter' => $options['exporter'],
2✔
111
            ]);
2✔
112
    }
113

114
    /**
115
     * @param array{
116
     *     type: string,
117
     *     processors?: string[],
118
     *     exporter?: string
119
     * } $processor
120
     *
121
     * @return array{
122
     *     factory: class-string<LogProcessorFactoryInterface>,
123
     *     class: class-string<LogRecordProcessorInterface>,
124
     *     processors: ?Reference[],
125
     *     exporter: ?Reference,
126
     * }
127
     */
128
    private function getLogProcessorOptions(array $processor): array
129
    {
130
        $processorEnum = LogProcessorEnum::from($processor['type']);
2✔
131
        $options = [
2✔
132
            'factory' => $processorEnum->getFactoryClass(),
2✔
133
            'class' => $processorEnum->getClass(),
2✔
134
            'processors' => [],
2✔
135
            'exporter' => null,
2✔
136
        ];
2✔
137

138
        // if (LogProcessorEnum::Batch === $processorEnum) {
139
        //     // TODO: Check batch options
140
        //     clock: OpenTelemetry\SDK\Common\Time\SystemClock
141
        //     max_queue_size: 2048
142
        //     schedule_delay: 5000
143
        //     export_timeout: 30000
144
        //     max_export_batch_size: 512
145
        //     auto_flush: true
146
        // }
147

148
        if (LogProcessorEnum::Multi === $processorEnum) {
2✔
UNCOV
149
            if (!isset($processor['processors']) || 0 === count($processor['processors'])) {
×
UNCOV
150
                throw new \InvalidArgumentException('Processors are not set or empty');
×
151
            }
UNCOV
152
            $options['processors'] = array_map(
×
UNCOV
153
                fn (string $processor) => new Reference(sprintf('open_telemetry.logs.processors.%s', $processor)),
×
UNCOV
154
                $processor['processors'],
×
UNCOV
155
            );
×
156
        }
157

158
        if (LogProcessorEnum::Simple === $processorEnum) {
2✔
159
            if (!isset($processor['exporter'])) {
2✔
UNCOV
160
                throw new \InvalidArgumentException('Exporter is not set');
×
161
            }
162
            $options['exporter'] = new Reference(sprintf('open_telemetry.logs.exporters.%s', $processor['exporter']));
2✔
163
        }
164

165
        return $options;
2✔
166
    }
167

168
    /**
169
     * @param array{
170
     *     type: string,
171
     *     processor?: string,
172
     * } $provider
173
     */
174
    private function loadLogProvider(string $name, array $provider): void
175
    {
176
        $providerId = sprintf('open_telemetry.logs.providers.%s', $name);
6✔
177
        $options = $this->getLoggerProviderOptions($provider);
6✔
178

179
        $this->container
6✔
180
            ->setDefinition($providerId, new ChildDefinition('open_telemetry.logs.provider'))
6✔
181
            ->setClass($options['class'])
6✔
182
            ->setFactory([$options['factory'], 'createProvider'])
6✔
183
            ->setArguments([
6✔
184
                '$processor' => $options['processor'],
6✔
185
            ]);
6✔
186
    }
187

188
    /**
189
     * @param array{
190
     *     type: string,
191
     *     processor?: string,
192
     * } $provider
193
     *
194
     * @return array{
195
     *     factory: class-string<LoggerProviderFactoryInterface>,
196
     *     class: class-string<LoggerProviderInterface>,
197
     *     processor: ?Reference,
198
     * }
199
     */
200
    private function getLoggerProviderOptions(array $provider): array
201
    {
202
        $providerEnum = LoggerProviderEnum::from($provider['type']);
6✔
203
        $options = [
6✔
204
            'factory' => $providerEnum->getFactoryClass(),
6✔
205
            'class' => $providerEnum->getClass(),
6✔
206
            'processor' => null,
6✔
207
        ];
6✔
208

209
        if (LoggerProviderEnum::Default === $providerEnum) {
6✔
210
            if (!isset($provider['processor'])) {
2✔
UNCOV
211
                throw new \InvalidArgumentException('Processor is not set');
×
212
            }
213
            $options['processor'] = new Reference(sprintf('open_telemetry.logs.processors.%s', $provider['processor']));
2✔
214
        }
215

216
        return $options;
6✔
217
    }
218

219
    /**
220
     * @param array{
221
     *     provider: string,
222
     *     name?: string,
223
     *     version?: string,
224
     * } $logger
225
     */
226
    private function loadLogLogger(string $name, array $logger): void
227
    {
228
        $loggerId = sprintf('open_telemetry.logs.loggers.%s', $name);
12✔
229

230
        $this->container
12✔
231
            ->setDefinition($loggerId, new ChildDefinition('open_telemetry.logs.logger'))
12✔
232
            ->setPublic(true)
12✔
233
            ->setFactory([
12✔
234
                new Reference(sprintf('open_telemetry.logs.providers.%s', $logger['provider'])),
12✔
235
                'getLogger',
12✔
236
            ])
12✔
237
            ->setArguments([
12✔
238
                $logger['name'] ?? $this->container->getParameter('open_telemetry.bundle.name'),
12✔
239
                $logger['version'] ?? $this->container->getParameter('open_telemetry.bundle.version'),
12✔
240
            ]);
12✔
241
    }
242
}
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