Magento 2 Training : Unit 8 – Lesson A

You can log what you want inside the Magento logs files. You can define the level of you message : debug, warning, critical ?
Let’s see how to use it with Magento 2 !

Logger injection

You can create the file :
app/code/Maxime/Jobs/Controller/Job/Testlog.php

With this content :

<?php
namespace Maxime\Jobs\Controller\Job;

class Testlog extends \Magento\Framework\App\Action\Action
{
    /**
     * Logger
     *
     * @var LoggerInterface
     */
    protected $_logger;

    /**
     * @param \Magento\Framework\App\Action\Context $context
     * @param \Psr\Log\LoggerInterface $logger
     */
    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Psr\Log\LoggerInterface $logger
    )
    {
        $this->_logger = $logger;
        parent::__construct($context);
    }

    public function execute()
    {
        var_dump(get_class($this->_logger));

        $this->_view->loadLayout();
        $this->_view->getLayout()->initMessages();
        $this->_view->renderLayout();
    }
}

On this class, we inject our “Logger”, and we display the classname of the object.

Go on this URL :
http://magento2.lan/jobs/job/testlog

We will see this string :
Magento\Framework\Logger\Monolog

Our object has got this class besause it’s defined on this file :
app/etc/di.xml

You will see a line like this :
<preference for="Psr\Log\LoggerInterface" type="Magento\Framework\Logger\Monolog" />

Log levels

Is you check the code inside the Monolog class you will not see a lot of informations. But if you check inside it’s parent :
vendor/monolog/monolog/src/Monolog/Logger.php

You will see some interesting methods :
– addDebug or debug
– addInfo or info
– addNotice or notice
– addWarning or warn or warning
– addError or err or error
– addCritical or crit or critical
– addAlert or alert
– addEmergency or emerg or emergency

These methods allow you to add some log with the level you want. Debug is the less crtitical, and emergence is the most critical.

Now, you can update the controller file with this code :

<?php
namespace Maxime\Jobs\Controller\Job;

class Testlog extends \Magento\Framework\App\Action\Action
{
    /**
     * Logger
     *
     * @var LoggerInterface
     */
    protected $_logger;

    /**
     * @param \Magento\Framework\App\Action\Context $context
     * @param \Psr\Log\LoggerInterface $logger
     */
    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Psr\Log\LoggerInterface $logger
    )
    {
        $this->_logger = $logger;
        parent::__construct($context);
    }

    public function execute()
    {
        $this->_logger->addDebug('My debug log');
        $this->_logger->addInfo('My info log');
        $this->_logger->addNotice('My notice log');
        $this->_logger->addWarning('My warning log');
        $this->_logger->addError('My error log');
        $this->_logger->addCritical('My critical log');
        $this->_logger->addAlert('My alert log');
        $this->_logger->addEmergency('My emergency log');

        $this->_view->loadLayout();
        $this->_view->getLayout()->initMessages();
        $this->_view->renderLayout();
    }
}

Is you run the previous URL, you will see nothing.
But inside the folder “var/log”, you will have many files.

Open the file var/log/system.log
You will see these logs at the end of the file :

[2016-04-26 20:02:08] main.INFO: My info log [] []
[2016-04-26 20:02:08] main.NOTICE: My notice log [] []
[2016-04-26 20:02:08] main.WARNING: My warning log [] []
[2016-04-26 20:02:08] main.ERROR: My error log [] []
[2016-04-26 20:02:08] main.CRITICAL: My critical log [] []
[2016-04-26 20:02:08] main.ALERT: My alert log [] []
[2016-04-26 20:02:08] main.EMERGENCY: My emergency log [] []

But, where is the debug log ? You will see it inside the file :
var/log/debug.log
This line must be inside :

[2016-04-26 20:02:08] main.DEBUG: My debug log {"is_exception":false} []

Depending on the log level, your message will be added on “system.log” or “debug.log” file.
Inside the class vendor/monolog/monolog/src/Monolog/Logger.php, the method addRecord search a “handler” to define where to write the log.

Create your own log file with Magento 2

Create the file :
app/code/Maxime/Jobs/Logger/Logger.php

And put this code :

<?php

namespace Maxime\Jobs\Logger;

class Logger extends \Monolog\Logger
{

}

