Magento 2: Substituição do método Mage :: log?

105

No Magento 1, se você quisesse enviar uma mensagem para os logs, usaria um método estático na Mageclasse global .

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

Existe um equivalente no Magento 2? Eu pesquisei através do site docs dev e não vi nada óbvio que saia. Há este artigo do Inchoo , mas é de quase um ano atrás e muita coisa mudou desde então.

Como desenvolvedor do módulo Magento 2, se eu quiser substituir código como o seguinte no Magento 1

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

Qual é o mínimo necessário que preciso fazer?

Alan Storm
fonte

Respostas:

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

Você usa o sistema de depuração, exceção, para o PSR Logger, por exemplo:

$this->logger->info($message);
$this->logger->debug($message);
Pratik
fonte
9
+1 Obrigado, é uma interface / classe / tipo útil para se conhecer - mas não está claro em sua resposta onde as informações serão registradas e como (se possível) alterar esse local.
Alan Storm
Você verifica Manager.php para a seguinte classe Magento \ Framework \ Event e adiciona esta linha $ this-> logger-> debug ($ eventName); após a página de atualização e verifique o arquivo debug.txt, você obtém todo o nome de evant para uma página específica.
Pratik
2
Tecnicamente, esta é a maneira 'correta' de instanciar um criador de logs em suas próprias classes personalizadas - especialmente se você pretende mantê-lo por perto, em vez de apenas uma depuração rápida. No entanto, existem várias classes principais - particularmente as classes Block - que instanciam e armazenam automaticamente uma propriedade _logger. Se você estender uma dessas classes principais, não será necessário repetir a lógica. Outras respostas buscam criar manipuladores para definir seu próprio arquivo de log, mas os logs padrão são sempre /var/log/system.log ou /var/log/debug.log. Eu acredito que a função específica de log determina qual é usado.
Jeremy Rimpo
7
Para mim, o nível de "depuração" começou a funcionar apenas quando eu habilitei "Log to file" em Configuração> Avançado> Desenvolvedor> Depuração. Usando 2.2
Omer Sabic
122

No magento2, você também pode escrever nos logs usando a Zendbiblioteca como abaixo:

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

Editado

Você também pode imprimir objetos e matrizes PHP como abaixo:

$logger->info(print_r($yourArray, true));
Manashvi Birla
fonte
7
+1 Útil - você sabe se o Zend logger formatará automaticamente matrizes / objetos PHP etc?
Alan Storm
1
@ AlanStorm - Sim, você pode, verifique minha resposta atualizada.!
Manashvi Birla
2
@Manashvibirla: PHP objectsnão são impressas ...
zed Blackbeard
3
Várias dessas respostas têm seu lugar e uso. Obviamente, esta solução requer quase tanto código quanto o uso do DI para instanciar o criador de logs padrão - mas é um drop-in simples no local que permite definir seu próprio arquivo de log. Às vezes, é um pouco chato pesquisar nos arquivos de log padrão - que tendem a ficar desordenados - para encontrar seus próprios logs. Portanto, esta é uma boa solução 'rápida' para isso.
Jeremy Rimpo
2
É o rei do embaressing quantas vezes eu venho aqui para copiar e usar isso ... <3
Lez
56
\Magento\Framework\App\ObjectManager::getInstance()
    ->get(\Psr\Log\LoggerInterface::class)->debug('message');
Mage2.PRO
fonte
6
+1 Obrigado, é uma interface / classe / tipo útil para se conhecer - mas não está claro em sua resposta onde as informações serão registradas e como (se possível) alterar esse local.
Alan Storm
1
Essa é a resposta correta.
Medina
4
Eu não recomendaria usar o ObjectManager diretamente. Em vez disso, use DI
7ochem
12
Embora eu concorde com o @ 7ochem se você estiver criando uma função de log permanente, pode ser necessário injetar log temporário nas classes principais (ou de terceiros) de tempos em tempos para solucionar problemas de depuração. Passar pelo árduo processo de adicionar uma classe Logger ao construtor é extremamente complicado nesses casos. Para uma função simples de depuração de linha única, essa é provavelmente a melhor solução. No entanto, você terá que lidar com a pesquisa nos arquivos de log padrão para encontrar sua própria saída de depuração.
Jeremy Rimpo
Lembre-se também de que existem várias classes principais - particularmente as classes Block - que possuem uma propriedade _logger que você pode acessar sem instanciar uma nova cópia.
Jeremy Rimpo
28

