Magento 2: Ersatz für Mage :: log-Methode?

105

Wenn Sie in Magento 1 eine Nachricht an die Protokolle senden möchten, verwenden Sie eine statische Methode für die globale MageKlasse.

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

Gibt es in Magento 2 ein Äquivalent? Ich habe die Seite mit den Entwicklerdokumenten durchgegoogelt und keine offensichtlichen Probleme festgestellt. Es gibt diesen Inchoo- Artikel, aber er ist fast ein Jahr her und seitdem hat sich so viel geändert.

Wenn ich als Magento 2-Modulentwickler Code wie den folgenden in Magento 1 ersetzen möchte

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

Was ist das Nötigste, was ich tun muss?

Alan Storm
quelle

Antworten:

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

Sie verwenden Debug, Exception, System für PSR Logger, zum Beispiel:

$this->logger->info($message);
$this->logger->debug($message);
Pratik
quelle
9
+1 Vielen Dank, das ist eine nützliche Schnittstelle / Klasse / Typ, über die Sie Bescheid wissen müssen. Aus Ihrer Antwort geht jedoch nicht hervor, wo die Informationen protokolliert werden und wie (wenn möglich) dieser Speicherort geändert werden kann.
Alan Storm
Sie überprüfen Manager.php auf folgende Klasse: Magento \ Framework \ Event und fügen diese Zeile hinzu: $ this-> logger-> debug ($ eventName); Nach dem Aktualisieren der Seite und dem Überprüfen der Datei debug.txt erhalten Sie alle relevanten Namen für eine bestimmte Seite.
Pratik
2
Technisch gesehen ist dies die 'richtige' Möglichkeit, einen Logger in Ihren eigenen benutzerdefinierten Klassen zu instanziieren - insbesondere, wenn Sie ihn behalten möchten, anstatt nur ein kurzes Debuggen durchzuführen. Es gibt jedoch mehrere Kernklassen - insbesondere Blockklassen -, die automatisch eine _logger-Eigenschaft instanziieren und speichern. Wenn Sie eine dieser Kernklassen erweitern, müssen Sie die Logik nicht wiederholen. Andere Antworten befassen sich mit dem Erstellen von Handlern zum Definieren Ihrer eigenen Protokolldatei. Die Standardprotokolle lauten jedoch immer /var/log/system.log oder /var/log/debug.log. Ich glaube, die spezifische Protokollierungsfunktion bestimmt, welche verwendet wird.
Jeremy Rimpo
7
Für mich begann die "Debug" -Ebene erst zu funktionieren, als ich "In Datei protokollieren" unter "Konfiguration"> "Erweitert"> "Entwickler"> "Debuggen" aktivierte. Mit 2.2
Omer Sabic
122

In magento2 können Sie auch mithilfe der folgenden ZendBibliothek in die Protokolle schreiben :

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

Bearbeitet

Sie können auch PHP-Objekte und -Arrays wie folgt drucken:

$logger->info(print_r($yourArray, true));
Manashvi Birla
quelle
7
+1 Nützlich - wissen Sie, ob Zend Logger PHP Arrays / Objekte usw. automatisch formatiert?
Alan Storm
1
@AlanStorm - Ja, Sie können meine aktualisierte Antwort überprüfen.!
Manashvi Birla
2
@ Manashvibirla: PHP objectswerden nicht gedruckt ...
zed Blackbeard
1
@KeyurShah Die Lösung bestand darin, Ubuntu im Hinterkopf zu behalten, da ich Ubuntu verwendete.!
Vielen
3
Einige dieser Antworten haben ihren Platz und ihre Verwendung. Offensichtlich erfordert diese Lösung fast so viel Code wie DI, um den Standard-Logger zu instanziieren - aber es ist ein einfaches In-Place-Drop-In, mit dem Sie Ihre eigene Logdatei erstellen können. Manchmal ist es ziemlich ärgerlich, die Standardprotokolldateien zu durchsuchen, die überfüllt sind, um Ihre eigenen Protokolle zu finden. Das ist also eine nette 'schnelle' Lösung dafür.
Jeremy Rimpo
56
\Magento\Framework\App\ObjectManager::getInstance()
    ->get(\Psr\Log\LoggerInterface::class)->debug('message');
Mage2.PRO
quelle
6
+1 Vielen Dank, das ist eine nützliche Schnittstelle / Klasse / Typ, über die Sie Bescheid wissen müssen. Aus Ihrer Antwort geht jedoch nicht hervor, wo die Informationen protokolliert werden und wie (wenn möglich) dieser Speicherort geändert werden kann.
Alan Storm
1
Das ist die richtige Antwort.
Medina
4
Ich würde nicht empfehlen, den ObjectManager direkt zu verwenden. Verwenden Sie stattdessen DI
7ochem
12
Obwohl ich mit @ 7ochem einverstanden bin, wenn Sie eine permanente Protokollierungsfunktion erstellen, kann es erforderlich sein, von Zeit zu Zeit temporäre Protokollierungen in Kernklassen (oder in Klassen von Drittanbietern) einzufügen, um Probleme zu debuggen. Der mühsame Prozess des Hinzufügens einer Logger-Klasse zum Konstruktor ist in diesen Fällen unnötig kompliziert. Für eine einfache, einzeilige Debug-Funktion ist dies wahrscheinlich die beste Lösung. Sie müssen sich jedoch mit dem Durchsuchen der Standardprotokolldateien befassen, um Ihre eigene Debug-Ausgabe zu finden.
Jeremy Rimpo
Beachten Sie auch, dass es mehrere Kernklassen gibt - insbesondere Blockklassen -, die eine _logger-Eigenschaft haben, auf die Sie zugreifen können, ohne eine neue Kopie zu erstellen.
Jeremy Rimpo
28