After, create the following file :
app/code/Maxime/Jobs/Logger/Handler.php

Inside this class, we will set the log filename :

<?php
namespace Maxime\Jobs\Logger;

use Monolog\Logger;

class Handler extends \Magento\Framework\Logger\Handler\Base
{
    /**
     * Logging level
     * @var int
     */
    protected $loggerType = Logger::DEBUG;

    /**
     * File name
     * @var string
     */
    protected $fileName = '/var/log/maxime_jobs.log';
}

Nos we have to change the “di.xml” file, which define dependancy injections :
app/code/Maxime/Jobs/etc/di.xml

After the closing “config” tag, add this code :

    <!-- Logger and Handler -->
    <type name="Maxime\Jobs\Logger\Handler">
        <arguments>
            <argument name="filesystem" xsi:type="object">Magento\Framework\Filesystem\Driver\File</argument>
        </arguments>
    </type>
    <type name="Maxime\Jobs\Logger\Logger">
        <arguments>
            <argument name="name" xsi:type="string">maximeJobs</argument>
            <argument name="handlers"  xsi:type="array">
                <item name="system" xsi:type="object">Maxime\Jobs\Logger\Handler</item>
            </argument>
        </arguments>
    </type>

Here is the full file if you want :

Afficher

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <!-- Create our type DepartmentGridDataProvider -->
    <virtualType name="DepartmentGridDataProvider" type="Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider">
        <arguments>
            <argument name="collection" xsi:type="object" shared="false">Maxime\Jobs\Model\Resource\Department\Collection</argument>
            <argument name="filterPool" xsi:type="object" shared="false">DepartmentGridFilterPool</argument> <!-- Define new object for filters -->
        </arguments>
    </virtualType>

    <!-- Create our type DepartmentGridFilterPool -->
    <virtualType name="DepartmentGridFilterPool" type="Magento\Framework\View\Element\UiComponent\DataProvider\FilterPool">
        <arguments>
            <argument name="appliers" xsi:type="array">
                <item name="regular" xsi:type="object">Magento\Framework\View\Element\UiComponent\DataProvider\RegularFilter</item>
                <item name="fulltext" xsi:type="object">Magento\Framework\View\Element\UiComponent\DataProvider\FulltextFilter</item>
            </argument>
        </arguments>
    </virtualType>

    <!-- Custom collection factory here -->
    <type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
        <arguments>
            <argument name="collections" xsi:type="array">
                <!-- Type for jobs_department_listing_data_source -->
                <item name="jobs_department_listing_data_source" xsi:type="string">Maxime\Jobs\Model\ResourceModel\Grid\Department\Collection</item>
                <!-- Type for jobs_job_listing_data_source -->
                <item name="jobs_job_listing_data_source" xsi:type="string">Maxime\Jobs\Model\ResourceModel\Grid\Job\Collection</item>
            </argument>
        </arguments>
    </type>

    <!-- Simulate our class Maxime\Jobs\Model\ResourceModel\Grid\Department\Collection -->
    <virtualType name="Maxime\Jobs\Model\ResourceModel\Grid\Department\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
        <arguments>
            <argument name="mainTable" xsi:type="string">maxime_department</argument>
            <argument name="resourceModel" xsi:type="string">Maxime\Jobs\Model\ResourceModel\Department</argument>
        </arguments>
    </virtualType>

    <!-- Create our type JobGridDataProvider -->
    <virtualType name="JobGridDataProvider" type="Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider">
        <arguments>
            <argument name="collection" xsi:type="object" shared="false">Maxime\Jobs\Model\Resource\Job\Collection</argument>
            <argument name="filterPool" xsi:type="object" shared="false">JobGridFilterPool</argument> <!-- Define new object for filters -->
        </arguments>
    </virtualType>

    <!-- Create our type JobGridFilterPool -->
    <virtualType name="JobGridFilterPool" type="Magento\Framework\View\Element\UiComponent\DataProvider\FilterPool">
        <arguments>
            <argument name="appliers" xsi:type="array">
                <item name="regular" xsi:type="object">Magento\Framework\View\Element\UiComponent\DataProvider\RegularFilter</item>
                <item name="fulltext" xsi:type="object">Magento\Framework\View\Element\UiComponent\DataProvider\FulltextFilter</item>
            </argument>
        </arguments>
    </virtualType>

    <!-- Simulate our class Maxime\Jobs\Model\ResourceModel\Grid\Job\Collection -->
    <virtualType name="Maxime\Jobs\Model\ResourceModel\Grid\Job\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
        <arguments>
            <argument name="mainTable" xsi:type="string">maxime_job</argument>
            <argument name="resourceModel" xsi:type="string">Maxime\Jobs\Model\ResourceModel\Job</argument>
        </arguments>
    </virtualType>

    <!-- Logger and Handler -->
    <type name="Maxime\Jobs\Logger\Handler">
        <arguments>
            <argument name="filesystem" xsi:type="object">Magento\Framework\Filesystem\Driver\File</argument>
        </arguments>
    </type>
    <type name="Maxime\Jobs\Logger\Logger">
        <arguments>
            <argument name="name" xsi:type="string">maximeJobs</argument>
            <argument name="handlers"  xsi:type="array">
                <item name="system" xsi:type="object">Maxime\Jobs\Logger\Handler</item>
            </argument>
        </arguments>
    </type>
