From 7b757885b6bd7f2014b510894d55812e3879b05f Mon Sep 17 00:00:00 2001 From: Norbert Orzechowicz Date: Fri, 22 Feb 2019 12:59:13 +0100 Subject: [PATCH] Added possibility to register many monolog handlers --- .../AppInsightsPHPExtension.php | 48 +++++++++++++++---- DependencyInjection/Configuration.php | 25 ++++++++++ README.md | 16 +++++++ .../AppInsightsPHPExtensionTest.php | 23 +++++++++ .../DependencyInjection/ConfigurationTest.php | 26 ++++++++++ composer.json | 2 +- 6 files changed, 130 insertions(+), 10 deletions(-) diff --git a/DependencyInjection/AppInsightsPHPExtension.php b/DependencyInjection/AppInsightsPHPExtension.php index 40aa880..e5866ba 100644 --- a/DependencyInjection/AppInsightsPHPExtension.php +++ b/DependencyInjection/AppInsightsPHPExtension.php @@ -4,6 +4,7 @@ namespace AppInsightsPHP\Symfony\AppInsightsPHPBundle\DependencyInjection; +use AppInsightsPHP\Monolog\Handler\AppInsightsTraceHandler; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; @@ -19,19 +20,10 @@ public function load(array $configs, ContainerBuilder $container) $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); $loader->load('app_insights_php.xml'); - $loader->load('app_insights_php_monolog.xml'); $container->setParameter('app_insights_php.instrumentation_key', $config['instrumentation_key']); $container->setParameter('app_insights_php.doctrine.track_dependency', $config['doctrine']['track_dependency']); - if ($config['doctrine']['track_dependency']) { - if (!class_exists('AppInsightsPHP\\Doctrine\\DBAL\\Logging\\DependencyLogger')) { - throw new \RuntimeException('Please first run `composer require download app-insights-php/doctrine-dependency-logger` if you want to log DBAL queries.'); - } - - $loader->load('app_insights_php_doctrine.xml'); - } - $container->setDefinition('app_insights_php.configuration.exceptions', new Definition(\AppInsightsPHP\Client\Configuration\Exceptions::class, [ $config['exceptions']['enabled'], @@ -64,5 +56,43 @@ public function load(array $configs, ContainerBuilder $container) ); $container->getDefinition('app_insights_php.telemetry.factory')->replaceArgument(1, new Reference('app_insights_php.configuration')); + + // Doctrine + if ($config['doctrine']['track_dependency']) { + if (!class_exists('AppInsightsPHP\\Doctrine\\DBAL\\Logging\\DependencyLogger')) { + throw new \RuntimeException('Please first run `composer require download app-insights-php/doctrine-dependency-logger` if you want to log DBAL queries.'); + } + + $loader->load('app_insights_php_doctrine.xml'); + } + + // Monolog + if (\count($config['monolog']['handlers'])) { + foreach ($config['monolog']['handlers'] as $name => $handlerConfig) { + $id = sprintf(sprintf('app_insights_php.monolog.handler.%s', $name)); + + switch ($handlerConfig['type']) { + case 'trace': + $class = AppInsightsTraceHandler::class; + $arguments = [ + new Reference('app_insights_php.telemetry'), + $this->levelToMonologConst($handlerConfig['level']), + (bool) $handlerConfig['bubble'], + ]; + break; + default: + throw new \RuntimeException('Unrecognized monolog handler type %s', $handlerConfig['type']); + } + + $container->register($id, $class) + ->setArguments($arguments) + ->setPublic(false); + } + } + } + + private function levelToMonologConst($level) + { + return \is_int($level) ? $level : \constant('Monolog\Logger::'.strtoupper($level)); } } diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index b55845c..d60cfa3 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -4,6 +4,7 @@ namespace AppInsightsPHP\Symfony\AppInsightsPHPBundle\DependencyInjection; +use Monolog\Logger; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; @@ -14,6 +15,8 @@ public function getConfigTreeBuilder() $treeBuilder = new TreeBuilder('app_insights_php'); $rootNode = method_exists(TreeBuilder::class, 'getRootNode') ? $treeBuilder->getRootNode() : $treeBuilder->root('app_insights_php'); + $allowedLoggerTypes = ['trace']; + $rootNode ->children() ->booleanNode('enabled')->defaultTrue()->end() @@ -51,6 +54,28 @@ public function getConfigTreeBuilder() ->booleanNode('track_dependency')->defaultFalse()->end() ->end() ->end() + ->arrayNode('monolog') + ->addDefaultsIfNotSet() + ->children() + ->arrayNode('handlers') + ->canBeUnset() + ->useAttributeAsKey('name') + ->arrayPrototype() + ->children() + ->scalarNode('name')->end() + ->scalarNode('level')->defaultValue(Logger::DEBUG)->end() + ->scalarNode('bubble')->defaultTrue()->end() + ->scalarNode('type') + ->defaultValue('trace') + ->validate() + ->ifNotInArray($allowedLoggerTypes) + ->thenInvalid(sprintf('Allowed types: [%s]', implode(', ', $allowedLoggerTypes))) + ->end() + ->end() + ->end() + ->end() + ->end() + ->end() ->end() ; diff --git a/README.md b/README.md index 26deade..6fe616b 100644 --- a/README.md +++ b/README.md @@ -79,4 +79,20 @@ app_insights_php: enabled: true doctrine: track_dependency: true + monolog: + handlers: + trace: # register: app_insights_php.monolog.handler.trace - service + type: trace + level: DEBUG + bubble: true + foo: # register: app_insights_php.monolog.handler.foo - service + type: trace + level: ERROR + bubble: true + +monolog: + handlers: + app_insights: + type: service + id: "app_insights_php.monolog.handler.trace" ``` diff --git a/Tests/DependencyInjection/AppInsightsPHPExtensionTest.php b/Tests/DependencyInjection/AppInsightsPHPExtensionTest.php index f691381..e13232e 100644 --- a/Tests/DependencyInjection/AppInsightsPHPExtensionTest.php +++ b/Tests/DependencyInjection/AppInsightsPHPExtensionTest.php @@ -6,7 +6,9 @@ use AppInsightsPHP\Client\Client; use AppInsightsPHP\Doctrine\DBAL\Logging\DependencyLogger; +use AppInsightsPHP\Monolog\Handler\AppInsightsTraceHandler; use AppInsightsPHP\Symfony\AppInsightsPHPBundle\DependencyInjection\AppInsightsPHPExtension; +use Monolog\Logger; use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\KernelInterface; @@ -96,4 +98,25 @@ public function test_ignored_exceptions_configuration() $this->assertTrue($this->container->get('app_insights_php.configuration')->exceptions()->isIgnored(\RuntimeException::class)); $this->assertFalse($this->container->get('app_insights_php.configuration')->exceptions()->isIgnored(\Exception::class)); } + + public function test_monolog_configuration() + { + $extension = new AppInsightsPHPExtension(); + $extension->load( + [[ + 'instrumentation_key' => 'test_key', + 'monolog' => [ + 'handlers' => [ + [ + 'name' => 'foo.logger', + 'level' => Logger::DEBUG, + ], + ], + ], + ]], + $this->container + ); + + $this->assertInstanceOf(AppInsightsTraceHandler::class, $this->container->get('app_insights_php.monolog.handler.foo.logger')); + } } diff --git a/Tests/DependencyInjection/ConfigurationTest.php b/Tests/DependencyInjection/ConfigurationTest.php index cd6a1d5..cd2a6b7 100644 --- a/Tests/DependencyInjection/ConfigurationTest.php +++ b/Tests/DependencyInjection/ConfigurationTest.php @@ -5,6 +5,7 @@ namespace AppInsightsPHP\Symfony\AppInsightsPHPBundle\Tests\DependencyInjection; use AppInsightsPHP\Symfony\AppInsightsPHPBundle\DependencyInjection\Configuration; +use Monolog\Logger; use PHPUnit\Framework\TestCase; use Symfony\Component\Config\Definition\Processor; @@ -24,6 +25,31 @@ public function test_default_configuration() $this->assertTrue($config['enabled']); $this->assertEquals([], $config['exceptions']['ignored_exceptions']); $this->assertFalse($config['doctrine']['track_dependency']); + $this->assertEmpty($config['monolog']['handlers']); + } + + public function test_monolog_configuration() + { + $configs = [ + [ + 'instrumentation_key' => 'test_key', + 'monolog' => [ + 'handlers' => [ + [ + 'name' => 'foo.logger', + 'level' => Logger::DEBUG, + ], + ], + ], + ], + ]; + + $config = $this->process($configs); + + $this->assertArrayHasKey('foo.logger', $config['monolog']['handlers']); + $this->assertEquals(Logger::DEBUG, $config['monolog']['handlers']['foo.logger']['level']); + $this->assertTrue($config['monolog']['handlers']['foo.logger']['bubble']); + $this->assertEquals('trace', $config['monolog']['handlers']['foo.logger']['type']); } protected function process($configs) diff --git a/composer.json b/composer.json index ee108c2..ae27dae 100644 --- a/composer.json +++ b/composer.json @@ -20,7 +20,7 @@ }, "require": { "php": "^7.1", - "app-insights-php/monolog-handler": "^0.1", + "app-insights-php/monolog-handler": "^0.1.1", "symfony/framework-bundle": "^3.4|^4.0", "guzzlehttp/guzzle": "^6.0" },