Temporäres Druckprotokoll mit neuer Datei

$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

Fabrik Methode

Sie müssen die Klasse \ Psr \ Log \ LoggerInterface in den Konstruktor einfügen , um das Logger-Objekt aufzurufen

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

}

Oder Sie verwenden diesen Code direkt in der HTML-Datei:

So drucken Sie die Zeichenfolge Ausgabe in debug.log

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

So drucken Sie die Array-Ausgabe 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));
Prinz Patel
quelle
10

Wenn Sie den Standard-Logger, aber eine benutzerdefinierte Datei für die Protokollierung (oder eine andere benutzerdefinierte Logik) verwenden möchten, müssen Sie den benutzerdefinierten Logger-Handler verwenden:

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

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

Fügen Sie es dann als Handler irgendwo in Ihrem Code hinzu:

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

Ein Schritt zurück in die Praxis IMO

Petar Dzhambazov
quelle
+1 Nützliche Informationen, danke! Allerdings ist es nicht klar , wie Sie nutzen diesen Logger Zusammenhang mit dem PSR-3 - Autoloader - Schnittstelle - also wenn Sie der Anmeldung mit $this->logger->info($message, $level);- wie sagt man „meinen Kontext verwenden“?
Alan Storm
2
Nun, die Sache ist, dass alle Handler, die Monolog zur Verfügung stehen, geloopt werden und zuerst der Level des Records (DEBUG, INFO etc.) verwendet wird. Die einzige Möglichkeit, mit der ich absolut sicher sein kann, dass Ihr Handler verwendet wird, besteht darin, ihn vor der Verwendung zu schieben, sodass er ganz oben auf dem Stapel steht und an erster Stelle in der Schleife steht. Eine andere Möglichkeit wäre, es einfach als Handler festzulegen und alle anderen zu entfernen, aber das wäre nicht sehr freundlich.
Petar Dzhambazov
Wenn Sie versuchen , in der 2.0.0 GA zusätzliche Handler einzuführen, oder arbeiten mit den Handler in di.xml Angabe können Sie sich dieses Problems bewusst sein wollen github.com/magento/magento2/issues/2529 ich in dieser Ausgabe lief versuchen einen benutzerdefinierten Logger mit einem benutzerdefinierten Logfile-Handle und einen benutzerdefinierten Handler, der einige Einträge in eine Datenbanktabelle schreibt.
mttjohnson
9

Auf einfache Weise wird die Anmeldedatei system.loggespeichert , wenn Sie keine Abhängigkeitsinjektion erstellen möchten oder wenn Sie den folgenden Code verwenden

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

Das ist alles..

Himanshu
quelle
5

Nein, es gibt kein direktes Äquivalent. Es ist jetzt ein bisschen kompliziert.

Siehe: Protokollieren in eine benutzerdefinierte Datei in Magento 2

Ryan Hoerr
quelle
1
+1, danke! Bei anderen Antworten klingt es jedoch so, als gäbe es möglicherweise nur einen einzigen Logger, und das Erweitern / Erstellen eines Handle-Ansatzes ist nicht mehr erforderlich. Wissen Sie, ob das stimmt?
Alan Storm
4

Fügen Sie die Klasse psr logger mit use in Ihre Datei ein und rufen Sie dann addDebug()method auf. Dadurch wird die Protokollmeldung in der var/log/debug.logDatei gedruckt

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
quelle
2
Sie sollten AddDebug nicht verwenden, da dies nicht mit PSR-Loggern kompatibel ist. Verwenden Sie stattdessen einfach Debug.
Maciej Paprocki
4

AKTUALISIERT: 19/08/2019

Wenn Sie nach einem eleganten benutzerdefinierten Protokollhandler suchen, empfehle ich die Verwendung von virtuellen Typen (für die kein PHP-Code hinzugefügt werden muss).

Inspiriert von der Antwort von Petar Dzhambazov und Halk , meine Damen und Herren, habe ich Ihnen immer einen besseren und kürzeren Weg vorgestellt, anstatt den benutzerdefinierten Protokollcode zu duplizieren.

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>

VERWENDUNGSZWECK

Vendor \ Something \ Model \ 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>

Das ist alles, keine zusätzlichen PHP-Dateien oder -Linien - nutzen Sie die Vorteile von Magento 2: Virtual Types !!!

Hoffe das hilft ;)

Toan Nguyen
quelle
3
Implementiert dieser Code PSI? (Political Statements Injection): P
7ochem
1
@ 7ochem Oh ja, es ist: v
Toan Nguyen
2

Es gibt ein Update für Logger in 2.2. Sie können den Logger für den Produktionsmodus aktivieren, indem Sie SQL ausführen:

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

Dann können Sie das \Psr\Log\LoggerInterface Protokoll wie oben beschrieben ausdrucken:

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
quelle
Danke, und Sie können dies auch anstelle von QUERY SQL verwenden: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. Inject $loggerclass in constructor \Psr\Log\LoggerInterface $logger
    Dies wird durch die Übergabe von $ logger als Argument erreicht.

  2. $loggerIm Konstruktor initialisieren

    $this->logger = $logger
  3. Verwenden Sie in der Funktion innerhalb der Klasse, die Sie protokollieren möchten, die folgende Zeile

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

Wenn Sie es in Ihrer einzelnen Klasse mit einer benutzerdefinierten Protokolldatei benötigen:

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
quelle
0

Platzieren Sie den PSR-Logger-Code in Ihrem Konstruktor:

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

dann kannst du in deiner funktion verwenden wie:

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

quelle