Magento 2: remplacement de la méthode Mage :: log?

105

Dans Magento 1, si vous vouliez envoyer un message aux journaux, vous utiliseriez une méthode statique sur la Mageclasse globale .

Mage::log($message, Zend_Log::DEBUG, "my-log-file.log");

Existe-t-il un équivalent dans Magento 2? J'ai consulté Google sur le site des documents de développement et je n'ai encore rien vu d'évident. Il y a cet article Inchoo , mais il y a presque un an et tant de choses ont changé depuis.

En tant que développeur de module Magento 2, si je veux remplacer le code suivant dans Magento 1

Mage::log($message, Zend_Log::DEBUG, "my-log-file.log");

Quel est le minimum que je dois faire?

Alan Storm
la source

Réponses:

124
protected $logger;
public function __construct(\Psr\Log\LoggerInterface $logger)
{
    $this->logger = $logger;
}

Vous utilisez debug, exception, system pour PSR Logger, par exemple:

$this->logger->info($message);
$this->logger->debug($message);
Pratik
la source
9
+1 Merci, c'est une interface / classe / type utile à connaître - mais votre réponse ne précise pas où les informations seront enregistrées et comment (si possible) modifier cet emplacement.
Alan Storm
Vous vérifiez Manager.php pour la classe suivante Magento \ Framework \ Event et ajoutez cette ligne $ this-> logger-> debug ($ eventName); Après avoir actualisé la page et vérifié le fichier debug.txt, vous obtenez tous les noms évidents pour une page spécifique.
Pratik
2
Techniquement, il s'agit du moyen "correct" d'instancier un enregistreur dans vos propres classes personnalisées, en particulier si vous souhaitez le conserver plutôt que de simplement un débogage rapide. Cependant, il existe plusieurs classes principales - en particulier les classes Block - qui instancient et stockent automatiquement une propriété _logger. Si vous étendez l'une de ces classes de base, il n'est pas nécessaire de répéter la logique. D'autres réponses permettent de créer des gestionnaires pour définir votre propre fichier journal, mais les journaux par défaut sont toujours /var/log/system.log ou /var/log/debug.log. Je crois que la fonction de journalisation spécifique détermine laquelle est utilisée.
Jeremy Rimpo
7
Pour moi, le niveau "débogage" a commencé à fonctionner uniquement lorsque j'ai activé l'option "Enregistrer dans un fichier" dans Configuration> Avancé> Développeur> Débogage. Utilisation de 2.2
Omer Sabic
122

Dans magento2, vous pouvez également écrire dans les journaux à l'aide de la Zendbibliothèque, comme ci-dessous:

$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/test.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info('Your text message');

Édité

Vous pouvez également imprimer des objets et des tableaux PHP comme ci-dessous:

$logger->info(print_r($yourArray, true));
Manashvi Birla
la source
7
+1 Utile - savez-vous si Zend logger formatera automatiquement les tableaux / objets PHP, etc.?
Alan Storm
1
@AlanStorm - Oui, vous pouvez vérifier ma réponse mise à jour.!
Manashvi Birla
2
@Manashvibirla: n'imprime PHP objectspas ...
Black Barbe Noir
3
Plusieurs de ces réponses ont leur place et leur utilisation. Évidemment, cette solution nécessite presque autant de code que l’utilisation de DI pour instancier l’enregistreur standard, mais c’est un simple dépôt sur place qui vous permet de définir votre propre fichier journal. Parfois, il est plutôt ennuyeux de chercher dans les fichiers journaux standard - qui ont tendance à être encombrés - pour trouver vos propres journaux. C'est donc une bonne solution "rapide" pour cela.
Jeremy Rimpo
2
C’est roi d’embarrasser à quelle fréquence je viens ici pour copier et utiliser cette ... <3
Lez
56
\Magento\Framework\App\ObjectManager::getInstance()
    ->get(\Psr\Log\LoggerInterface::class)->debug('message');
Mage2.PRO
la source
6
+1 Merci, c'est une interface / classe / type utile à connaître - mais votre réponse ne précise pas où les informations seront enregistrées et comment (si possible) modifier cet emplacement.
Alan Storm
1
C'est la bonne réponse.
médina
4
Je ne conseillerais pas d'utiliser directement ObjectManager. Utilisez DI à la place
7ochem
12
Bien que je sois d’accord avec @ 7ochem si vous créez une fonction de journalisation permanente, il peut être nécessaire d’injecter de temps en temps la journalisation temporaire dans les classes principales (ou tierces) pour résoudre les problèmes. Passer par le processus ardu d'ajouter une classe Logger au constructeur est inutilement compliqué dans ces cas. Pour une simple fonction de débogage sur une seule ligne, c'est probablement la meilleure solution. Cependant, vous devrez effectuer une recherche dans les fichiers journaux par défaut pour trouver votre propre sortie de débogage.
Jeremy Rimpo
N'oubliez pas non plus qu'il existe plusieurs classes principales, en particulier les classes Block, qui possèdent une propriété _logger à laquelle vous pouvez accéder sans instancier une nouvelle copie.
Jeremy Rimpo
28

