Yii2 Monolog allows one to use Monolog easily with Yii2. For instructions regarding Monolog itself please refer to the documentation.
Require this package, with Composer, in the root directory of your project.
composer require leinonen/yii2-monolog
Configure the leinonen\Yii2Monolog\Yii2Monolog
as a bootstrapped component in your application config.
An example configuration of one log channel called myLoggerChannel
with a basic StreamHandler and a UidProcessor:
use leinonen\Yii2Monolog\MonologTarget;
use leinonen\Yii2Monolog\Yii2Monolog;
use Monolog\Handler\StreamHandler;
use Monolog\Processor\UidProcessor;
...
[
'bootstrap' => ['monolog'],
'components' => [
...
'monolog' => [
'class' => Yii2Monolog::class,
'channels' => [
'myLoggerChannel' => [
'handlers' => [
StreamHandler::class => [
'path' => '@app/runtime/logs/someLog.log',
],
],
'processors' => [
UidProcessor::class,
],
],
],
],
],
...
]
To see the core concepts about Monolog channels check the Offical Documentation for Monolog.
This component allows registering multiple channels with channel name
=> configuration array
key value pairs with the channels
configuration key.
The component automatically registers a main channel which is used when requesting Psr\Log\LoggerInterface
from the DI container or when fetching a Logger from the component without specifying a channel name.
The main channel is configurable with the configuration key mainChannel
[
'components' => [
...
'monolog' => [
'class' => Yii2Monolog::class,
'channels' => [
'myFirstChannel' => [
...
],
'someOtherAwesomeChannel' => [
...
],
],
'mainChannel' => 'someOtherAwesomeChannel'
]
]
]
If the main channel is null or not specified at all, the first channel from the channels list will be used as the main channel. With the example config above it would be myFirstChannel
.
The package supports all official and 3rd party handlers for Monolog. It uses leinonen\Yii2Monolog\CreationStrategies\ReflectionStrategy
by default in background to figure out the config values which the handler is to be constructed with. The handlers are defined with a config key handlers
in the Monolog configuration. All the handlers are resolved through Yii's DI container making it easier to implement your own custom handlers.
Example handler configuration with a stack of two handlers:
[
...
'monolog' => [
'channels' => [
'myLoggerChannel' => [
'handlers' => [
SlackbotHandler::class => [
'slackTeam' => 'myTeam',
'token' => 'mySecretSlackToken',
'channel' => 'myChannel',
],
RotatingFileHandler::class => [
'path' => '@app/runtime/logs/myRotatinglog.log',
'maxFiles' => 10,
],
],
],
],
],
...
]
You can find the available handlers from the Monolog\Handler namespace
The package also provides a specific creation strategies for couple of handlers to help integrating with Yii2.
The path
config value is resolved through Yii's getAlias()
method making it possible to use aliases such as @app
in the config. Use this instead of stream
The path
config value is resolved through Yii's getAlias()
method making it possible to use aliases such as @app
in the config. Use this instead of filename
The package supports all official and 3rd party formatters for Monolog. It uses leinonen\Yii2Monolog\CreationStrategies\ReflectionStrategy
by default in background to figure out the config values which the formatter is to be constructed with. All the formatters are resolved through Yii's DI container making it easier to implement your own custom formatters.
It's possible to configure a custom formatter for each handler. The formatter is configured with a formatter
key in the handler's config array:
'handlers' => [
StreamHandler::class => [
'path' => '@app/runtime/logs/myLog.log',
'formatter' => [
LineFormatter::class => [
'format' => "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n",
'dateFormat' => "Y-m-d\TH:i:sP"
]
]
]
]
You can find available formatters from the Monolog/Formatter namespace.
The package supports all official and 3rd party processors for Monolog. It uses leinonen\Yii2Monolog\CreationStrategies\ReflectionStrategy
by default in background to figure out the config values which the processor is to be constructed with. All the processors are resolved through Yii's DI container making it easier to implement your own custom processors.
The processors can be defined globally for one target or specifically for a handler. Processors are configured with a processors
key in the config array with an array of callables:
[
...
'monolog' => [
'channels' => [
'myLoggerChannel' => [
'processors' => [
GitProcessor::class,
function ($record) {
$record['myCustomData'] = 'test';
return $record;
},
],
],
],
],
...
]
Or config to a specific handler:
...
'handlers' => [
StreamHandler::class => [
'path' => '@app/runtime/logs/myLog.log',
'processors' => [
GitProcessor::class,
function ($record) {
$record['myCustomData'] = 'test';
return $record;
}
]
]
You can find available processors from the Monolog/Processor namespace.
For further customisation it's possible to specify a configure
key for all classes that are created with leinonen\Yii2Monolog\CreationStrategies\ReflectionStrategy
. The configure key must be a callable which receives the created class instance and config. It also has to return the instance. It is called just after the class has been resolved from Yii's DI container.
For example it's possible to customize Monolog\Handler\RotatingFileHandler
's filename format:
'handlers' => [
RotatingFileHandler::class => [
'path' => 'something',
'maxFiles' => 2,
'configure' => function (RotatingFileHandler $handler, $config) {
$handler->setFilenameFormat('myprefix-{filename}-{date}', 'Y-m-d');
return $handler;
}
],
]
If you want to integrate this component into an existing project which utilizes Yii's own logger, you can configure channels as log targets easily. See Yii's documentation about log targets here.
Example configuration:
use leinonen\Yii2Monolog\MonologTarget;
use leinonen\Yii2Monolog\Yii2Monolog;
[
'bootstrap' => ['monolog', 'log'],
'components' => [
...
'monolog' => [
'class' => Yii2Monolog::class,
'channels' => [
'myFirstChannel' => [
...
],
'someOtherAwesomeChannel' => [
...
],
],
'mainChannel' => 'someOtherAwesomeChannel'
],
'log' => [
'targets' => [
[
'class' => MonologTarget::class,
'channel' => 'myFirstChannel',
'levels' => ['error', 'warning']
],
]
]
]
]
In this case all the Yii's loggers messages will go through the handler / processor stack of myFirstChannel
logger without touching any of your existing code.
\Yii::warning('hello');
\Yii::error('world!');
If you leave the channel configuration out the target will use the main channel configured in the component.
If you want to not use Yii's logger at all it's possible to use this component as a completely standalone logger.
Fetching a specific logger from the component:
$myChannelLogger = Yii::$app->monolog->getLogger('myChannel');
$myChannelLogger->critical('help me!');
$mainChannelLogger = Yii::$app->monolog->getLogger();
$mainChannelLogger->notice('This was a log message through the main channel');
As the main channel is registered as the implementation of the Psr\Log\LoggerInterface
you can also use constructor injection in your controllers:
class SuperController
{
private $logger;
public function __construct($id, $module, LoggerInterface $logger, $config = [])
{
$this->logger = $logger;
parent::__construct($id, $module, $config);
}
public function actionExample()
{
$this->logger->notice('Action Example was called');
}
}