Magento 2: sostituzione per il metodo Mage :: log?


105

In Magento 1, se si desidera inviare un messaggio ai registri, si utilizzerà un metodo statico sulla Mageclasse globale .

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

C'è un equivalente in Magento 2? Ho cercato su Google attraverso il sito di sviluppo di documenti e non ho visto nulla di ovvio che si apre. C'è questo articolo di Inchoo , ma è di quasi un anno fa e da allora sono cambiate molte cose.

Come sviluppatore del modulo Magento 2, se voglio sostituire il codice come il seguente in Magento 1

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

Qual è il minimo indispensabile che devo fare?

Risposte:


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

Ad esempio, si utilizza il debug, l'eccezione, il sistema per il logger PSR:

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

9
+1 Grazie, questa è un'interfaccia / classe / tipo utile da conoscere - ma dalla tua risposta non è chiaro dove verranno registrate le informazioni e come (se possibile) cambiare quella posizione.
Alan Storm,

Controlla Manager.php per la seguente classe Magento \ Framework \ Event e aggiungi questa riga $ this-> logger-> debug ($ eventName); che dopo l'aggiornamento della pagina e il controllo del file debug.txt si ottiene tutto il nome per pagina specifica.
Pratik,

2
Tecnicamente, questo è il modo "corretto" di creare un'istanza di un logger nelle proprie classi personalizzate, in particolare se si intende mantenerlo attivo piuttosto che solo un rapido debug. Tuttavia, esistono diverse classi principali, in particolare le classi Block, che istanziano e memorizzano automaticamente una proprietà _logger. Se estendi una di queste classi principali, non è necessario ripetere la logica. Altre risposte scavano nella creazione di gestori per definire il proprio file di registro, ma i registri predefiniti sono sempre /var/log/system.log o /var/log/debug.log. Credo che la funzione di registrazione specifica determini quale viene utilizzato.
Jeremy Rimpo,

7
Per me, il livello "debug" ha iniziato a funzionare solo quando ho abilitato "Accedi al file" in Configurazione> Avanzate> Sviluppatore> Debug. Uso 2.2
Omer Sabic,

122

In magento2, puoi anche scrivere nei log usando la Zendlibreria come di seguito:

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

Modificato

Puoi anche stampare oggetti e matrici PHP come di seguito:

$logger->info(print_r($yourArray, true));

7
+1 Utile: sai se Zend logger formatterà automaticamente array / oggetti PHP ecc.?
Alan Storm,

1
@AlanStorm - Sì, puoi, controlla la mia risposta aggiornata.!
Manashvi Birla,

2
@Manashvibirla: PHP objectsnon stanno stampando ...
zed Barbanera

3
Molte di queste risposte hanno il loro posto e uso. Ovviamente questa soluzione richiede quasi lo stesso codice dell'utilizzo di DI per creare un'istanza del logger standard, ma è un semplice drop-in sul posto che consente di impostare il proprio file di registro. A volte è piuttosto fastidioso cercare nei file di registro standard - che tendono a essere disordinati - per trovare i propri registri. Quindi questa è una bella soluzione 'rapida' per questo.
Jeremy Rimpo,

2
È re dell'imbarazzo quante volte vengo qui per copiare e usare questo ... <3
Lez

56
\Magento\Framework\App\ObjectManager::getInstance()
    ->get(\Psr\Log\LoggerInterface::class)->debug('message');

6
+1 Grazie, questa è un'interfaccia / classe / tipo utile da conoscere - ma dalla tua risposta non è chiaro dove verranno registrate le informazioni e come (se possibile) cambiare quella posizione.
Alan Storm,

1
Questa è la risposta corretta
medina,

4
Non consiglierei di usare direttamente l'ObjectManager. Usa invece DI
7

12
Mentre sono d'accordo con @ 7ochem se stai creando una funzione di registrazione permanente, può essere necessario iniettare la registrazione temporanea in classi core (o di terze parti) di volta in volta per eseguire il debug dei problemi. Passare attraverso l'arduo processo di aggiunta di una classe Logger al costruttore è inutilmente complicato in questi casi. Per una semplice funzione di debug a riga singola questa è probabilmente la soluzione migliore. Tuttavia, dovrai cercare con i file di registro predefiniti per trovare il tuo output di debug.
Jeremy Rimpo,

