Passed
Push — master ( 8cd72e...2db2f3 )
by Tobias
02:40
created

EkinoNewRelicExtension::getInteractorServiceId()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 17
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 17
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 7
nc 5
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of Ekino New Relic bundle.
7
 *
8
 * (c) Ekino - Thomas Rabaix <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace  Ekino\NewRelicBundle\DependencyInjection;
15
16
use Ekino\NewRelicBundle\Listener\CommandListener;
17
use Ekino\NewRelicBundle\Listener\RequestListener;
18
use Ekino\NewRelicBundle\Listener\ResponseListener;
19
use Ekino\NewRelicBundle\NewRelic\AdaptiveInteractor;
20
use Ekino\NewRelicBundle\NewRelic\BlackholeInteractor;
21
use Ekino\NewRelicBundle\NewRelic\Config;
22
use Ekino\NewRelicBundle\NewRelic\LoggingInteractorDecorator;
23
use Ekino\NewRelicBundle\NewRelic\NewRelicInteractor;
24
use Ekino\NewRelicBundle\NewRelic\NewRelicInteractorInterface;
25
use Ekino\NewRelicBundle\TransactionNamingStrategy\ControllerNamingStrategy;
26
use Ekino\NewRelicBundle\TransactionNamingStrategy\RouteNamingStrategy;
27
use Ekino\NewRelicBundle\TransactionNamingStrategy\TransactionNamingStrategyInterface;
28
use Symfony\Component\Config\FileLocator;
29
use Symfony\Component\DependencyInjection\ContainerBuilder;
30
use Symfony\Component\DependencyInjection\ContainerInterface;
31
use Symfony\Component\DependencyInjection\Loader;
32
use Symfony\Component\DependencyInjection\Reference;
33
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
34
35
/**
36
 * This is the class that loads and manages your bundle configuration.
37
 *
38
 * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html}
39
 */
40
class EkinoNewRelicExtension extends Extension
41
{
42
    public function load(array $configs, ContainerBuilder $container): void
43
    {
44
        $configuration = new Configuration();
45
        $config = $this->processConfiguration($configuration, $configs);
46
47
        $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
48
        $loader->load('services.xml');
49
50
        $container->setAlias(NewRelicInteractorInterface::class, $this->getInteractorServiceId($config))->setPublic(false);
51
        $container->setAlias(TransactionNamingStrategyInterface::class, $this->getTransactionNamingServiceId($config))->setPublic(false);
52
53
        if ($config['logging']) {
54
            $container->register(LoggingInteractorDecorator::class)
55
                ->setDecoratedService(NewRelicInteractorInterface::class)
56
                ->setArguments(
57
                    [
58
                        '$interactor' => new Reference(LoggingInteractorDecorator::class.'.inner'),
59
                        '$logger' => new Reference('logger', ContainerInterface::NULL_ON_INVALID_REFERENCE),
60
                    ]
61
                )
62
                ->setPublic(false)
63
            ;
64
        }
65
66
        if (empty($config['deployment_names'])) {
67
            $config['deployment_names'] = \array_values(\array_filter(\explode(';', $config['application_name'] ?? '')));
68
        }
69
70
        $container->getDefinition(Config::class)
71
            ->setArguments(
72
                [
73
                    '$name' => $config['application_name'],
74
                    '$apiKey' => $config['api_key'],
75
                    '$licenseKey' => $config['license_key'],
76
                    '$xmit' => $config['xmit'],
77
                    '$deploymentNames' => $config['deployment_names'],
78
                ]
79
            );
80
81
        if ($config['http']['enabled']) {
82
            $loader->load('http_listener.xml');
83
            $container->getDefinition(RequestListener::class)
84
                ->setArguments(
85
                    [
86
                        '$ignoreRoutes' => $config['http']['ignored_routes'],
87
                        '$ignoredPaths' => $config['http']['ignored_paths'],
88
                        '$symfonyCache' => $config['http']['using_symfony_cache'],
89
                    ]
90
                );
91
92
            $container->getDefinition(ResponseListener::class)
93
                ->setArguments(
94
                    [
95
                        '$instrument' => $config['instrument'],
96
                        '$symfonyCache' => $config['http']['using_symfony_cache'],
97
                    ]
98
                );
99
        }
100
101
        if ($config['commands']['enabled']) {
102
            $loader->load('command_listener.xml');
103
            $container->getDefinition(CommandListener::class)
104
                ->setArguments(
105
                    [
106
                        '$ignoredCommands' => $config['commands']['ignored_commands'],
107
                    ]
108
                );
109
        }
110
111
        if ($config['exceptions']['enabled']) {
112
            $loader->load('exception_listener.xml');
113
        }
114
115
        if ($config['deprecations']['enabled']) {
116
            $loader->load('deprecation_listener.xml');
117
        }
118
119
        if ($config['twig']) {
120
            $loader->load('twig.xml');
121
        }
122
123
        if ($config['enabled'] && $config['monolog']['enabled']) {
124
            if (!\class_exists(\Monolog\Handler\NewRelicHandler::class)) {
125
                throw new \LogicException('The "symfony/monolog-bundle" package must be installed in order to use "monolog" option.');
126
            }
127
            $loader->load('monolog.xml');
128
            $container->setParameter('ekino.new_relic.monolog.channels', $config['monolog']['channels']);
129
            $container->setAlias('ekino.new_relic.logs_handler', $config['monolog']['service'])->setPublic(false);
130
131
            $level = $config['monolog']['level'];
132
            // This service is used by MonologHandlerPass to inject into Monolog Service
133
            $container->findDefinition('ekino.new_relic.logs_handler')
134
                ->setArguments(
135
                    [
136
                        '$level' => \is_int($level) ? $level : \constant('Monolog\Logger::'.\strtoupper($level)),
137
                        '$appName' => $config['application_name'],
138
                    ]
139
                );
140
        }
141
    }
142
143
    private function getInteractorServiceId(array $config): string
144
    {
145
        if (!$config['enabled']) {
146
            return BlackholeInteractor::class;
147
        }
148
149
        if (!isset($config['interactor'])) {
150
            // Fallback on AdaptiveInteractor.
151
            return AdaptiveInteractor::class;
152
        }
153
154
        if ('auto' === $config['interactor']) {
155
            // Check if the extension is loaded or not
156
            return \extension_loaded('newrelic') ? NewRelicInteractor::class : BlackholeInteractor::class;
157
        }
158
159
        return $config['interactor'];
160
    }
161
162
    private function getTransactionNamingServiceId(array $config): string
163
    {
164
        switch ($config['http']['transaction_naming']) {
165
            case 'controller':
166
                return ControllerNamingStrategy::class;
167
            case 'route':
168
                return RouteNamingStrategy::class;
169
            case 'service':
170
                if (!isset($config['http']['transaction_naming_service'])) {
171
                    throw new \LogicException(
172
                        'When using the "service", transaction naming scheme, the "transaction_naming_service" config parameter must be set.'
173
                    );
174
                }
175
176
                return $config['http']['transaction_naming_service'];
177
            default:
178
                throw new \InvalidArgumentException(
179
                    \sprintf(
180
                        'Invalid transaction naming scheme "%s", must be "route", "controller" or "service".',
181
                        $config['http']['transaction_naming']
182
                    )
183
                );
184
        }
185
    }
186
}
187