Journal d'impression temporaire avec nouveau fichier

$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/logfile.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info('Simple Text Log'); // Simple Text Log
$logger->info('Array Log'.print_r($myArrayVar, true)); // Array Log

Méthode d'usine

Vous devez injecter la classe \ Psr \ Log \ LoggerInterface dans le constructeur pour appeler un objet logger.

protected $_logger;
public function __construct(
...
\Psr\Log\LoggerInterface $logger
...
) {
    $this->_logger = $logger;
}

public function logExample() {

    //To print string Output in debug.log
    $this->_logger->addDebug('Your Text Or Variables'); 

    // To print array Output in system.log
    $this->_logger->log('600', print_r($yourArray, true));

}

Ou vous utilisez directement ce code dans un fichier phtml:

Pour imprimer la chaîne Sortie dans le fichier debug.log

\Magento\Framework\App\ObjectManager::getInstance()
   ->get('Psr\Log\LoggerInterface')->debug('Your Message');

Pour imprimer un tableau Sortie dans system.log

$myArray = array('test1'=>'123', 'test2'=>'123', 'test3'=>'123');
$level = '100'; // use one of: 100, 200, 250, 300, 400, 500, 550, 600
\Magento\Framework\App\ObjectManager::getInstance()
    ->get('Psr\Log\LoggerInterface')
    ->log($level, print_r($myArray, true));
Prince Patel
la source
10

Si vous souhaitez utiliser le consignateur par défaut mais le fichier personnalisé pour la consignation (ou toute autre logique personnalisée), vous devez utiliser le gestionnaire de consignateur personnalisé:

class Logger extends Magento\Framework\Logger\Handler\Base
{
  /**
   * @var string
   */
  protected $fileName = '/var/log/my-log-file.log';

  /**
   * @var int
   */
  protected $loggerType = MonologLogger::DEBUG;
}

Puis ajoutez-le en tant que gestionnaire quelque part dans votre code:

protected function addCustomLogHandler()
{
    $logger = Data::getCustomLogger();
    if(isset($this->_logger)){
        $this->_logger->pushHandler($logger);
    }
}

Un pas en arrière dans le confort IMO

Petar Dzhambazov
la source
+1 Informations utiles, merci! Cependant, la manière dont vous utilisez ce contexte de journalisation avec l'interface de l'autochargeur PSR-3 n'est pas claire . Par exemple, si vous vous connectez avec $this->logger->info($message, $level);, comment dites-vous "utiliser mon contexte"?
Alan Storm
2
Le problème, c’est que tous les gestionnaires disponibles pour Monolog sont en boucle et que le premier qui peut gérer le niveau d’enregistrement (DEBUG, INFO, etc.) est utilisé. Donc, la seule façon pour moi d’être absolument sûr que votre gestionnaire est utilisé, est de le pousser avant que vous n’en ayez besoin. Une autre solution serait de simplement le définir en tant que gestionnaire, en supprimant tous les autres, mais cela ne sera pas très convivial.
Petar Dzhambazov
Si vous essayez d'introduire des gestionnaires supplémentaires dans la version 2.0.0 GA ou si vous spécifiez les gestionnaires dans di.xml, vous voudrez peut-être connaître le problème. Github.com/magento/magento2/issues/2529 J'ai rencontré ce problème en essayant pour qu'un enregistreur personnalisé ait un descripteur de fichier journal personnalisé et un gestionnaire personnalisé qui écrit certaines entrées dans une table de base de données.
mttjohnson
9

De manière simple, si vous ne voulez pas créer d'injection de dépendance ou utiliser quoi que ce soit d'autre, le code ci-dessous stockera le journal dans le system.logfichier

$logger = \Magento\Framework\App\ObjectManager::getInstance()->get(\Psr\Log\LoggerInterface::class);
$logger->info('message');

C'est tout..

Himanshu
la source
5

Non, il n'y a pas d'équivalent direct. C'est un peu compliqué maintenant.

Voir: Connexion à un fichier personnalisé dans Magento 2

Ryan Hoerr
la source
1
+1, merci! Cependant, d’autres réponses donnent à penser qu’il ne peut y avoir qu’un seul enregistreur, et l’approche extension / création d’une poignée n’est plus nécessaire. Savez-vous si c'est vrai?
Alan Storm
4

Incluez la classe psr logger dans votre fichier à l'aide de la méthode use puis call addDebug(). Ceci imprimera le message de log dans le var/log/debug.logfichier

use Psr\Log\LoggerInterface;

class demo {
  function demo()
  {
    //EDIT: Using debug instead of addDebug for PSR compatiblity
    $this->_objectManager->get('Psr\Log\LoggerInterface')->debug("your message goes here");
  }

}
chirag dodia
la source
2
vous ne devriez pas utiliser addDebug, car ce n'est pas compatible avec le logger psr. utilisez juste debug à la place.
Maciej Paprocki
4

MISE À JOUR: 19/08/2019