Inoltre, tieni presente che esistono diverse classi principali, in particolare le classi Block, che hanno una proprietà _logger a cui puoi accedere senza creare un'istanza di una nuova copia.
Jeremy Rimpo,

28

Registro di stampa temporaneo con nuovo file

$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

Metodo di fabbrica

È necessario iniettare la classe \ Psr \ Log \ LoggerInterface nel costruttore per chiamare l'oggetto 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));

}

Oppure usi direttamente questo codice nel file phtml:

Per stampare l'output della stringa in debug.log

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

Per stampare l'output dell'array in 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));

10

Se si desidera utilizzare il logger predefinito ma un file personalizzato per la registrazione (o altra logica personalizzata) è necessario utilizzare il gestore del logger personalizzato:

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

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

Quindi aggiungilo come gestore da qualche parte nel tuo codice:

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

Un passo indietro per comodità IMO


+1 Informazioni utili, grazie! Tuttavia, non è chiaro come si utilizza questo contesto del logger con l'interfaccia del caricatore automatico PSR-3, ad esempio se si sta effettuando il login $this->logger->info($message, $level);, come si dice "usa il mio contesto"?
Alan Storm,

2
Bene, il fatto è che tutti i gestori disponibili per Monolog sono collegati in loop e per primi in grado di gestire il livello di registrazione (DEBUG, INFO ecc.). Quindi l'unico modo in cui vedo per essere assolutamente sicuro che il tuo gestore sia usato, è di spingerlo prima che tu ne abbia bisogno, quindi è in cima allo stack e arriva prima nel ciclo. Un altro modo sarebbe semplicemente impostarlo come gestore, rimuovendo tutti gli altri, ma non sarà una cosa molto amichevole da fare.
Petar Dzhambazov,

Se si tenta di introdurre gestori aggiuntivi in ​​GA 2.0.0 o si lavora specificando i gestori in di.xml, si consiglia di conoscere questo problema github.com/magento/magento2/issues/2529 Ho riscontrato questo problema provando per ottenere un logger personalizzato per avere un handle di file di registro personalizzato e un gestore personalizzato che scrive alcune voci in una tabella del database.
mttjohnson,

9

In modo semplice se non si desidera creare l'inserimento di dipendenze o qualsiasi altra cosa si usi sotto il codice, esso memorizzerà il system.logfile di accesso

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

È tutto..



4

Includi la classe psr logger nel tuo file usando use e quindi chiama il addDebug()metodo. Questo stamperà il messaggio di registro nel var/log/debug.logfile

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");
  }

}

2
non dovresti usare addDebug in quanto non è compatibile con psr logger. usa invece solo il debug.
Maciej Paprocki,

4

AGGIORNATO: 19/08/2019

Se stai cercando un elegante gestore di log personalizzato, ti consiglio di usare i tipi virtuali (che non hanno bisogno di aggiungere alcun codice PHP)

Ispirato dalla risposta di Petar Dzhambazov e Halk , signore e signori, vi ho presentato un modo migliore e più breve invece di duplicare il codice di registro personalizzato in ogni momento.

StackOverflow \ Esempio \ 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>

USO

Venditore \ Qualcosa \ modello \ 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 \ Esempio \ 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>

Questo è tutto, senza file o linee PHP extra - usa i vantaggi di Magento 2: Tipi virtuali !!!

Spero che sia di aiuto ;)


3
Questo codice sta implementando PSI? (Iniezione di dichiarazioni politiche): P
7

1
@ 7ochem Oh sì, è: v
Toan Nguyen

2

C'è un aggiornamento per logger in 2.2. È possibile abilitare il logger per la modalità di produzione eseguendo SQL:

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

Quindi è possibile utilizzare \Psr\Log\LoggerInterface per il registro di stampa proprio come sopra le risposte:

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));
}

grazie, e puoi anche usare questo invece di 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. Inietta $loggerclasse nel costruttore \Psr\Log\LoggerInterface $logger
    Ciò si ottiene passando $ logger come argomento.

  2. Inizializza $loggernel costruttore

    $this->logger = $logger
  3. In funzione all'interno della classe che si desidera accedere utilizzare la riga seguente

    $this->logger->debug($message);
    $this->logger->log($level, $message);
    

1

Se ne hai bisogno all'interno della tua singola classe con file di registro personalizzato:

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'));
}

0

Inserisci il codice del logger PSR nel costruttore:

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

quindi puoi utilizzare nella tua funzione come:

$this->logger->info($message);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.