Registro de impressão temporário com novo arquivo

$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étodo de fábrica

Você precisa injetar a classe \ Psr \ Log \ LoggerInterface no construtor para chamar o objeto de 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 você usa diretamente esse código no arquivo phtml:

Para imprimir a string Saída em debug.log

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

Para imprimir a saída da matriz no 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
fonte
10

Se você deseja usar o criador de logs padrão, mas o arquivo personalizado para criação de log (ou outra lógica customizada), é necessário usar o manipulador de criador de logs personalizado:

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

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

Em seguida, adicione-o como manipulador em algum lugar do seu código:

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

Um passo atrás na conveniência IMO

Petar Dzhambazov
fonte
+1 Informações úteis, obrigado! No entanto, não está claro como você usa esse contexto do criador de logs com a interface do carregador automático PSR-3 - ou seja, se você está efetuando login $this->logger->info($message, $level);- como você diz "usar meu contexto"?
Alan Storm
2
Bem, o fato é que todos os manipuladores disponíveis para o Monolog são executados em loop e primeiro que podem lidar com o nível de registro (DEBUG, INFO etc.) é usado. Portanto, a única maneira que eu tenho certeza absoluta de que seu manipulador é usado é empurrá-lo antes que você precise, para que fique no topo da pilha e fique em primeiro lugar no loop. Outra maneira seria simplesmente configurá-lo como manipulador, removendo todos os outros, mas isso não será uma coisa muito amigável.
Petar Dzhambazov
Se você tentar introduzir manipuladores adicionais no GA 2.0.0, ou trabalhar com a especificação dos manipuladores no di.xml, você pode estar ciente desse problema github.com/magento/magento2/issues/2529 Corri para esse problema tentando para obter que um criador de logs personalizado tenha um identificador de arquivo de log personalizado e um manipulador personalizado que grave algumas entradas em uma tabela do banco de dados.
precisa saber é o seguinte
9

De uma maneira simples, se você não deseja criar injeção de dependência ou qualquer outra coisa que use abaixo do código, ele armazenará o system.logarquivo de logon

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

Isso é tudo..

Himanshu
fonte
5

Não, não há equivalente direto. Está um pouco complicado agora.

Consulte: Registrando em um arquivo personalizado no Magento 2

Ryan Hoerr
fonte
1
+1, obrigado! No entanto - outras respostas fazem parecer que pode haver um único criador de logs e a abordagem de extensão / criação de identificador não é mais necessária. Você sabe se isso é verdade?
Alan Storm
4

Inclua a classe psr logger em seu arquivo usando use e chame o addDebug()método Isso imprimirá a mensagem de log no var/log/debug.logarquivo

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
fonte
2
você não deve adicionar addDebug, pois isso não é compatível com o psr logger. use apenas depuração.
Maciej Paprocki
4

ATUALIZADO: 19/08/2019

Se você estiver procurando um manipulador de log personalizado e elegante, recomendo que você use Tipos Virtuais (que não precisam adicionar nenhum código PHP)

Inspirados na resposta de Petar Dzhambazov e halk , senhoras e senhores, apresentei uma maneira melhor e mais curta, em vez de duplicar o código de log personalizado o tempo todo.

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>

USO

Fornecedor \ Algo \ Modelo \ 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>

Isso é tudo, sem arquivos ou linhas PHP extras - use as vantagens do Magento 2: Tipos Virtuais !!!

Espero que isto ajude ;)

Toan Nguyen
fonte
3
Esse código está implementando PSI? (Injeção de declarações políticas): P
7ochem
1
@ 7ochem Oh sim, é: v
Toan Nguyen
2

Há uma atualização para o logger em 2.2. Você pode ativar o criador de logs para o modo de produção executando o SQL:

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

Em seguida, você pode usar o \Psr\Log\LoggerInterface log de impressão como as respostas acima:

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
fonte
obrigado, e você também pode usar isso em vez 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. Injetar $loggerclasse no construtor \Psr\Log\LoggerInterface $logger
    Isso é conseguido passando $ logger como argumento.

  2. Inicializar $loggerno construtor

    $this->logger = $logger
  3. Na função da classe que você deseja registrar, use a linha abaixo

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

Se você precisar em sua classe única com arquivo de log personalizado:

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

Coloque o código do logger PSR em seu construtor:

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

então você pode usar em sua função como:

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

fonte