In every development process you sometimes need to log variables or custom messages. Now, we will explain how to create a custom log. Magento 2 comes with built-in log facility which is based on Monolog library. You can find this package in the following location: “MAGENTO2_ROOT/vendor/monolog“.

The main Magento 2 log facility class is “Magento\Framework\Logger\Monolog, and this is defined in “MAGENTO2_ROOT/app/etc/di.xml” as:

<preference for="Psr\Log\LoggerInterface" type="Magento\Framework\Logger\Monolog" />

You can see that this class extends class “Monolog\Logger” from monolog package.

<?php
/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
 
namespace Magento\Framework\Logger;
 
use Monolog\Logger;
 
class Monolog extends Logger
{
}

In class “Monolog\Logger” there are a couple of interesting methods for creating logs.
These methods accept two arguments, the first argument is message (string) and the second one is optional array parameter (you can pass instance of object).

Some methods:

$this->_logger->addDebug($message); // log location: var/log/system.log
$this->_logger->addInfo($message); // log location: var/log/exception.log
$this->_logger->addNotice($message); // log location: var/log/exception.log
$this->_logger->addError($message); // log location: var/log/exception.log
$this->_logger->critical($e); // log location: var/log/exception.log

One useful example for logging php exception:

In Magento 1 we are using static method

Mage::logException($e);

In Magento 2 we are using an instance of “Magento\Framework\Logger\Monolog” and method “critical” for logging exception from try-catch

$this->_logger->critical($e);
// instance of $e will be converted to string (magic metod __toString() will be called).

Let’s start with an example of how to get instance of Magento\Framework\Logger\Monolog in your class.

Magento 2 uses dependency injection and all instances of classes come through class constructor.
If you want to use object “Magento\Framework\Logger\Monolog” then the instance should be passed through constructor of your class.

Example of this code is shown below:

<?php
namespace Guru\Test\Model;
 
class Example{
    protected $_logger;
    public function __construct(
        \Psr\Log\LoggerInterface $logger, //log injection
        array $data = []
    ) {
        $this->_logger = $logger;
        parent::__construct($data);
    }
    public function someExampleMethod() {
        /*
        some logic of method
        */
        //accessing to logger instance and calling log method
        $this->_logger->addDebug('some text or variable');
    }
}

You can see that we passed “\Psr\Log\LoggerInterface $logger” in class through constructor in order to be able to use log object in this class.
After that we can use instance “$this->_logger” in class “Guru\Test\Model\Example“.

If you want to write a log in your custom file name, in a custom location, then the process is not that simple :-), you will have to create a custom Log handler.

Main Magento 2 log class has three handlers which are defined in the same “MAGENTO2_ROOT/app/etc/di.xml” file. These handlers are: exception, system and debug.

main
 
                Magento\Framework\Logger\Handler\Critical
                Magento\Framework\Logger\Handler\System
                Magento\Framework\Logger\Handler\Debug

In some classes we don’t need to pass log object through constructor, because the log object already exists.
For example, we have this situation on every html block class which extends “\Magento\Framework\View\Element\Template” or in model class which extends “\Magento\Framework\Model\AbstractModel“.

These “parent” classes have already property “$_logger” instance of: Magento\Framework\Logger.

And there you go – I hope you’ll find this quick overview of Magento 2 logging and some customization options around it useful.

In case you feel you need some extra help, we can offer you a detailed custom report based on our technical audit – feel free to get in touch and see what we can do for you!