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 :
<?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>
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”
This is not working for me. Even not logging at all.
Can you please check once your code?
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 😉