Magento 2: Zastąpienie metody Mag :: log?


105

W Magento 1, jeśli chcesz wysłać wiadomość do dzienników, użyjesz metody statycznej dla Mageklasy globalnej .

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

Czy istnieje odpowiednik Magento 2? Mam google pośrednictwem serwisu docs dev i nie coś oczywistego, że wyskakuje widział. Jest ten artykuł o Inchoo , ale pochodzi z prawie roku temu i od tego czasu wiele się zmieniło.

Jako programista modułu Magento 2, jeśli chcę zastąpić kod podobny do następującego w Magento 1

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

Jakie minimum muszę zrobić?

Odpowiedzi:


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

Używasz debugowania, wyjątków i systemu PSR Logger na przykład:

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

9
+1 Dziękuję, jest to przydatny interfejs / klasa / typ, o którym warto wiedzieć - ale z odpowiedzi nie wynika jasno, gdzie będą rejestrowane informacje i jak (jeśli to możliwe) zmienić tę lokalizację.
Alan Storm,

Sprawdzasz Manager.php dla następnej klasy Magento \ Framework \ Event i dodajesz ten wiersz $ this-> logger-> debug ($ eventName); niż po odświeżeniu strony i sprawdzeniu pliku debug.txt otrzymujesz wszystkie oczywiste nazwy dla konkretnej strony.
Pratik,

2
Technicznie jest to „poprawny” sposób na utworzenie instancji loggera we własnych niestandardowych klasach - szczególnie jeśli zamierzasz go trzymać, a nie tylko szybki debugowanie. Istnieje jednak kilka klas podstawowych - w szczególności klasy Blok - które automatycznie tworzą instancję i przechowują właściwość _logger. Jeśli rozszerzysz jedną z tych podstawowych klas, nie musisz powtarzać logiki. Inne odpowiedzi opisują tworzenie programów obsługi, aby zdefiniować własny plik dziennika, ale domyślnymi dziennikami są zawsze /var/log/system.log lub /var/log/debug.log. Uważam, że konkretna funkcja rejestrowania określa, która jest używana.
Jeremy Rimpo,

7
Dla mnie poziom „debugowania” zaczął działać tylko wtedy, gdy włączyłem „Zaloguj się do pliku” w Konfiguracja> Zaawansowane> Deweloper> Debugowanie. Korzystanie 2.2
Omer Sabic

122

W magento2 możesz również pisać do dzienników, korzystając z Zendbiblioteki, jak poniżej:

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

Edytowane

Możesz także wydrukować obiekty i tablice PHP jak poniżej:

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

7
+1 Przydatne - czy wiesz, czy Zend logger automatycznie sformatuje tablice / obiekty PHP itp.?
Alan Storm,

1
@AlanStorm - Tak, możesz sprawdzić moją zaktualizowaną odpowiedź.!
Manashvi Birla,

2
@Manashvibirla: PHP objectsnie drukują ...
zed Blackbeard

1
@KeyurShah Rozwiązanie zostało dostarczone z myślą o Ubuntu, ponieważ używałem Ubuntu.! dzięki za opinie
Manashvi Birla

3
Kilka z tych odpowiedzi ma swoje miejsce i zastosowanie. Oczywiście to rozwiązanie wymaga prawie tyle samo kodu, co użycie DI do utworzenia standardowego programu rejestrującego - ale jest to prosta lista rozwijana, która pozwala ustawić własny plik dziennika. Czasami przeszukiwanie standardowych plików dziennika - które są często zagracone - jest dość denerwujące, aby znaleźć własne dzienniki. Jest to więc dobre „szybkie” rozwiązanie tego problemu.
Jeremy Rimpo,

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

6
+1 Dziękuję, jest to przydatny interfejs / klasa / typ, o którym warto wiedzieć - ale z odpowiedzi nie wynika jasno, gdzie będą rejestrowane informacje i jak (jeśli to możliwe) zmienić tę lokalizację.
Alan Storm,

1
To poprawna odpowiedź.
medyna

4
Nie radziłbym używać bezpośrednio menedżera obiektów ObjectManager. Zamiast tego użyj DI
7ochem

12
Chociaż zgadzam się z @ 7ochem, jeśli tworzysz funkcję trwałego logowania, może być konieczne od czasu do czasu wstrzyknięcie tymczasowego logowania do podstawowych (lub stron trzecich) klas w celu debugowania problemów. Przejście przez żmudny proces dodawania klasy Logger do konstruktora jest w tych przypadkach bezcelowo nadmiernie skomplikowane. W przypadku prostej, jednowierszowej funkcji debugowania jest to prawdopodobnie najlepsze rozwiązanie. Będziesz jednak musiał poradzić sobie z przeszukiwaniem domyślnych plików dziennika, aby znaleźć własne wyjście debugowania.
Jeremy Rimpo,

