PageRenderTime 40ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/symfony/monolog-bundle/DependencyInjection/MonologExtension.php

https://gitlab.com/ineszribi/SmartBookStoreWeb
PHP | 626 lines | 520 code | 77 blank | 29 comment | 34 complexity | 730ba6e6ba84284188f6fefd511ceec1 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Bundle\MonologBundle\DependencyInjection;
  11. use Monolog\Formatter\ElasticaFormatter;
  12. use Monolog\Logger;
  13. use Symfony\Component\HttpKernel\DependencyInjection\Extension;
  14. use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
  15. use Symfony\Component\DependencyInjection\ContainerBuilder;
  16. use Symfony\Component\Config\FileLocator;
  17. use Symfony\Component\DependencyInjection\Definition;
  18. use Symfony\Component\DependencyInjection\Reference;
  19. use Symfony\Component\DependencyInjection\ContainerInterface;
  20. use Elastica\Client;
  21. /**
  22. * MonologExtension is an extension for the Monolog library.
  23. *
  24. * @author Jordi Boggiano <j.boggiano@seld.be>
  25. * @author Christophe Coevoet <stof@notk.org>
  26. */
  27. class MonologExtension extends Extension
  28. {
  29. private $nestedHandlers = array();
  30. private $swiftMailerHandlers = array();
  31. private function levelToMonologConst($level)
  32. {
  33. return is_int($level) ? $level : constant('Monolog\Logger::'.strtoupper($level));
  34. }
  35. /**
  36. * Loads the Monolog configuration.
  37. *
  38. * @param array $configs An array of configuration settings
  39. * @param ContainerBuilder $container A ContainerBuilder instance
  40. */
  41. public function load(array $configs, ContainerBuilder $container)
  42. {
  43. $configuration = $this->getConfiguration($configs, $container);
  44. $config = $this->processConfiguration($configuration, $configs);
  45. if (isset($config['handlers'])) {
  46. $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
  47. $loader->load('monolog.xml');
  48. $container->setAlias('logger', 'monolog.logger');
  49. $handlers = array();
  50. foreach ($config['handlers'] as $name => $handler) {
  51. $handlers[$handler['priority']][] = array(
  52. 'id' => $this->buildHandler($container, $name, $handler),
  53. 'channels' => empty($handler['channels']) ? null : $handler['channels']
  54. );
  55. }
  56. $container->setParameter(
  57. 'monolog.swift_mailer.handlers',
  58. $this->swiftMailerHandlers
  59. );
  60. ksort($handlers);
  61. $sortedHandlers = array();
  62. foreach ($handlers as $priorityHandlers) {
  63. foreach (array_reverse($priorityHandlers) as $handler) {
  64. $sortedHandlers[] = $handler;
  65. }
  66. }
  67. $handlersToChannels = array();
  68. foreach ($sortedHandlers as $handler) {
  69. if (!in_array($handler['id'], $this->nestedHandlers)) {
  70. $handlersToChannels[$handler['id']] = $handler['channels'];
  71. }
  72. }
  73. $container->setParameter('monolog.handlers_to_channels', $handlersToChannels);
  74. $this->addClassesToCompile(array(
  75. 'Monolog\\Formatter\\FormatterInterface',
  76. 'Monolog\\Formatter\\LineFormatter',
  77. 'Monolog\\Handler\\HandlerInterface',
  78. 'Monolog\\Handler\\AbstractHandler',
  79. 'Monolog\\Handler\\AbstractProcessingHandler',
  80. 'Monolog\\Handler\\StreamHandler',
  81. 'Monolog\\Handler\\FingersCrossedHandler',
  82. 'Monolog\\Handler\\FilterHandler',
  83. 'Monolog\\Handler\\TestHandler',
  84. 'Monolog\\Logger',
  85. 'Symfony\\Bridge\\Monolog\\Logger',
  86. 'Symfony\\Bridge\\Monolog\\Handler\\DebugHandler',
  87. 'Monolog\\Handler\\FingersCrossed\\ActivationStrategyInterface',
  88. 'Monolog\\Handler\\FingersCrossed\\ErrorLevelActivationStrategy',
  89. ));
  90. }
  91. $container->setParameter('monolog.additional_channels', isset($config['channels']) ? $config['channels'] : array());
  92. }
  93. /**
  94. * Returns the base path for the XSD files.
  95. *
  96. * @return string The XSD base path
  97. */
  98. public function getXsdValidationBasePath()
  99. {
  100. return __DIR__.'/../Resources/config/schema';
  101. }
  102. public function getNamespace()
  103. {
  104. return 'http://symfony.com/schema/dic/monolog';
  105. }
  106. private function buildHandler(ContainerBuilder $container, $name, array $handler)
  107. {
  108. $handlerId = $this->getHandlerId($name);
  109. $definition = new Definition(sprintf('%%monolog.handler.%s.class%%', $handler['type']));
  110. $handler['level'] = $this->levelToMonologConst($handler['level']);
  111. switch ($handler['type']) {
  112. case 'service':
  113. $container->setAlias($handlerId, $handler['id']);
  114. return $handlerId;
  115. case 'stream':
  116. $definition->setArguments(array(
  117. $handler['path'],
  118. $handler['level'],
  119. $handler['bubble'],
  120. $handler['file_permission'],
  121. ));
  122. break;
  123. case 'console':
  124. if (!class_exists('Symfony\Bridge\Monolog\Handler\ConsoleHandler')) {
  125. throw new \RuntimeException('The console handler requires symfony/monolog-bridge 2.4+');
  126. }
  127. $definition->setArguments(array(
  128. null,
  129. $handler['bubble'],
  130. isset($handler['verbosity_levels']) ? $handler['verbosity_levels'] : array()
  131. ));
  132. $definition->addTag('kernel.event_subscriber');
  133. break;
  134. case 'firephp':
  135. $definition->setArguments(array(
  136. $handler['level'],
  137. $handler['bubble'],
  138. ));
  139. $definition->addTag('kernel.event_listener', array('event' => 'kernel.response', 'method' => 'onKernelResponse'));
  140. break;
  141. case 'gelf':
  142. if (isset($handler['publisher']['id'])) {
  143. $publisherId = $handler['publisher']['id'];
  144. } elseif (class_exists('Gelf\Transport\UdpTransport')) {
  145. $transport = new Definition("Gelf\Transport\UdpTransport", array(
  146. $handler['publisher']['hostname'],
  147. $handler['publisher']['port'],
  148. $handler['publisher']['chunk_size'],
  149. ));
  150. $transportId = uniqid('monolog.gelf.transport.');
  151. $transport->setPublic(false);
  152. $container->setDefinition($transportId, $transport);
  153. $publisher = new Definition("%monolog.gelfphp.publisher.class%", array());
  154. $publisher->addMethodCall('addTransport', array(new Reference($transportId)));
  155. $publisherId = uniqid('monolog.gelf.publisher.');
  156. $publisher->setPublic(false);
  157. $container->setDefinition($publisherId, $publisher);
  158. } elseif (class_exists('Gelf\MessagePublisher')) {
  159. $publisher = new Definition("%monolog.gelf.publisher.class%", array(
  160. $handler['publisher']['hostname'],
  161. $handler['publisher']['port'],
  162. $handler['publisher']['chunk_size'],
  163. ));
  164. $publisherId = uniqid('monolog.gelf.publisher.');
  165. $publisher->setPublic(false);
  166. $container->setDefinition($publisherId, $publisher);
  167. } else {
  168. throw new \RuntimeException('The gelf handler requires the graylog2/gelf-php package to be installed');
  169. }
  170. $definition->setArguments(array(
  171. new Reference($publisherId),
  172. $handler['level'],
  173. $handler['bubble'],
  174. ));
  175. break;
  176. case 'mongo':
  177. if (isset($handler['mongo']['id'])) {
  178. $clientId = $handler['mongo']['id'];
  179. } else {
  180. $server = 'mongodb://';
  181. if (isset($handler['mongo']['user'])) {
  182. $server .= $handler['mongo']['user'] . ':' . $handler['mongo']['pass'] . '@';
  183. }
  184. $server .= $handler['mongo']['host'] . ':' . $handler['mongo']['port'];
  185. $client = new Definition("%monolog.mongo.client.class%", array(
  186. $server
  187. ));
  188. $clientId = uniqid('monolog.mongo.client.');
  189. $client->setPublic(false);
  190. $container->setDefinition($clientId, $client);
  191. }
  192. $definition->setArguments(array(
  193. new Reference($clientId),
  194. $handler['mongo']['database'],
  195. $handler['mongo']['collection'],
  196. $handler['level'],
  197. $handler['bubble'],
  198. ));
  199. break;
  200. case 'elasticsearch':
  201. if (isset($handler['elasticsearch']['id'])) {
  202. $clientId = $handler['elasticsearch']['id'];
  203. } else {
  204. // elastica client new definition
  205. $elasticaClient = new Definition('%monolog.elastica.client.class%');
  206. $elasticaClient->setArguments(array(
  207. array(
  208. 'host' => $handler['elasticsearch']['host'],
  209. 'port' => $handler['elasticsearch']['port']
  210. )
  211. ));
  212. $clientId = uniqid('monolog.elastica.client.');
  213. $elasticaClient->setPublic(false);
  214. $container->setDefinition($clientId, $elasticaClient);
  215. }
  216. // elastica handler definition
  217. $definition->setArguments(array(
  218. new Reference($clientId),
  219. array(
  220. 'index' => $handler['index'],
  221. 'type' => $handler['document_type'],
  222. ),
  223. $handler['level'],
  224. $handler['bubble']
  225. ));
  226. break;
  227. case 'chromephp':
  228. $definition->setArguments(array(
  229. $handler['level'],
  230. $handler['bubble'],
  231. ));
  232. $definition->addTag('kernel.event_listener', array('event' => 'kernel.response', 'method' => 'onKernelResponse'));
  233. break;
  234. case 'rotating_file':
  235. $definition->setArguments(array(
  236. $handler['path'],
  237. $handler['max_files'],
  238. $handler['level'],
  239. $handler['bubble'],
  240. $handler['file_permission'],
  241. ));
  242. break;
  243. case 'fingers_crossed':
  244. $handler['action_level'] = $this->levelToMonologConst($handler['action_level']);
  245. if (null !== $handler['passthru_level']) {
  246. $handler['passthru_level'] = $this->levelToMonologConst($handler['passthru_level']);
  247. }
  248. $nestedHandlerId = $this->getHandlerId($handler['handler']);
  249. $this->nestedHandlers[] = $nestedHandlerId;
  250. if (isset($handler['activation_strategy'])) {
  251. $activation = new Reference($handler['activation_strategy']);
  252. } elseif (!empty($handler['excluded_404s'])) {
  253. $activationDef = new Definition('%monolog.activation_strategy.not_found.class%', array($handler['excluded_404s'], $handler['action_level']));
  254. $activationDef->addMethodCall('setRequest', array(new Reference('request', ContainerInterface::NULL_ON_INVALID_REFERENCE, false)));
  255. $container->setDefinition($handlerId.'.not_found_strategy', $activationDef);
  256. $activation = new Reference($handlerId.'.not_found_strategy');
  257. } else {
  258. $activation = $handler['action_level'];
  259. }
  260. $definition->setArguments(array(
  261. new Reference($nestedHandlerId),
  262. $activation,
  263. $handler['buffer_size'],
  264. $handler['bubble'],
  265. $handler['stop_buffering'],
  266. $handler['passthru_level']
  267. ));
  268. break;
  269. case 'filter':
  270. $handler['min_level'] = $this->levelToMonologConst($handler['min_level']);
  271. $handler['max_level'] = $this->levelToMonologConst($handler['max_level']);
  272. foreach (array_keys($handler['accepted_levels']) as $k) {
  273. $handler['accepted_levels'][$k] = $this->levelToMonologConst($handler['accepted_levels'][$k]);
  274. }
  275. $nestedHandlerId = $this->getHandlerId($handler['handler']);
  276. $this->nestedHandlers[] = $nestedHandlerId;
  277. $minLevelOrList = !empty($handler['accepted_levels']) ? $handler['accepted_levels'] : $handler['min_level'];
  278. $definition->setArguments(array(
  279. new Reference($nestedHandlerId),
  280. $minLevelOrList,
  281. $handler['max_level'],
  282. $handler['bubble']
  283. ));
  284. break;
  285. case 'buffer':
  286. $nestedHandlerId = $this->getHandlerId($handler['handler']);
  287. $this->nestedHandlers[] = $nestedHandlerId;
  288. $definition->setArguments(array(
  289. new Reference($nestedHandlerId),
  290. $handler['buffer_size'],
  291. $handler['level'],
  292. $handler['bubble'],
  293. ));
  294. break;
  295. case 'group':
  296. case 'whatfailuregroup':
  297. $references = array();
  298. foreach ($handler['members'] as $nestedHandler) {
  299. $nestedHandlerId = $this->getHandlerId($nestedHandler);
  300. $this->nestedHandlers[] = $nestedHandlerId;
  301. $references[] = new Reference($nestedHandlerId);
  302. }
  303. $definition->setArguments(array(
  304. $references,
  305. $handler['bubble'],
  306. ));
  307. break;
  308. case 'syslog':
  309. $definition->setArguments(array(
  310. $handler['ident'],
  311. $handler['facility'],
  312. $handler['level'],
  313. $handler['bubble'],
  314. $handler['logopts'],
  315. ));
  316. break;
  317. case 'syslogudp':
  318. $definition->setArguments(array(
  319. $handler['host'],
  320. $handler['port'],
  321. $handler['facility'],
  322. $handler['level'],
  323. $handler['bubble'],
  324. ));
  325. break;
  326. case 'swift_mailer':
  327. $oldHandler = false;
  328. // fallback for older symfony versions that don't have the new SwiftMailerHandler in the bridge
  329. $newHandlerClass = $container->getParameterBag()->resolveValue($definition->getClass());
  330. if (!class_exists($newHandlerClass)) {
  331. $definition = new Definition('Monolog\Handler\SwiftMailerHandler');
  332. $oldHandler = true;
  333. }
  334. if (isset($handler['email_prototype'])) {
  335. if (!empty($handler['email_prototype']['method'])) {
  336. $prototype = array(new Reference($handler['email_prototype']['id']), $handler['email_prototype']['method']);
  337. } else {
  338. $prototype = new Reference($handler['email_prototype']['id']);
  339. }
  340. } else {
  341. $message = new Definition('Swift_Message');
  342. $message->setLazy(true);
  343. $message->setFactoryMethod('createMessage');
  344. $message->setPublic(false);
  345. $message->addMethodCall('setFrom', array($handler['from_email']));
  346. $message->addMethodCall('setTo', array($handler['to_email']));
  347. $message->addMethodCall('setSubject', array($handler['subject']));
  348. if (isset($handler['mailer'])) {
  349. $mailer = $handler['mailer'];
  350. } else {
  351. $mailer = 'mailer';
  352. }
  353. $message->setFactoryService($mailer);
  354. if (isset($handler['content_type'])) {
  355. $message->addMethodCall('setContentType', array($handler['content_type']));
  356. }
  357. $messageId = sprintf('%s.mail_prototype', $handlerId);
  358. $container->setDefinition($messageId, $message);
  359. $prototype = new Reference($messageId);
  360. }
  361. $definition->setArguments(array(
  362. new Reference($handler['mailer']),
  363. $prototype,
  364. $handler['level'],
  365. $handler['bubble'],
  366. ));
  367. if (!$oldHandler) {
  368. $this->swiftMailerHandlers[] = $handlerId;
  369. $definition->addTag('kernel.event_listener', array('event' => 'kernel.terminate', 'method' => 'onKernelTerminate'));
  370. if (method_exists($newHandlerClass, 'onCliTerminate')) {
  371. $definition->addTag('kernel.event_listener', array('event' => 'console.terminate', 'method' => 'onCliTerminate'));
  372. }
  373. }
  374. break;
  375. case 'native_mailer':
  376. $definition->setArguments(array(
  377. $handler['to_email'],
  378. $handler['subject'],
  379. $handler['from_email'],
  380. $handler['level'],
  381. $handler['bubble'],
  382. ));
  383. break;
  384. case 'socket':
  385. $definition->setArguments(array(
  386. $handler['connection_string'],
  387. $handler['level'],
  388. $handler['bubble'],
  389. ));
  390. if (isset($handler['timeout'])) {
  391. $definition->addMethodCall('setTimeout', array($handler['timeout']));
  392. }
  393. if (isset($handler['connection_timeout'])) {
  394. $definition->addMethodCall('setConnectionTimeout', array($handler['connection_timeout']));
  395. }
  396. if (isset($handler['persistent'])) {
  397. $definition->addMethodCall('setPersistent', array($handler['persistent']));
  398. }
  399. break;
  400. case 'pushover':
  401. $definition->setArguments(array(
  402. $handler['token'],
  403. $handler['user'],
  404. $handler['title'],
  405. $handler['level'],
  406. $handler['bubble'],
  407. ));
  408. break;
  409. case 'hipchat':
  410. $definition->setArguments(array(
  411. $handler['token'],
  412. $handler['room'],
  413. $handler['nickname'],
  414. $handler['notify'],
  415. $handler['level'],
  416. $handler['bubble'],
  417. ));
  418. break;
  419. case 'slack':
  420. $definition->setArguments(array(
  421. $handler['token'],
  422. $handler['channel'],
  423. $handler['bot_name'],
  424. $handler['use_attachment'],
  425. $handler['icon_emoji'],
  426. $handler['level'],
  427. $handler['bubble'],
  428. $handler['use_short_attachment'],
  429. $handler['include_extra'],
  430. ));
  431. break;
  432. case 'cube':
  433. $definition->setArguments(array(
  434. $handler['url'],
  435. $handler['level'],
  436. $handler['bubble'],
  437. ));
  438. break;
  439. case 'amqp':
  440. $definition->setArguments(array(
  441. new Reference($handler['exchange']),
  442. $handler['exchange_name'],
  443. $handler['level'],
  444. $handler['bubble'],
  445. ));
  446. break;
  447. case 'error_log':
  448. $definition->setArguments(array(
  449. $handler['message_type'],
  450. $handler['level'],
  451. $handler['bubble'],
  452. ));
  453. break;
  454. case 'raven':
  455. if (null !== $handler['client_id']) {
  456. $clientId = $handler['client_id'];
  457. } else {
  458. $client = new Definition("Raven_Client", array(
  459. $handler['dsn']
  460. ));
  461. $client->setPublic(false);
  462. $clientId = 'monolog.raven.client.'.sha1($handler['dsn']);
  463. $container->setDefinition($clientId, $client);
  464. }
  465. $definition->setArguments(array(
  466. new Reference($clientId),
  467. $handler['level'],
  468. $handler['bubble'],
  469. ));
  470. break;
  471. case 'loggly':
  472. $definition->setArguments(array(
  473. $handler['token'],
  474. $handler['level'],
  475. $handler['bubble'],
  476. ));
  477. if (!empty($handler['tags'])) {
  478. $definition->addMethodCall('setTag', array(implode(',', $handler['tags'])));
  479. }
  480. break;
  481. case 'logentries':
  482. $definition->setArguments(array(
  483. $handler['token'],
  484. $handler['use_ssl'],
  485. $handler['level'],
  486. $handler['bubble'],
  487. ));
  488. break;
  489. case 'flowdock':
  490. $definition->setArguments(array(
  491. $handler['token'],
  492. $handler['level'],
  493. $handler['bubble'],
  494. ));
  495. if (empty($handler['formatter'])) {
  496. $formatter = new Definition("Monolog\Formatter\FlowdockFormatter", array(
  497. $handler['source'],
  498. $handler['from_email'],
  499. ));
  500. $formatterId = 'monolog.flowdock.formatter.'.sha1($handler['source'].'|'.$handler['from_email']);
  501. $formatter->setPublic(false);
  502. $container->setDefinition($formatterId, $formatter);
  503. $definition->addMethodCall('setFormatter', array(new Reference($formatterId)));
  504. }
  505. break;
  506. case 'rollbar':
  507. if (!empty($handler['id'])) {
  508. $rollbarId = $handler['id'];
  509. } else {
  510. $config = $handler['config'] ?: array();
  511. $config['access_token'] = $handler['token'];
  512. $rollbar = new Definition("RollbarNotifier", array(
  513. $config,
  514. ));
  515. $rollbarId = 'monolog.rollbar.notifier.'.sha1(json_encode($config));
  516. $rollbar->setPublic(false);
  517. $container->setDefinition($rollbarId, $rollbar);
  518. }
  519. $definition->setArguments(array(
  520. new Reference($rollbarId),
  521. $handler['level'],
  522. $handler['bubble'],
  523. ));
  524. break;
  525. // Handlers using the constructor of AbstractHandler without adding their own arguments
  526. case 'browser_console':
  527. case 'newrelic':
  528. case 'test':
  529. case 'null':
  530. case 'debug':
  531. $definition->setArguments(array(
  532. $handler['level'],
  533. $handler['bubble'],
  534. ));
  535. break;
  536. default:
  537. throw new \InvalidArgumentException(sprintf('Invalid handler type "%s" given for handler "%s"', $handler['type'], $name));
  538. }
  539. if (!empty($handler['formatter'])) {
  540. $definition->addMethodCall('setFormatter', array(new Reference($handler['formatter'])));
  541. }
  542. $container->setDefinition($handlerId, $definition);
  543. return $handlerId;
  544. }
  545. private function getHandlerId($name)
  546. {
  547. return sprintf('monolog.handler.%s', $name);
  548. }
  549. }