vendor/symfony/monolog-bundle/DependencyInjection/MonologExtension.php line 965
<?php/** This file is part of the Symfony package.** (c) Fabien Potencier <fabien@symfony.com>** For the full copyright and license information, please view the LICENSE* file that was distributed with this source code.*/namespace Symfony\Bundle\MonologBundle\DependencyInjection;use Monolog\Attribute\AsMonologProcessor;use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy;use Monolog\Handler\HandlerInterface;use Monolog\Logger;use Monolog\Processor\ProcessorInterface;use Monolog\Processor\PsrLogMessageProcessor;use Monolog\ResettableInterface;use Symfony\Bridge\Monolog\Handler\FingersCrossed\HttpCodeActivationStrategy;use Symfony\Bridge\Monolog\Processor\SwitchUserTokenProcessor;use Symfony\Bridge\Monolog\Processor\TokenProcessor;use Symfony\Bridge\Monolog\Processor\WebProcessor;use Symfony\Bundle\FullStack;use Symfony\Component\Config\FileLocator;use Symfony\Component\DependencyInjection\Argument\BoundArgument;use Symfony\Component\DependencyInjection\ChildDefinition;use Symfony\Component\DependencyInjection\ContainerBuilder;use Symfony\Component\DependencyInjection\Definition;use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;use Symfony\Component\DependencyInjection\Reference;use Symfony\Component\HttpKernel\DependencyInjection\Extension;use Symfony\Component\HttpKernel\Kernel;use Symfony\Contracts\HttpClient\HttpClientInterface;/*** MonologExtension is an extension for the Monolog library.** @author Jordi Boggiano <j.boggiano@seld.be>* @author Christophe Coevoet <stof@notk.org>*/class MonologExtension extends Extension{private $nestedHandlers = [];private $swiftMailerHandlers = [];private function levelToMonologConst($level, ContainerBuilder $container){if (null === $level || is_numeric($level)) {return $level;}if (defined('Monolog\Logger::'.strtoupper($level))) {return constant('Monolog\Logger::' . strtoupper($level));}if ($container->hasParameter($level)) {return $this->levelToMonologConst($container->getParameter($level), $container);}try {$logLevel = $container->resolveEnvPlaceholders($level, true);} catch (ParameterNotFoundException $notFoundException) {throw new \InvalidArgumentException(sprintf('Could not match "%s" to a log level.', $level));}if ($logLevel !== '' && $logLevel !== $level) {return $this->levelToMonologConst($logLevel, $container);}throw new \InvalidArgumentException(sprintf('Could not match "%s" to a log level.', $level));}/*** Loads the Monolog configuration.** @param array $configs An array of configuration settings* @param ContainerBuilder $container A ContainerBuilder instance*/public function load(array $configs, ContainerBuilder $container){if (class_exists(FullStack::class) && Kernel::MAJOR_VERSION < 5 && Logger::API >= 2) {throw new \RuntimeException('Symfony 5 is required for Monolog 2 support. Please downgrade Monolog to version 1.');}$configuration = $this->getConfiguration($configs, $container);$config = $this->processConfiguration($configuration, $configs);if (isset($config['handlers'])) {$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));$loader->load('monolog.xml');$container->setParameter('monolog.use_microseconds', $config['use_microseconds']);$handlers = [];foreach ($config['handlers'] as $name => $handler) {$handlers[$handler['priority']][] = ['id' => $this->buildHandler($container, $name, $handler),'channels' => empty($handler['channels']) ? null : $handler['channels'],];}$container->setParameter('monolog.swift_mailer.handlers',$this->swiftMailerHandlers);ksort($handlers);$sortedHandlers = [];foreach ($handlers as $priorityHandlers) {foreach (array_reverse($priorityHandlers) as $handler) {$sortedHandlers[] = $handler;}}$handlersToChannels = [];foreach ($sortedHandlers as $handler) {if (!in_array($handler['id'], $this->nestedHandlers)) {$handlersToChannels[$handler['id']] = $handler['channels'];}}$container->setParameter('monolog.handlers_to_channels', $handlersToChannels);}$container->setParameter('monolog.additional_channels', isset($config['channels']) ? $config['channels'] : []);if (method_exists($container, 'registerForAutoconfiguration')) {if (interface_exists(ProcessorInterface::class)) {$container->registerForAutoconfiguration(ProcessorInterface::class)->addTag('monolog.processor');} else {$container->registerForAutoconfiguration(WebProcessor::class)->addTag('monolog.processor');}if (interface_exists(ResettableInterface::class)) {$container->registerForAutoconfiguration(ResettableInterface::class)->addTag('kernel.reset', ['method' => 'reset']);}$container->registerForAutoconfiguration(TokenProcessor::class)->addTag('monolog.processor');if (interface_exists(HttpClientInterface::class)) {$handlerAutoconfiguration = $container->registerForAutoconfiguration(HandlerInterface::class);$handlerAutoconfiguration->setBindings($handlerAutoconfiguration->getBindings() + [HttpClientInterface::class => new BoundArgument(new Reference('monolog.http_client'), false),]);}}if (80000 <= \PHP_VERSION_ID && method_exists($container, 'registerAttributeForAutoconfiguration')) {$container->registerAttributeForAutoconfiguration(AsMonologProcessor::class, static function (ChildDefinition $definition, AsMonologProcessor $attribute, \Reflector $reflector): void {$tagAttributes = get_object_vars($attribute);if ($reflector instanceof \ReflectionMethod) {if (isset($tagAttributes['method'])) {throw new \LogicException(sprintf('AsMonologProcessor attribute cannot declare a method on "%s::%s()".', $reflector->class, $reflector->name));}$tagAttributes['method'] = $reflector->getName();}$definition->addTag('monolog.processor', $tagAttributes);});}}/*** Returns the base path for the XSD files.** @return string The XSD base path*/public function getXsdValidationBasePath(){return __DIR__.'/../Resources/config/schema';}public function getNamespace(){return 'http://symfony.com/schema/dic/monolog';}private function buildHandler(ContainerBuilder $container, $name, array $handler){$handlerId = $this->getHandlerId($name);if ('service' === $handler['type']) {$container->setAlias($handlerId, $handler['id']);if (!empty($handler['nested']) && true === $handler['nested']) {$this->markNestedHandler($handlerId);}return $handlerId;}$handlerClass = $this->getHandlerClassByType($handler['type']);$definition = new Definition($handlerClass);$handler['level'] = $this->levelToMonologConst($handler['level'], $container);if ($handler['include_stacktraces']) {$definition->setConfigurator(['Symfony\\Bundle\\MonologBundle\\MonologBundle', 'includeStacktraces']);}if (null === $handler['process_psr_3_messages']['enabled']) {$handler['process_psr_3_messages']['enabled'] = !isset($handler['handler']) && !$handler['members'];}if ($handler['process_psr_3_messages']['enabled'] && method_exists($handlerClass, 'pushProcessor')) {$processorId = $this->buildPsrLogMessageProcessor($container, $handler['process_psr_3_messages']);$definition->addMethodCall('pushProcessor', [new Reference($processorId)]);}switch ($handler['type']) {case 'stream':$definition->setArguments([$handler['path'],$handler['level'],$handler['bubble'],$handler['file_permission'],$handler['use_locking'],]);break;case 'console':$definition->setArguments([null,$handler['bubble'],isset($handler['verbosity_levels']) ? $handler['verbosity_levels'] : [],$handler['console_formatter_options']]);$definition->addTag('kernel.event_subscriber');break;case 'chromephp':case 'firephp':$definition->setArguments([$handler['level'],$handler['bubble'],]);$definition->addTag('kernel.event_listener', ['event' => 'kernel.response', 'method' => 'onKernelResponse']);break;case 'gelf':if (isset($handler['publisher']['id'])) {$publisher = new Reference($handler['publisher']['id']);} elseif (class_exists('Gelf\Transport\UdpTransport')) {$transport = new Definition("Gelf\Transport\UdpTransport", [$handler['publisher']['hostname'],$handler['publisher']['port'],$handler['publisher']['chunk_size'],]);$transport->setPublic(false);$publisher = new Definition('Gelf\Publisher', []);$publisher->addMethodCall('addTransport', [$transport]);$publisher->setPublic(false);} elseif (class_exists('Gelf\MessagePublisher')) {$publisher = new Definition('Gelf\MessagePublisher', [$handler['publisher']['hostname'],$handler['publisher']['port'],$handler['publisher']['chunk_size'],]);$publisher->setPublic(false);} else {throw new \RuntimeException('The gelf handler requires the graylog2/gelf-php package to be installed');}$definition->setArguments([$publisher,$handler['level'],$handler['bubble'],]);break;case 'mongo':if (isset($handler['mongo']['id'])) {$client = new Reference($handler['mongo']['id']);} else {$server = 'mongodb://';if (isset($handler['mongo']['user'])) {$server .= $handler['mongo']['user'].':'.$handler['mongo']['pass'].'@';}$server .= $handler['mongo']['host'].':'.$handler['mongo']['port'];$client = new Definition('MongoDB\Client', [$server,]);$client->setPublic(false);}$definition->setArguments([$client,$handler['mongo']['database'],$handler['mongo']['collection'],$handler['level'],$handler['bubble'],]);break;case 'elasticsearch':@trigger_error('The "elasticsearch" handler type is deprecated in MonologBundle since version 3.8.0, use the "elastica" type instead, or switch to the official Elastic client using the "elastic_search" type.', E_USER_DEPRECATED);// no breakcase 'elastica':case 'elastic_search':if (isset($handler['elasticsearch']['id'])) {$client = new Reference($handler['elasticsearch']['id']);} else {if ($handler['type'] === 'elastic_search') {// v8 has a new Elastic\ prefix$client = new Definition(class_exists('Elastic\Elasticsearch\Client') ? 'Elastic\Elasticsearch\Client' : 'Elasticsearch\Client');$factory = class_exists('Elastic\Elasticsearch\ClientBuilder') ? 'Elastic\Elasticsearch\ClientBuilder' : 'Elasticsearch\ClientBuilder';$client->setFactory([$factory, 'fromConfig']);$clientArguments = ['host' => $handler['elasticsearch']['host'],];if (isset($handler['elasticsearch']['user'], $handler['elasticsearch']['password'])) {$clientArguments['basicAuthentication'] = [$handler['elasticsearch']['user'], $handler['elasticsearch']['password']];}} else {$client = new Definition('Elastica\Client');$clientArguments = ['host' => $handler['elasticsearch']['host'],'port' => $handler['elasticsearch']['port'],'transport' => $handler['elasticsearch']['transport'],];if (isset($handler['elasticsearch']['user'], $handler['elasticsearch']['password'])) {$clientArguments['headers'] = ['Authorization' => 'Basic ' . base64_encode($handler['elasticsearch']['user'] . ':' . $handler['elasticsearch']['password'])];}}$client->setArguments([$clientArguments]);$client->setPublic(false);}// elastica handler definition$definition->setArguments([$client,['index' => $handler['index'],'type' => $handler['document_type'],'ignore_error' => $handler['ignore_error']],$handler['level'],$handler['bubble'],]);break;case 'telegram':if (!class_exists('Monolog\Handler\TelegramBotHandler')) {throw new \RuntimeException('The TelegramBotHandler is not available. Please update "monolog/monolog" to 2.2.0');}$definition->setArguments([$handler['token'],$handler['channel'],$handler['level'],$handler['bubble'],$handler['parse_mode'],$handler['disable_webpage_preview'],$handler['disable_notification'],$handler['split_long_messages'],$handler['delay_between_messages'],]);break;case 'redis':case 'predis':if (isset($handler['redis']['id'])) {$clientId = $handler['redis']['id'];} elseif ('redis' === $handler['type']) {if (!class_exists(\Redis::class)) {throw new \RuntimeException('The \Redis class is not available.');}$client = new Definition(\Redis::class);$client->addMethodCall('connect', [$handler['redis']['host'], $handler['redis']['port']]);$client->addMethodCall('auth', [$handler['redis']['password']]);$client->addMethodCall('select', [$handler['redis']['database']]);$client->setPublic(false);$clientId = uniqid('monolog.redis.client.', true);$container->setDefinition($clientId, $client);} else {if (!class_exists(\Predis\Client::class)) {throw new \RuntimeException('The \Predis\Client class is not available.');}$client = new Definition(\Predis\Client::class);$client->setArguments([$handler['redis']['host'],]);$client->setPublic(false);$clientId = uniqid('monolog.predis.client.', true);$container->setDefinition($clientId, $client);}$definition->setArguments([new Reference($clientId),$handler['redis']['key_name'],$handler['level'],$handler['bubble'],]);break;case 'rotating_file':$definition->setArguments([$handler['path'],$handler['max_files'],$handler['level'],$handler['bubble'],$handler['file_permission'],$handler['use_locking'],]);$definition->addMethodCall('setFilenameFormat', [$handler['filename_format'],$handler['date_format'],]);break;case 'fingers_crossed':$handler['action_level'] = $this->levelToMonologConst($handler['action_level'], $container);if (null !== $handler['passthru_level']) {$handler['passthru_level'] = $this->levelToMonologConst($handler['passthru_level'], $container);}$nestedHandlerId = $this->getHandlerId($handler['handler']);$this->markNestedHandler($nestedHandlerId);$activation = $handler['action_level'];if (class_exists(SwitchUserTokenProcessor::class)) {$activation = new Definition(ErrorLevelActivationStrategy::class, [$activation]);}if (isset($handler['activation_strategy'])) {$activation = new Reference($handler['activation_strategy']);} elseif (!empty($handler['excluded_404s'])) {if (class_exists(HttpCodeActivationStrategy::class)) {@trigger_error('The "excluded_404s" option is deprecated in MonologBundle since version 3.4.0, you should rely on the "excluded_http_codes" option instead.', E_USER_DEPRECATED);}$activationDef = new Definition('Symfony\Bridge\Monolog\Handler\FingersCrossed\NotFoundActivationStrategy', [new Reference('request_stack'),$handler['excluded_404s'],$activation]);$container->setDefinition($handlerId.'.not_found_strategy', $activationDef);$activation = new Reference($handlerId.'.not_found_strategy');} elseif (!empty($handler['excluded_http_codes'])) {if (!class_exists('Symfony\Bridge\Monolog\Handler\FingersCrossed\HttpCodeActivationStrategy')) {throw new \LogicException('"excluded_http_codes" cannot be used as your version of Monolog bridge does not support it.');}$activationDef = new Definition('Symfony\Bridge\Monolog\Handler\FingersCrossed\HttpCodeActivationStrategy', [new Reference('request_stack'),$handler['excluded_http_codes'],$activation]);$container->setDefinition($handlerId.'.http_code_strategy', $activationDef);$activation = new Reference($handlerId.'.http_code_strategy');}$definition->setArguments([new Reference($nestedHandlerId),$activation,$handler['buffer_size'],$handler['bubble'],$handler['stop_buffering'],$handler['passthru_level'],]);break;case 'filter':$handler['min_level'] = $this->levelToMonologConst($handler['min_level'], $container);$handler['max_level'] = $this->levelToMonologConst($handler['max_level'], $container);foreach (array_keys($handler['accepted_levels']) as $k) {$handler['accepted_levels'][$k] = $this->levelToMonologConst($handler['accepted_levels'][$k], $container);}$nestedHandlerId = $this->getHandlerId($handler['handler']);$this->markNestedHandler($nestedHandlerId);$minLevelOrList = !empty($handler['accepted_levels']) ? $handler['accepted_levels'] : $handler['min_level'];$definition->setArguments([new Reference($nestedHandlerId),$minLevelOrList,$handler['max_level'],$handler['bubble'],]);break;case 'buffer':$nestedHandlerId = $this->getHandlerId($handler['handler']);$this->markNestedHandler($nestedHandlerId);$definition->setArguments([new Reference($nestedHandlerId),$handler['buffer_size'],$handler['level'],$handler['bubble'],$handler['flush_on_overflow'],]);break;case 'deduplication':$nestedHandlerId = $this->getHandlerId($handler['handler']);$this->markNestedHandler($nestedHandlerId);$defaultStore = '%kernel.cache_dir%/monolog_dedup_'.sha1($handlerId);$definition->setArguments([new Reference($nestedHandlerId),isset($handler['store']) ? $handler['store'] : $defaultStore,$handler['deduplication_level'],$handler['time'],$handler['bubble'],]);break;case 'group':case 'whatfailuregroup':case 'fallbackgroup':$references = [];foreach ($handler['members'] as $nestedHandler) {$nestedHandlerId = $this->getHandlerId($nestedHandler);$this->markNestedHandler($nestedHandlerId);$references[] = new Reference($nestedHandlerId);}$definition->setArguments([$references,$handler['bubble'],]);break;case 'syslog':$definition->setArguments([$handler['ident'],$handler['facility'],$handler['level'],$handler['bubble'],$handler['logopts'],]);break;case 'syslogudp':$definition->setArguments([$handler['host'],$handler['port'],$handler['facility'],$handler['level'],$handler['bubble'],]);if ($handler['ident']) {$definition->addArgument($handler['ident']);}break;case 'swift_mailer':$mailer = $handler['mailer'] ?: 'mailer';if (isset($handler['email_prototype'])) {if (!empty($handler['email_prototype']['method'])) {$prototype = [new Reference($handler['email_prototype']['id']), $handler['email_prototype']['method']];} else {$prototype = new Reference($handler['email_prototype']['id']);}} else {$messageFactory = new Definition('Symfony\Bundle\MonologBundle\SwiftMailer\MessageFactory');$messageFactory->setLazy(true);$messageFactory->setPublic(false);$messageFactory->setArguments([new Reference($mailer),$handler['from_email'],$handler['to_email'],$handler['subject'],$handler['content_type']]);$messageFactoryId = sprintf('%s.mail_message_factory', $handlerId);$container->setDefinition($messageFactoryId, $messageFactory);// set the prototype as a callable$prototype = [new Reference($messageFactoryId), 'createMessage'];}$definition->setArguments([new Reference($mailer),$prototype,$handler['level'],$handler['bubble'],]);$this->swiftMailerHandlers[] = $handlerId;$definition->addTag('kernel.event_listener', ['event' => 'kernel.terminate', 'method' => 'onKernelTerminate']);$definition->addTag('kernel.event_listener', ['event' => 'console.terminate', 'method' => 'onCliTerminate']);break;case 'native_mailer':$definition->setArguments([$handler['to_email'],$handler['subject'],$handler['from_email'],$handler['level'],$handler['bubble'],]);if (!empty($handler['headers'])) {$definition->addMethodCall('addHeader', [$handler['headers']]);}break;case 'symfony_mailer':$mailer = $handler['mailer'] ?: 'mailer.mailer';if (isset($handler['email_prototype'])) {if (!empty($handler['email_prototype']['method'])) {$prototype = [new Reference($handler['email_prototype']['id']), $handler['email_prototype']['method']];} else {$prototype = new Reference($handler['email_prototype']['id']);}} else {$prototype = (new Definition('Symfony\Component\Mime\Email'))->setPublic(false)->addMethodCall('from', [$handler['from_email']])->addMethodCall('to', $handler['to_email'])->addMethodCall('subject', [$handler['subject']]);}$definition->setArguments([new Reference($mailer),$prototype,$handler['level'],$handler['bubble'],]);break;case 'socket':$definition->setArguments([$handler['connection_string'],$handler['level'],$handler['bubble'],]);if (isset($handler['timeout'])) {$definition->addMethodCall('setTimeout', [$handler['timeout']]);}if (isset($handler['connection_timeout'])) {$definition->addMethodCall('setConnectionTimeout', [$handler['connection_timeout']]);}if (isset($handler['persistent'])) {$definition->addMethodCall('setPersistent', [$handler['persistent']]);}break;case 'pushover':$definition->setArguments([$handler['token'],$handler['user'],$handler['title'],$handler['level'],$handler['bubble'],]);if (isset($handler['timeout'])) {$definition->addMethodCall('setTimeout', [$handler['timeout']]);}if (isset($handler['connection_timeout'])) {$definition->addMethodCall('setConnectionTimeout', [$handler['connection_timeout']]);}break;case 'hipchat':$definition->setArguments([$handler['token'],$handler['room'],$handler['nickname'],$handler['notify'],$handler['level'],$handler['bubble'],$handler['use_ssl'],$handler['message_format'],!empty($handler['host']) ? $handler['host'] : 'api.hipchat.com',!empty($handler['api_version']) ? $handler['api_version'] : 'v1',]);if (isset($handler['timeout'])) {$definition->addMethodCall('setTimeout', [$handler['timeout']]);}if (isset($handler['connection_timeout'])) {$definition->addMethodCall('setConnectionTimeout', [$handler['connection_timeout']]);}break;case 'slack':$definition->setArguments([$handler['token'],$handler['channel'],$handler['bot_name'],$handler['use_attachment'],$handler['icon_emoji'],$handler['level'],$handler['bubble'],$handler['use_short_attachment'],$handler['include_extra'],]);if (isset($handler['timeout'])) {$definition->addMethodCall('setTimeout', [$handler['timeout']]);}if (isset($handler['connection_timeout'])) {$definition->addMethodCall('setConnectionTimeout', [$handler['connection_timeout']]);}break;case 'slackwebhook':$definition->setArguments([$handler['webhook_url'],$handler['channel'],$handler['bot_name'],$handler['use_attachment'],$handler['icon_emoji'],$handler['use_short_attachment'],$handler['include_extra'],$handler['level'],$handler['bubble'],]);break;case 'slackbot':$definition->setArguments([$handler['team'],$handler['token'],urlencode($handler['channel']),$handler['level'],$handler['bubble'],]);break;case 'cube':$definition->setArguments([$handler['url'],$handler['level'],$handler['bubble'],]);break;case 'amqp':$definition->setArguments([new Reference($handler['exchange']),$handler['exchange_name'],$handler['level'],$handler['bubble'],]);break;case 'error_log':$definition->setArguments([$handler['message_type'],$handler['level'],$handler['bubble'],]);break;case 'sentry':if (null !== $handler['hub_id']) {$hub = new Reference($handler['hub_id']);} else {if (null !== $handler['client_id']) {$clientId = $handler['client_id'];} else {$options = new Definition('Sentry\\Options',[['dsn' => $handler['dsn']]]);if (!empty($handler['environment'])) {$options->addMethodCall('setEnvironment', [$handler['environment']]);}if (!empty($handler['release'])) {$options->addMethodCall('setRelease', [$handler['release']]);}$builder = new Definition('Sentry\\ClientBuilder', [$options]);$client = new Definition('Sentry\\Client');$client->setFactory([$builder, 'getClient']);$clientId = 'monolog.sentry.client.'.sha1($handler['dsn']);$container->setDefinition($clientId, $client);if (!$container->hasAlias('Sentry\\ClientInterface')) {$container->setAlias('Sentry\\ClientInterface', $clientId);}}$hub = new Definition('Sentry\\State\\Hub',[new Reference($clientId)]);$container->setDefinition(sprintf('monolog.handler.%s.hub', $name), $hub);// can't set the hub to the current hub, getting into a recursion otherwise...//$hub->addMethodCall('setCurrent', array($hub));}$definition->setArguments([$hub,$handler['level'],$handler['bubble'],$handler['fill_extra_context'],]);break;case 'raven':if (null !== $handler['client_id']) {$clientId = $handler['client_id'];} else {$client = new Definition('Raven_Client', [$handler['dsn'],['auto_log_stacks' => $handler['auto_log_stacks'],'environment' => $handler['environment']]]);$client->setPublic(false);$clientId = 'monolog.raven.client.'.sha1($handler['dsn']);$container->setDefinition($clientId, $client);}$definition->setArguments([new Reference($clientId),$handler['level'],$handler['bubble'],]);if (!empty($handler['release'])) {$definition->addMethodCall('setRelease', [$handler['release']]);}break;case 'loggly':$definition->setArguments([$handler['token'],$handler['level'],$handler['bubble'],]);if (!empty($handler['tags'])) {$definition->addMethodCall('setTag', [implode(',', $handler['tags'])]);}break;case 'logentries':$definition->setArguments([$handler['token'],$handler['use_ssl'],$handler['level'],$handler['bubble'],]);if (isset($handler['timeout'])) {$definition->addMethodCall('setTimeout', [$handler['timeout']]);}if (isset($handler['connection_timeout'])) {$definition->addMethodCall('setConnectionTimeout', [$handler['connection_timeout']]);}break;case 'insightops':$definition->setArguments([$handler['token'],$handler['region'] ? $handler['region'] : 'us',$handler['use_ssl'],$handler['level'],$handler['bubble'],]);break;case 'flowdock':$definition->setArguments([$handler['token'],$handler['level'],$handler['bubble'],]);if (empty($handler['formatter'])) {$formatter = new Definition("Monolog\Formatter\FlowdockFormatter", [$handler['source'],$handler['from_email'],]);$formatterId = 'monolog.flowdock.formatter.'.sha1($handler['source'].'|'.$handler['from_email']);$formatter->setPublic(false);$container->setDefinition($formatterId, $formatter);$definition->addMethodCall('setFormatter', [new Reference($formatterId)]);}break;case 'rollbar':if (!empty($handler['id'])) {$rollbarId = $handler['id'];} else {$config = $handler['config'] ?: [];$config['access_token'] = $handler['token'];$rollbar = new Definition('RollbarNotifier', [$config,]);$rollbarId = 'monolog.rollbar.notifier.'.sha1(json_encode($config));$rollbar->setPublic(false);$container->setDefinition($rollbarId, $rollbar);}$definition->setArguments([new Reference($rollbarId),$handler['level'],$handler['bubble'],]);break;case 'newrelic':$definition->setArguments([$handler['level'],$handler['bubble'],$handler['app_name'],]);break;case 'server_log':if (!class_exists('Symfony\Bridge\Monolog\Handler\ServerLogHandler')) {throw new \RuntimeException('The ServerLogHandler is not available. Please update "symfony/monolog-bridge" to 3.3.');}$definition->setArguments([$handler['host'],$handler['level'],$handler['bubble'],]);break;// Handlers using the constructor of AbstractHandler without adding their own argumentscase 'browser_console':case 'test':case 'null':case 'noop':case 'debug':$definition->setArguments([$handler['level'],$handler['bubble'],]);break;default:$nullWarning = '';if ($handler['type'] == '') {$nullWarning = ', if you meant to define a null handler in a yaml config, make sure you quote "null" so it does not get converted to a php null';}throw new \InvalidArgumentException(sprintf('Invalid handler type "%s" given for handler "%s"' . $nullWarning, $handler['type'], $name));}if (!empty($handler['nested']) && true === $handler['nested']) {$this->markNestedHandler($handlerId);}if (!empty($handler['formatter'])) {$definition->addMethodCall('setFormatter', [new Reference($handler['formatter'])]);}if (!in_array($handlerId, $this->nestedHandlers) && is_subclass_of($handlerClass, ResettableInterface::class)) {$definition->addTag('kernel.reset', ['method' => 'reset']);}$container->setDefinition($handlerId, $definition);return $handlerId;}private function markNestedHandler($nestedHandlerId){if (in_array($nestedHandlerId, $this->nestedHandlers)) {return;}$this->nestedHandlers[] = $nestedHandlerId;}private function getHandlerId($name){return sprintf('monolog.handler.%s', $name);}private function getHandlerClassByType($handlerType){$typeToClassMapping = ['stream' => 'Monolog\Handler\StreamHandler','console' => 'Symfony\Bridge\Monolog\Handler\ConsoleHandler','group' => 'Monolog\Handler\GroupHandler','buffer' => 'Monolog\Handler\BufferHandler','deduplication' => 'Monolog\Handler\DeduplicationHandler','rotating_file' => 'Monolog\Handler\RotatingFileHandler','syslog' => 'Monolog\Handler\SyslogHandler','syslogudp' => 'Monolog\Handler\SyslogUdpHandler','null' => 'Monolog\Handler\NullHandler','test' => 'Monolog\Handler\TestHandler','gelf' => 'Monolog\Handler\GelfHandler','rollbar' => 'Monolog\Handler\RollbarHandler','flowdock' => 'Monolog\Handler\FlowdockHandler','browser_console' => 'Monolog\Handler\BrowserConsoleHandler','firephp' => 'Symfony\Bridge\Monolog\Handler\FirePHPHandler','chromephp' => 'Symfony\Bridge\Monolog\Handler\ChromePhpHandler','debug' => 'Symfony\Bridge\Monolog\Handler\DebugHandler','swift_mailer' => 'Symfony\Bridge\Monolog\Handler\SwiftMailerHandler','native_mailer' => 'Monolog\Handler\NativeMailerHandler','symfony_mailer' => 'Symfony\Bridge\Monolog\Handler\MailerHandler','socket' => 'Monolog\Handler\SocketHandler','pushover' => 'Monolog\Handler\PushoverHandler','raven' => 'Monolog\Handler\RavenHandler','sentry' => 'Sentry\Monolog\Handler','newrelic' => 'Monolog\Handler\NewRelicHandler','hipchat' => 'Monolog\Handler\HipChatHandler','slack' => 'Monolog\Handler\SlackHandler','slackwebhook' => 'Monolog\Handler\SlackWebhookHandler','slackbot' => 'Monolog\Handler\SlackbotHandler','cube' => 'Monolog\Handler\CubeHandler','amqp' => 'Monolog\Handler\AmqpHandler','error_log' => 'Monolog\Handler\ErrorLogHandler','loggly' => 'Monolog\Handler\LogglyHandler','logentries' => 'Monolog\Handler\LogEntriesHandler','whatfailuregroup' => 'Monolog\Handler\WhatFailureGroupHandler','fingers_crossed' => 'Monolog\Handler\FingersCrossedHandler','filter' => 'Monolog\Handler\FilterHandler','mongo' => 'Monolog\Handler\MongoDBHandler','elasticsearch' => 'Monolog\Handler\ElasticSearchHandler','telegram' => 'Monolog\Handler\TelegramBotHandler','server_log' => 'Symfony\Bridge\Monolog\Handler\ServerLogHandler','redis' => 'Monolog\Handler\RedisHandler','predis' => 'Monolog\Handler\RedisHandler','insightops' => 'Monolog\Handler\InsightOpsHandler',];$v2HandlerTypesAdded = ['elastica' => 'Monolog\Handler\ElasticaHandler','elasticsearch' => 'Monolog\Handler\ElasticaHandler','elastic_search' => 'Monolog\Handler\ElasticsearchHandler','fallbackgroup' => 'Monolog\Handler\FallbackGroupHandler','noop' => 'Monolog\Handler\NoopHandler',];$v2HandlerTypesRemoved = ['hipchat','raven','slackbot',];$v3HandlerTypesRemoved = ['swift_mailer',];if (Logger::API >= 2) {$typeToClassMapping = array_merge($typeToClassMapping, $v2HandlerTypesAdded);foreach($v2HandlerTypesRemoved as $v2HandlerTypeRemoved) {unset($typeToClassMapping[$v2HandlerTypeRemoved]);}}if (Logger::API >= 3) {foreach($v3HandlerTypesRemoved as $v3HandlerTypeRemoved) {unset($typeToClassMapping[$v3HandlerTypeRemoved]);}}if (!isset($typeToClassMapping[$handlerType])) {if (Logger::API === 1 && array_key_exists($handlerType, $v2HandlerTypesAdded)) {throw new \InvalidArgumentException(sprintf('"%s" was added in Monolog v2, please upgrade if you wish to use it.', $handlerType));}if (Logger::API >= 2 && array_key_exists($handlerType, $v2HandlerTypesRemoved)) {throw new \InvalidArgumentException(sprintf('"%s" was removed in Monolog v2.', $handlerType));}if (Logger::API >= 3 && array_key_exists($handlerType, $v3HandlerTypesRemoved)) {throw new \InvalidArgumentException(sprintf('"%s" was removed in Monolog v3.', $handlerType));}throw new \InvalidArgumentException(sprintf('There is no handler class defined for handler "%s".', $handlerType));}return $typeToClassMapping[$handlerType];}private function buildPsrLogMessageProcessor(ContainerBuilder $container, array $processorOptions): string{static $hasConstructorArguments;if (!isset($hasConstructorArguments)) {$reflectionConstructor = (new \ReflectionClass(PsrLogMessageProcessor::class))->getConstructor();$hasConstructorArguments = null !== $reflectionConstructor && $reflectionConstructor->getNumberOfParameters() > 0;unset($reflectionConstructor);}$processorId = 'monolog.processor.psr_log_message';$processorArguments = [];unset($processorOptions['enabled']);if (!empty($processorOptions)) {if (!$hasConstructorArguments) {throw new \RuntimeException('Monolog 1.26 or higher is required for the "date_format" and "remove_used_context_fields" options to be used.');}$processorArguments = [$processorOptions['date_format'] ?? null,$processorOptions['remove_used_context_fields'] ?? false,];$processorId .= '.'.ContainerBuilder::hash($processorArguments);}if (!$container->hasDefinition($processorId)) {$processor = new Definition(PsrLogMessageProcessor::class);$processor->setPublic(false);$processor->setArguments($processorArguments);$container->setDefinition($processorId, $processor);}return $processorId;}}