Należy również pamiętać, że istnieje kilka klas podstawowych - w szczególności klasy Blok - które mają właściwość _logger, do której można uzyskać dostęp bez tworzenia nowej kopii.
Jeremy Rimpo,

28

Tymczasowy dziennik wydruku z nowym plikiem

$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

Metoda fabryczna

Musisz wstrzyknąć klasę \ Psr \ Log \ LoggerInterface do konstruktora, aby wywołać obiekt rejestrujący

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

}

Lub bezpośrednio używasz tego kodu w pliku phtml:

Aby wydrukować ciąg Wyjście w pliku debug.log

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

Aby wydrukować dane wyjściowe z tablicy w pliku 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

Jeśli chcesz użyć domyślnego programu rejestrującego, ale niestandardowego pliku do logowania (lub innej niestandardowej logiki), musisz użyć niestandardowej procedury obsługi programu rejestrującego:

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

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

Następnie dodaj go jako moduł obsługi do kodu:

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

Cofnij się wygodnie IMO


+1 Przydatne informacje, dziękuję! Jednak nie jest jasne, w jaki sposób używasz tego kontekstu rejestratora z interfejsem autoloadera PSR-3 - tzn. Jeśli logujesz się $this->logger->info($message, $level);- jak mówisz „użyj mojego kontekstu”?
Alan Storm,

2
Chodzi o to, że wszystkie programy obsługi dostępne dla Monologa są zapętlone i najpierw wykorzystywany jest poziom obsługi rekordów (DEBUG, INFO itp.). Tak więc jedyny sposób, w jaki widzę, aby być absolutnie pewnym, że twój moduł obsługi jest używany, to pchanie go, zanim go potrzebujesz, więc jest na górze stosu i jest na pierwszym miejscu w pętli. Innym sposobem byłoby po prostu ustawienie go jako modułu obsługi, usunięcie wszystkich innych, ale nie będzie to zbyt przyjazne.
Petar Dzhambazov

Jeśli próbujesz wprowadzić dodatkowe moduły obsługi w GA 2.0.0 lub pracujesz nad określeniem modułów obsługi w pliku di.xml, możesz chcieć wiedzieć o tym problemie github.com/magento/magento2/issues/2529 Natknąłem się na ten problem, próbując aby uzyskać niestandardowy program rejestrujący, który ma niestandardowy uchwyt pliku dziennika oraz niestandardowy moduł obsługi, który zapisuje niektóre wpisy w tabeli bazy danych.
mttjohnson,

9

W prosty sposób, jeśli nie chcesz tworzyć wstrzykiwania zależności lub cokolwiek innego użyć poniżej kodu, zapisze system.logplik dziennika

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

To wszystko..



4

Dołącz klasę psr logger do swojego pliku, używając metody use, a następnie call addDebug(). Spowoduje to wydrukowanie komunikatu dziennika w var/log/debug.logpliku

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
nie powinieneś dodgeDebug, ponieważ nie jest kompatybilny z logrrem psr. zamiast tego użyj po prostu debugowania.
Maciej Paprocki

4

AKTUALIZACJA: 19/08/2019

Jeśli szukasz eleganckiego niestandardowego modułu obsługi dzienników, zalecamy użycie typów wirtualnych (które nie wymagają dodawania kodu PHP)

Zainspirowany odpowiedzią Petara Dzhambazova i halk , panie i panowie, przedstawiłem wam lepszą i krótszą drogę zamiast zduplikowanego niestandardowego kodu dziennika.

StackOverflow \ Przykład \ 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>

STOSOWANIE

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 \ Przykład \ 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>

To wszystko, bez dodatkowych plików PHP lub linii - skorzystaj z zalet Magento 2: Typy wirtualne !!!

Mam nadzieję że to pomoże ;)


3
Czy ten kod implementuje PSI? (Zastrzyki z oświadczeń politycznych): P
7ochem

1
@ 7ochem O tak, to jest: v
Toan Nguyen

2

Jest jedna aktualizacja dla rejestratora w wersji 2.2. Możesz włączyć rejestrator w trybie produkcyjnym, uruchamiając SQL:

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

Następnie możesz użyć \Psr\Log\LoggerInterface dziennika wydruku tak jak powyższe odpowiedzi:

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

dzięki, możesz też użyć tego zamiast 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. Inject $loggerclass in constructor \Psr\Log\LoggerInterface $logger
    Osiąga się to poprzez przekazanie $ logger jako argumentu.

  2. Zainicjuj $loggerw konstruktorze

    $this->logger = $logger
  3. W funkcji w klasie, w której chcesz się zalogować, użyj poniższego wiersza

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

1

Jeśli potrzebujesz go w ramach jednej klasy z niestandardowym plikiem dziennika:

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

Umieść kod rejestratora PSR w swoim konstruktorze:

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

możesz użyć w swojej funkcji, takich jak:

$this->logger->info($message);
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.