Les logs permettent d’écrire les données que l’on souhaite dans des fichiers.
Ils peuvent avoir différentes priorité, du simple au debug à l’erreur critique, nous allons voir comment logger nos informations avec Magento 2
Injection du logger
Commencez par créer le fichier :
app/code/Maxime/Jobs/Controller/Job/Testlog.php
Mettez-y ce contenu :
<?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(); } }
Ici on injecte notre classe « Logger », puis on affiche sa classe pour savoir de quel type est cet objet.
Allez sur votre site via l’URL :
http://magento2.lan/jobs/job/testlog
Vous devriez voir s’afficher :
Magento\Framework\Logger\Monolog
Notre objet est de ce type car si vous allez dans le fichier :
app/etc/di.xml
Vous aurez une ligne qui dicte quelle classe utiliser :
<preference for="Psr\Log\LoggerInterface" type="Magento\Framework\Logger\Monolog" />
Différents niveau de log
En se rendant dans cette classe, nous avons peu d’information, mais si vous allez dans sa classe parente :
vendor/monolog/monolog/src/Monolog/Logger.php
Vous remarquerez que plusieurs méthodes nous intéressent :
– addDebug ou debug
– addInfo ou info
– addNotice ou notice
– addWarning ou warn ou warning
– addError ou err ou error
– addCritical ou crit ou critical
– addAlert ou alert
– addEmergency ou emerg ou emergency
Elles permettent d’ajouter un log avec un niveau plus ou moins important. Dans cette liste, les niveaux vont du moins critique au plus critique.
Modifions notre controller comme ceci :
<?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(); } }
Maintenant si vous lancer l’URL dans votre navigateur, vous ne verrez rien.
Mais si vous allez dans var/log, vous aurez plusieurs fichiers.
Commencez par regarder le fichier var/log/system.log
Vous devriez apercevoir ces logs :
[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 [] []
Vous remarquerez qu’il manque le log du addDebug. Vous allez pouvoir le trouver dans le fichier :
var/log/debug.log
Vous devriez avoir cette ligne :
[2016-04-26 20:02:08] main.DEBUG: My debug log {"is_exception":false} []
Selon le niveau de votre log, Magento va soit le placer dans « system.log » soit dans « debug.log ». Cela se passe dans la classe vendor/monolog/monolog/src/Monolog/Logger.php dans la méthode addRecord où il recherche un « handler » pour écrire le log.
Créez son propre fichier de log
Nous allons voir comment créer notre propre fichier de log.
Commencez par créer le fichier :
app/code/Maxime/Jobs/Logger/Logger.php
Et mettez-y ce code :
<?php namespace Maxime\Jobs\Logger; class Logger extends \Monolog\Logger { }
Ensuite créez le fichier :
app/code/Maxime/Jobs/Logger/Handler.php
Ici on va lui dire quel fichier utiliser :
<?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'; }
Ensuite, nous devons faire des modifications dans le fichier :
app/code/Maxime/Jobs/etc/di.xml
Ajoutez juste avant la fermeture du noeud « config » le code suivant :
<!-- 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>
Voici le fichier complet si vous le souhaitez :
<?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>
Pour finir, nous allons utiliser notre classe Logger dans notre controller, modifiez donc le fichier :
app/code/Maxime/Jobs/Controller/Job/Testlog.php
Avec ce 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(); } }
Il est possible qu’à ce stade vous ayez une erreur si vous accédez à la page de test des logs. Pour éviter cela, supprimez les dossier « generation », « cache » et « page_cache » dans le dossier « var »
Maintenant si vous rechargez la page de tout à l’heure, vous ne verrez toujours rien, mais notre fichier de log a été créé :
var/log/maxime_jobs.log
Et contient ces 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 [] []
Le nom de notre logger déclaré dans le di.xml : « maximeJobs » apparaît dans notre fichier de log.
Ici vous remarquez que le log debug est bien présent dans notre fichier !
Pourquoi ? Eh bien dans notre classe app/code/Maxime/Jobs/Logger/Handler.php
nous avons mis le $loggerType à « Logger::DEBUG »
Salut Maxime,
Pour le chemin du fichier log :
c’est :
var/log/maxime_jobs.log
et pas
/var/log/maxime_jobs.log
Désolé je me suis trompé
Salut Maxime,
Faut-t-il ajouter la ligne :
dans le fichier : app/code/Maxime/Jobs/etc/di.xml
pour avoir Maxime\Jobs\Logger\Logge au lieu Magento\Framework\Logger\Monolog dans le constructeur de l’action ???