1<?php 2 3/* 4 * This file is part of the Silex framework. 5 * 6 * (c) Fabien Potencier <fabien@symfony.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Silex\Provider; 13 14use Pimple\Container; 15use Pimple\ServiceProviderInterface; 16use Monolog\Formatter\LineFormatter; 17use Monolog\Logger; 18use Monolog\Handler; 19use Monolog\ErrorHandler; 20use Silex\Application; 21use Silex\Api\BootableProviderInterface; 22use Symfony\Bridge\Monolog\Handler\DebugHandler; 23use Symfony\Bridge\Monolog\Handler\FingersCrossed\NotFoundActivationStrategy; 24use Symfony\Bridge\Monolog\Processor\DebugProcessor; 25use Silex\EventListener\LogListener; 26 27/** 28 * Monolog Provider. 29 * 30 * @author Fabien Potencier <fabien@symfony.com> 31 */ 32class MonologServiceProvider implements ServiceProviderInterface, BootableProviderInterface 33{ 34 public function register(Container $app) 35 { 36 $app['logger'] = function () use ($app) { 37 return $app['monolog']; 38 }; 39 40 if ($bridge = class_exists('Symfony\Bridge\Monolog\Logger')) { 41 $app['monolog.handler.debug'] = function () use ($app) { 42 $level = MonologServiceProvider::translateLevel($app['monolog.level']); 43 44 return new DebugHandler($level); 45 }; 46 47 if (isset($app['request_stack'])) { 48 $app['monolog.not_found_activation_strategy'] = function () use ($app) { 49 return new NotFoundActivationStrategy($app['request_stack'], array('^/'), $app['monolog.level']); 50 }; 51 } 52 } 53 54 $app['monolog.logger.class'] = $bridge ? 'Symfony\Bridge\Monolog\Logger' : 'Monolog\Logger'; 55 56 $app['monolog'] = function ($app) use ($bridge) { 57 $log = new $app['monolog.logger.class']($app['monolog.name']); 58 59 $handler = new Handler\GroupHandler($app['monolog.handlers']); 60 if (isset($app['monolog.not_found_activation_strategy'])) { 61 $handler = new Handler\FingersCrossedHandler($handler, $app['monolog.not_found_activation_strategy']); 62 } 63 64 $log->pushHandler($handler); 65 66 if ($app['debug'] && $bridge) { 67 if (class_exists(DebugProcessor::class)) { 68 $log->pushProcessor(new DebugProcessor()); 69 } else { 70 $log->pushHandler($app['monolog.handler.debug']); 71 } 72 } 73 74 return $log; 75 }; 76 77 $app['monolog.formatter'] = function () { 78 return new LineFormatter(); 79 }; 80 81 $app['monolog.handler'] = $defaultHandler = function () use ($app) { 82 $level = MonologServiceProvider::translateLevel($app['monolog.level']); 83 84 $handler = new Handler\StreamHandler($app['monolog.logfile'], $level, $app['monolog.bubble'], $app['monolog.permission']); 85 $handler->setFormatter($app['monolog.formatter']); 86 87 return $handler; 88 }; 89 90 $app['monolog.handlers'] = function () use ($app, $defaultHandler) { 91 $handlers = array(); 92 93 // enables the default handler if a logfile was set or the monolog.handler service was redefined 94 if ($app['monolog.logfile'] || $defaultHandler !== $app->raw('monolog.handler')) { 95 $handlers[] = $app['monolog.handler']; 96 } 97 98 return $handlers; 99 }; 100 101 $app['monolog.level'] = function () { 102 return Logger::DEBUG; 103 }; 104 105 $app['monolog.listener'] = function () use ($app) { 106 return new LogListener($app['logger'], $app['monolog.exception.logger_filter']); 107 }; 108 109 $app['monolog.name'] = 'app'; 110 $app['monolog.bubble'] = true; 111 $app['monolog.permission'] = null; 112 $app['monolog.exception.logger_filter'] = null; 113 $app['monolog.logfile'] = null; 114 $app['monolog.use_error_handler'] = function ($app) { 115 return !$app['debug']; 116 }; 117 } 118 119 public function boot(Application $app) 120 { 121 if ($app['monolog.use_error_handler']) { 122 ErrorHandler::register($app['monolog']); 123 } 124 125 if (isset($app['monolog.listener'])) { 126 $app['dispatcher']->addSubscriber($app['monolog.listener']); 127 } 128 } 129 130 public static function translateLevel($name) 131 { 132 // level is already translated to logger constant, return as-is 133 if (is_int($name)) { 134 return $name; 135 } 136 137 $levels = Logger::getLevels(); 138 $upper = strtoupper($name); 139 140 if (!isset($levels[$upper])) { 141 throw new \InvalidArgumentException("Provided logging level '$name' does not exist. Must be a valid monolog logging level."); 142 } 143 144 return $levels[$upper]; 145 } 146} 147