MonologExtension.php 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  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 Symfony\Component\HttpKernel\DependencyInjection\Extension;
  12. use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
  13. use Symfony\Component\DependencyInjection\ContainerBuilder;
  14. use Symfony\Component\Config\FileLocator;
  15. use Symfony\Component\DependencyInjection\Definition;
  16. use Symfony\Component\DependencyInjection\Reference;
  17. /**
  18. * MonologExtension is an extension for the Monolog library.
  19. *
  20. * @author Jordi Boggiano <j.boggiano@seld.be>
  21. * @author Christophe Coevoet <stof@notk.org>
  22. */
  23. class MonologExtension extends Extension
  24. {
  25. private $nestedHandlers = array();
  26. /**
  27. * Loads the Monolog configuration.
  28. *
  29. * @param array $configs An array of configuration settings
  30. * @param ContainerBuilder $container A ContainerBuilder instance
  31. */
  32. public function load(array $configs, ContainerBuilder $container)
  33. {
  34. $configuration = $this->getConfiguration($configs, $container);
  35. $config = $this->processConfiguration($configuration, $configs);
  36. if (isset($config['handlers'])) {
  37. $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
  38. $loader->load('monolog.xml');
  39. $container->setAlias('logger', 'monolog.logger');
  40. $handlers = array();
  41. foreach ($config['handlers'] as $name => $handler) {
  42. $handlers[$handler['priority']][] = array(
  43. 'id' => $this->buildHandler($container, $name, $handler),
  44. 'channels' => isset($handler['channels']) ? $handler['channels'] : null
  45. );
  46. }
  47. ksort($handlers);
  48. $sortedHandlers = array();
  49. foreach ($handlers as $priorityHandlers) {
  50. foreach (array_reverse($priorityHandlers) as $handler) {
  51. $sortedHandlers[] = $handler;
  52. }
  53. }
  54. $handlersToChannels = array();
  55. foreach ($sortedHandlers as $handler) {
  56. if (!in_array($handler['id'], $this->nestedHandlers)) {
  57. $handlersToChannels[$handler['id']] = $handler['channels'];
  58. }
  59. }
  60. $container->setParameter('monolog.handlers_to_channels', $handlersToChannels);
  61. $this->addClassesToCompile(array(
  62. 'Monolog\\Formatter\\FormatterInterface',
  63. 'Monolog\\Formatter\\LineFormatter',
  64. 'Monolog\\Handler\\HandlerInterface',
  65. 'Monolog\\Handler\\AbstractHandler',
  66. 'Monolog\\Handler\\AbstractProcessingHandler',
  67. 'Monolog\\Handler\\StreamHandler',
  68. 'Monolog\\Handler\\FingersCrossedHandler',
  69. 'Monolog\\Handler\\TestHandler',
  70. 'Monolog\\Logger',
  71. 'Symfony\\Bridge\\Monolog\\Logger',
  72. 'Symfony\\Bridge\\Monolog\\Handler\\DebugHandler',
  73. ));
  74. }
  75. }
  76. /**
  77. * Returns the base path for the XSD files.
  78. *
  79. * @return string The XSD base path
  80. */
  81. public function getXsdValidationBasePath()
  82. {
  83. return __DIR__.'/../Resources/config/schema';
  84. }
  85. public function getNamespace()
  86. {
  87. return 'http://symfony.com/schema/dic/monolog';
  88. }
  89. private function buildHandler(ContainerBuilder $container, $name, array $handler)
  90. {
  91. $handlerId = $this->getHandlerId($name);
  92. $definition = new Definition(sprintf('%%monolog.handler.%s.class%%', $handler['type']));
  93. $handler['level'] = is_int($handler['level']) ? $handler['level'] : constant('Monolog\Logger::'.strtoupper($handler['level']));
  94. switch ($handler['type']) {
  95. case 'service':
  96. $container->setAlias($handlerId, $handler['id']);
  97. return $handlerId;
  98. case 'stream':
  99. $definition->setArguments(array(
  100. $handler['path'],
  101. $handler['level'],
  102. $handler['bubble'],
  103. ));
  104. break;
  105. case 'firephp':
  106. $definition->setArguments(array(
  107. $handler['level'],
  108. $handler['bubble'],
  109. ));
  110. $definition->addTag('kernel.event_listener', array('event' => 'kernel.response', 'method' => 'onKernelResponse'));
  111. break;
  112. case 'gelf':
  113. if (isset($handler['publisher']['id'])) {
  114. $publisherId = $handler['publisher']['id'];
  115. } else {
  116. $publisher = new Definition("%monolog.gelf.publisher.class%", array(
  117. $handler['publisher']['hostname'],
  118. $handler['publisher']['port'],
  119. $handler['publisher']['chunk_size'],
  120. ));
  121. $publisherId = 'monolog.gelf.publisher';
  122. $publisher->setPublic(false);
  123. $container->setDefinition($publisherId, $publisher);
  124. }
  125. $definition->setArguments(array(
  126. new Reference($publisherId),
  127. $handler['level'],
  128. $handler['bubble'],
  129. ));
  130. break;
  131. case 'chromephp':
  132. $definition->setArguments(array(
  133. $handler['level'],
  134. $handler['bubble'],
  135. ));
  136. $definition->addTag('kernel.event_listener', array('event' => 'kernel.response', 'method' => 'onKernelResponse'));
  137. break;
  138. case 'rotating_file':
  139. $definition->setArguments(array(
  140. $handler['path'],
  141. $handler['max_files'],
  142. $handler['level'],
  143. $handler['bubble'],
  144. ));
  145. break;
  146. case 'fingers_crossed':
  147. $handler['action_level'] = is_int($handler['action_level']) ? $handler['action_level'] : constant('Monolog\Logger::'.strtoupper($handler['action_level']));
  148. $nestedHandlerId = $this->getHandlerId($handler['handler']);
  149. $this->nestedHandlers[] = $nestedHandlerId;
  150. if (isset($handler['activation_strategy'])) {
  151. $activation = new Reference($handler['activation_strategy']);
  152. } else {
  153. $activation = $handler['action_level'];
  154. }
  155. $definition->setArguments(array(
  156. new Reference($nestedHandlerId),
  157. $activation,
  158. $handler['buffer_size'],
  159. $handler['bubble'],
  160. $handler['stop_buffering'],
  161. ));
  162. break;
  163. case 'buffer':
  164. $nestedHandlerId = $this->getHandlerId($handler['handler']);
  165. $this->nestedHandlers[] = $nestedHandlerId;
  166. $definition->setArguments(array(
  167. new Reference($nestedHandlerId),
  168. $handler['buffer_size'],
  169. $handler['level'],
  170. $handler['bubble'],
  171. ));
  172. break;
  173. case 'group':
  174. $references = array();
  175. foreach ($handler['members'] as $nestedHandler) {
  176. $nestedHandlerId = $this->getHandlerId($nestedHandler);
  177. $this->nestedHandlers[] = $nestedHandlerId;
  178. $references[] = new Reference($nestedHandlerId);
  179. }
  180. $definition->setArguments(array(
  181. $references,
  182. $handler['bubble'],
  183. ));
  184. break;
  185. case 'syslog':
  186. $definition->setArguments(array(
  187. $handler['ident'],
  188. $handler['facility'],
  189. $handler['level'],
  190. $handler['bubble'],
  191. $handler['logopts'],
  192. ));
  193. break;
  194. case 'swift_mailer':
  195. if (isset($handler['email_prototype'])) {
  196. if (!empty($handler['email_prototype']['method'])) {
  197. $prototype = array(new Reference($handler['email_prototype']['id']), $handler['email_prototype']['method']);
  198. } else {
  199. $prototype = new Reference($handler['email_prototype']['id']);
  200. }
  201. } else {
  202. $message = new Definition('Swift_Message');
  203. $message->setFactoryService('mailer');
  204. $message->setFactoryMethod('createMessage');
  205. $message->setPublic(false);
  206. $message->addMethodCall('setFrom', array($handler['from_email']));
  207. $message->addMethodCall('setTo', array($handler['to_email']));
  208. $message->addMethodCall('setSubject', array($handler['subject']));
  209. $messageId = sprintf('%s.mail_prototype', $handlerId);
  210. $container->setDefinition($messageId, $message);
  211. $prototype = new Reference($messageId);
  212. }
  213. $definition->setArguments(array(
  214. new Reference('mailer'),
  215. $prototype,
  216. $handler['level'],
  217. $handler['bubble'],
  218. ));
  219. break;
  220. case 'native_mailer':
  221. $definition->setArguments(array(
  222. $handler['to_email'],
  223. $handler['subject'],
  224. $handler['from_email'],
  225. $handler['level'],
  226. $handler['bubble'],
  227. ));
  228. break;
  229. case 'socket':
  230. $definition->setArguments(array(
  231. $handler['connection_string'],
  232. $handler['level'],
  233. $handler['bubble'],
  234. ));
  235. if (isset($handler['timeout'])) {
  236. $definition->addMethodCall('setTimeout', array($handler['timeout']));
  237. }
  238. if (isset($handler['connection_timeout'])) {
  239. $definition->addMethodCall('setConnectionTimeout', array($handler['connection_timeout']));
  240. }
  241. if (isset($handler['persistent'])) {
  242. $definition->addMethodCall('setPersistent', array($handler['persistent']));
  243. }
  244. break;
  245. // Handlers using the constructor of AbstractHandler without adding their own arguments
  246. case 'test':
  247. case 'null':
  248. case 'debug':
  249. $definition->setArguments(array(
  250. $handler['level'],
  251. $handler['bubble'],
  252. ));
  253. break;
  254. default:
  255. throw new \InvalidArgumentException(sprintf('Invalid handler type "%s" given for handler "%s"', $handler['type'], $name));
  256. }
  257. if (!empty($handler['formatter'])) {
  258. $definition->addMethodCall('setFormatter', array(new Reference($handler['formatter'])));
  259. }
  260. $container->setDefinition($handlerId, $definition);
  261. return $handlerId;
  262. }
  263. private function getHandlerId($name)
  264. {
  265. return sprintf('monolog.handler.%s', $name);
  266. }
  267. }