</config>

[collapse]

To finish, we have to use our custom Logger inside our controller, modify the file
app/code/Maxime/Jobs/Controller/Job/Testlog.php

With this code :

<?php
namespace Maxime\Jobs\Controller\Job;

class Testlog extends \Magento\Framework\App\Action\Action
{
    /**
     * Logger
     *
     * @var LoggerInterface
     */
    protected $_logger;

    /**
     * @param \Magento\Framework\App\Action\Context $context
     * @param \Maxime\Jobs\Logger\Logger $logger
     */
    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Maxime\Jobs\Logger\Logger $logger
    )
    {
        $this->_logger = $logger;
        parent::__construct($context);
    }

    public function execute()
    {
        $this->_logger->addDebug('My debug log');
        $this->_logger->addInfo('My info log');
        $this->_logger->addNotice('My notice log');
        $this->_logger->addWarning('My warning log');
        $this->_logger->addError('My error log');
        $this->_logger->addCritical('My critical log');
        $this->_logger->addAlert('My alert log');
        $this->_logger->addEmergency('My emergency log');

        $this->_view->loadLayout();
        $this->_view->getLayout()->initMessages();
        $this->_view->renderLayout();
    }
}

If you have an error when you test this code, delete folders “var/generation”, “var/cache”, and “var/page_cache”

Now, if you reload the page, it will write the logs inside our file :
var/log/maxime_jobs.log

It will contains these messages :

[2016-05-01 22:02:29] maximeJobs.DEBUG: My debug log [] []
[2016-05-01 22:02:29] maximeJobs.INFO: My info log [] []
[2016-05-01 22:02:29] maximeJobs.NOTICE: My notice log [] []
[2016-05-01 22:02:29] maximeJobs.WARNING: My warning log [] []
[2016-05-01 22:02:29] maximeJobs.ERROR: My error log [] []
[2016-05-01 22:02:29] maximeJobs.CRITICAL: My critical log [] []
[2016-05-01 22:02:29] maximeJobs.ALERT: My alert log [] []
[2016-05-01 22:02:29] maximeJobs.EMERGENCY: My emergency log [] []

The logger name we define inside the “di.xml” file is displayed : “maximeJobs”
And the debug message is not inside the debug.log file, but in our custom file !

Why ? Because inside our class app/code/Maxime/Jobs/Logger/Handler.php we set the $loggerType to “Logger::DEBUG”

Continue training
Return to previous lesson
Logs and Magento 2
Tagged on:

2 thoughts on “Logs and Magento 2

  • 05/31/2016 at 13:03
    Permalink

    This is not working for me. Even not logging at all.
    Can you please check once your code?

    Reply
    • 05/31/2016 at 13:09
      Permalink

      It works. Maybe check this points :
      – Check the file permissions of your var folder. You can go on http://www.maximehuran.fr/en/install-magento-2/ part “Ownership and permissions creation”
      – If you have Magento 2.1 Release Candidate, maybe it not work, this training is not tested yet with this version, because it’s not the final version already (it is in RC)

      Hope it will help you 😉

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

We use cookies to ensure that we give you the best experience on our website.
Ok