Si vous recherchez un gestionnaire de journaux élégant et personnalisé, je vous recommande d'utiliser des types virtuels (qui n'ont pas besoin d'ajouter de code PHP)

Inspirés de la réponse de Petar Dzhambazov et de halk , Mesdames et Messieurs, je vous ai présenté un moyen plus efficace et plus court au lieu de dupliquer le code de journal personnalisé en permanence.

StackOverflow \ Example \ etc \ di.xml

<!-- Custom log file for StackOverflow ; Duplicate it as much as you want separate log file -->
<virtualType name="StackOverflow\Example\Model\Logger\VirtualDebug" type="Magento\Framework\Logger\Handler\Base">
    <arguments>
        <argument name="fileName" xsi:type="string">/var/log/stackoverflow/donald_trump.log</argument>
    </arguments>
</virtualType>
<virtualType name="StackOverflow\Example\Model\Logger\VirtualLogger" type="Magento\Framework\Logger\Monolog">
    <arguments>
        <argument name="name" xsi:type="string">DonaldTrump</argument>
        <argument name="handlers" xsi:type="array">
            <item name="debug" xsi:type="object"> StackOverflow\Example\Model\Logger\VirtualDebug</item>
        </argument>
    </arguments>
</virtualType>

USAGE

Vendeur \ Quelque chose \ Modèle \ DonaldTrump.php

<?php
/**
 * Copyright © 2016 Toan Nguyen <https://nntoan.github.io>. All rights reserved.
 * See COPYING.txt for license details.
 *
 * This is the file you want to inject your custom logger.
 * Of course, your logger must be an instance of \Psr\Log\LoggerInterface.
 */

namespace Vendor\Something\Model;

/**
 * DonaldTrump business logic file
 *
 * @package Vendor\Something\Model
 * @author  Toan Nguyen <https://github.com/nntoan>
 */
class DonaldTrump
{
    /**
     * @var \Psr\Log\LoggerInterface
     */
    private $logger;

    /**
     * DonaldTrump constructor.
     *
     * @param \Psr\Log\LoggerInterface $logger
     */
    public function __construct(
        \Psr\Log\LoggerInterface $logger,
    ) {
        $this->logger = $logger;
    }

    // 1 billion lines of code after this line
}

StackOverflow \ Example \ etc \ frontend \ di.xml

<type name="Vendor\Something\Model\DonaldTrump">
    <arguments>
        <argument name="logger" xsi:type="object">StackOverflow\Example\Model\Logger\VirtualLogger</argument>
    </arguments>
</type>

C'est tout, pas de fichiers PHP ni de lignes supplémentaires - utilisez les avantages de Magento 2: Types virtuels !!!

J'espère que cela t'aides ;)

Toan Nguyen
la source
3
Ce code implémente-t-il PSI? (Injections politiques): P
7ochem
1
@ 7ochem Oh oui, c’est: v
Toan Nguyen
2

Il y a une mise à jour pour l'enregistreur dans la version 2.2. Vous pouvez activer le consignateur pour le mode de production en exécutant SQL:

 "INSERT INTO core_config_data (scope, scope_id, path, value) VALUES ('default', '0', 'dev/debug/debug_logging', '1');"

Ensuite, vous pouvez utiliser \Psr\Log\LoggerInterface pour le journal d'impression comme dans les réponses ci-dessus:

protected $logger;

public function __construct(
  \Psr\Log\LoggerInterface $logger
) {
    $this->logger = $logger;
  }

public function yourFunction() {
    $data = ["test" => "testing"];
    $this->logger->debug(var_export($data, true));
}
Yogesh Karodiya
la source
merci, et vous pouvez également utiliser cela à la place de QUERY SQL:In the Magento admin panel, go to "Stores" -> "Configuration" -> "Advanced" -> "Developer" -> "Debug" -> "Log to File". Setting this to "Yes" will cause debug information to be logged to var/log/debug.log in your Magento application directory.
fudu
1
  1. Injecter la $loggerclasse dans le constructeur \Psr\Log\LoggerInterface $logger
    Ceci est réalisé en passant $ logger en argument.

  2. Initialiser $loggerdans le constructeur

    $this->logger = $logger
  3. En fonction dans la classe que vous souhaitez enregistrer, utilisez la ligne ci-dessous

    $this->logger->debug($message);
    $this->logger->log($level, $message);
Oscprofessionals
la source
1

Si vous en avez besoin dans votre classe unique avec un fichier journal personnalisé:

public function __construct(\Psr\Log\LoggerInterface $logger, \Magento\Framework\App\Filesystem\DirectoryList $dir) 
{
    $this->logger = $logger;
    $this->dir = $dir;

    $this->logger->pushHandler(new \Monolog\Handler\StreamHandler($this->dir->getRoot().'/var/log/custom.log'));
}
mshakeel
la source
0

Placez le code de l'enregistreur PSR dans votre constructeur:

protected $logger;
public function __construct(\Psr\Log\LoggerInterface $logger)
{
    $this->logger = $logger;
}

alors vous pouvez utiliser dans votre fonction comme:

$this->logger->info($message);

la source