MediaWiki master
MonologSpi.php
Go to the documentation of this file.
1<?php
21namespace MediaWiki\Logger;
22
23use DateTimeZone;
25use Monolog\Formatter\FormatterInterface;
26use Monolog\Handler\FormattableHandlerInterface;
27use Monolog\Handler\HandlerInterface;
28use Monolog\Handler\StreamHandler;
29use Monolog\Logger;
30use Psr\Log\LoggerInterface;
31use Wikimedia\ObjectFactory\ObjectFactory;
32
122class MonologSpi implements Spi {
123
127 protected $singletons;
128
133 protected array $config = [];
134
138 public function __construct( array $config ) {
139 $this->mergeConfig( $config );
140 }
141
148 public function mergeConfig( array $config ) {
149 foreach ( $config as $key => $value ) {
150 if ( isset( $this->config[$key] ) ) {
151 $this->config[$key] = array_merge( $this->config[$key], $value );
152 } else {
153 $this->config[$key] = $value;
154 }
155 }
156 if ( !isset( $this->config['loggers']['@default'] ) ) {
157 $this->config['loggers']['@default'] = [
158 'handlers' => [ '@default' ],
159 ];
160 $this->config['handlers']['@default'] ??= [
161 'class' => StreamHandler::class,
162 'args' => [ 'php://stderr', Logger::ERROR ],
163 ];
164 }
165 $this->reset();
166 }
167
174 public function reset() {
175 $this->singletons = [
176 'loggers' => [],
177 'handlers' => [],
178 'formatters' => [],
179 'processors' => [],
180 ];
181 }
182
193 public function getLogger( $channel ) {
194 if ( !isset( $this->singletons['loggers'][$channel] ) ) {
195 // Fallback to using the '@default' configuration if an explicit
196 // configuration for the requested channel isn't found.
197 $spec = $this->config['loggers'][$channel] ?? $this->config['loggers']['@default'];
198
199 $monolog = $this->createLogger( $channel, $spec );
200 $this->singletons['loggers'][$channel] = $monolog;
201 }
202
203 return $this->singletons['loggers'][$channel];
204 }
205
212 protected function createLogger( $channel, $spec ): LoggerInterface {
213 $handlers = [];
214 if ( isset( $spec['handlers'] ) && $spec['handlers'] ) {
215 foreach ( $spec['handlers'] as $handler ) {
216 $handlers[] = $this->getHandler( $handler );
217 }
218 }
219
220 $processors = [];
221 if ( isset( $spec['processors'] ) ) {
222 foreach ( $spec['processors'] as $processor ) {
223 $processors[] = $this->getProcessor( $processor );
224 }
225 }
226
227 // Use UTC for logs instead of Monolog's default, which asks the
228 // PHP runtime, which MediaWiki sets to $wgLocaltimezone (T99581)
229 $obj = new Logger( $channel, $handlers, $processors, new DateTimeZone( 'UTC' ) );
230
231 if ( isset( $spec['calls'] ) ) {
232 foreach ( $spec['calls'] as $method => $margs ) {
233 $obj->$method( ...$margs );
234 }
235 }
236
237 return $obj;
238 }
239
245 public function getProcessor( $name ) {
246 if ( !isset( $this->singletons['processors'][$name] ) ) {
247 $spec = $this->config['processors'][$name];
249 $processor = ObjectFactory::getObjectFromSpec( $spec );
250 $this->singletons['processors'][$name] = $processor;
251 }
252 return $this->singletons['processors'][$name];
253 }
254
260 public function getHandler( $name ) {
261 if ( !isset( $this->singletons['handlers'][$name] ) ) {
262 $spec = $this->config['handlers'][$name];
264 $handler = ObjectFactory::getObjectFromSpec( $spec );
265 if (
266 isset( $spec['formatter'] ) &&
267 $handler instanceof FormattableHandlerInterface
268 ) {
269 $handler->setFormatter(
270 $this->getFormatter( $spec['formatter'] )
271 );
272 }
273 if ( isset( $spec['buffer'] ) && $spec['buffer'] ) {
274 $handler = new BufferHandler( $handler );
275 }
276 $this->singletons['handlers'][$name] = $handler;
277 }
278 return $this->singletons['handlers'][$name];
279 }
280
286 public function getFormatter( $name ) {
287 if ( !isset( $this->singletons['formatters'][$name] ) ) {
288 $spec = $this->config['formatters'][$name];
290 $formatter = ObjectFactory::getObjectFromSpec( $spec );
291 $this->singletons['formatters'][$name] = $formatter;
292 }
293 return $this->singletons['formatters'][$name];
294 }
295}
LoggerFactory service provider that creates loggers implemented by Monolog.
getHandler( $name)
Create or return cached handler.
getProcessor( $name)
Create or return cached processor.
mergeConfig(array $config)
Merge additional configuration data into the configuration.
reset()
Reset internal caches.
getLogger( $channel)
Get a logger instance.
createLogger( $channel, $spec)
Create a logger.
array array< string, array< string, array > > $config
Configuration for creating new loggers.
getFormatter( $name)
Create or return cached formatter.
Helper class for the index.php entry point.
Service provider interface to create \Psr\Log\LoggerInterface objects.
Definition Spi.php:64