Cursos Magento

Gravando arquivo de log personalizado no Magento 2

,

Atualizado em 22 de agosto de 2022

Este é o segundo e último artigo da série sobre Logs no Magento 2. No primeiro artigo, vimos como usar o sistema de log no Magento 2 e como ele funciona.

Neste artigo veremos como gerar arquivos personalizados e estender a classe de log do Magento 2. Caso esteja interessado em Magento 1, veja este outro artigo sobre como gravar logs no Magento 1.

Conhecendo os handlers de log nativos do Magento 2

Como vimos no artigo anterior, o Magento  faz uso da conhecida classe Monolog, e implementa 3 handlers nativos:

  • System – \Magento\Framework\Logger\Handler\System
  • Exception – \Magento\Framework\Logger\Handler\Exception
  • Debug – \Magento\Framework\Logger\Handler\Debug

Todos eles estendem a classe \Magento\Framework\Logger\Handler\Base, que então estende a classe \Monolog\Handler\StreamHandler – usada para gravar qualquer tipo de log em um formato do tipo stream (ex: arquivo local, arquivo remoto, php://stderr, etc).

Cada classe define um arquivo de saída e um nível de criticidade do log que ela representa, seguindo os padrões da RFC que vimos no artigo anterior.

<?php
namespace Magento\Framework\Logger\Handler;

use Monolog\Logger;

class Debug extends Base
{
    /**
     * @var string
     */
    protected $fileName = '/var/log/debug.log';

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

O Base Handler

A classe Base é a responsável por criar o arquivo especificado em $fileName, e também por gravar as informações nele e tratar o nome do arquivo antes de criá-lo.

Veja só como ela é definida no di.xml do módulo base do Magento:

// ...
<type name="Magento\Framework\Logger\Monolog">
        <arguments>
            <argument name="name" xsi:type="string">main</argument>
            <argument name="handlers"  xsi:type="array">
                <item name="system" xsi:type="object">Magento\Framework\Logger\Handler\System</item>
                <item name="debug" xsi:type="object">Magento\Framework\Logger\Handler\Debug</item>
            </argument>
        </arguments>
    </type>
// ...

É lá que são definidos os handlers disponíveis – e eventualmente onde podemos adicionar um novo handler.

Veja que o \Magento\Framework\Logger\Handler\Exception não está listado. Ele é chamado pelo \Magento\Framework\Logger\Handler\System.

Adicionando um Handler de log no Magento 2

Você pode adicionar um Handler para fazer algo específico com as informações de log de um determinado tipo.  No exemplo abaixo, criaremos uma classe para salvar as informações de log do Magento 2 em um arquivo de log personalizado – no caso, magenteiro.log.

Para isso, nós precisamos:

  1. Criar uma classe Handler, que estende a classe Base (\Magento\Framework\Logger\Handler\Base)
  2. Definir no __construct desta classe, qual $filesystem será usado pra gravar as informações recebidas. Este é o único parâmetro obrigatório no __construct da classe Base.
  3. Ainda na classe Handler, definir as propriedades protegidas $fileName e $loggerType com o nome do arquivo que queremos salvar e qual o tipo de criticidade que nosso handler vai tratar.
  4. Criar uma classe de log que estenda \Monolog\Logger para podermos usar depois
  5. Injetar o nome do nosso logger ($name) e o handler ($handlers) que criamos no construtor dela. Veja \Monolog\Logger::__construct.

Vamos lá?

namespace Magenteiro\LogExample\Logger;

use Magento\Framework\Logger\Handler\Base;
use Monolog\Logger;

class Handler extends Base
{
    protected $fileName = '/var/log/magenteiro.log';
    protected $loggerType = Logger::ALERT;
}
<type name="Magenteiro\LogExample\Logger\Handler">
    <arguments>
        <argument name="filesystem" xsi:type="object">Magento\Framework\Filesystem\Driver\File</argument>
    </arguments>
</type>
namespace Magenteiro\LogExample\Logger;

class Logger extends \Monolog\Logger
{

}
<type name="Magenteiro\LogExample\Logger\Logger">
    <arguments>
        <argument name="name" xsi:type="string">magenteiroLogger</argument>
        <argument name="handlers" xsi:type="array">
            <item name="system" xsi:type="object">Magenteiro\LogExample\Logger\Handler</item>
        </argument>
    </arguments>
</type>

Note que no passo 2 e no passo 5 usamos Dependency Injection para informar os parâmetros ao construtor das classes.

Sendo assim, ao importarmos nossa classe e chamarmos o método alert(), o conteúdo será gravado em /pastamagento/var/log/magenteiro.log.

Veja o exemplo:

namespace Magenteiro\LogExample\Console\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class TestCustom extends Command
{
    public function __construct(\Magenteiro\LogExample\Logger\Logger $logger)
    {
        $this->logger = $logger;
        parent::__construct();
    }

    /**
     * {@inheritdoc}v
     */
    protected function configure()
    {
        $this->setName('magenteiro:logCustomExample')
            ->setDescription('Usando logs customizados no Magento. Este será salvo em var/log/magenteiro.log');
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $output->writeln('Agora usando Magenteiro\Logger');
        $this->logger->alert('1: Alert: action must be taken immediately');

    }
}
Exemplo do resultado do log gravado no Magento 2
Exemplo do resultado gravado em var/log/magenteiro.log

Uma outra forma de gravar logs no Magento 2

Como vimos, acima temos a forma clássica e elegante de se fazer um log personalizado no Magento 2.

No entanto, existe uma forma ainda mais direta de fazê-lo (e menos elegante). Podemos ter resultados semelhantes usando a classe\Zend\Log\Logger.

Ficaria assim:

$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/magenteiro.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);

$logger->info('Isso gravado no /var/log/magenteiro.log');

Desta forma, temos todos os métodos de debug (info, debug, warning, etc) sem muito código.

No entanto, podemos dizer que este é o jeito “feio” de fazer. Como sabemos, devemos injetar nossas dependências nas nossas classes e métodos.

Neste caso precisaríamos de 2 classes: \Zend\Log\Writer\Stream e \Zend\Log\Logger, sendo que na primeira delas informamos o caminho completo de onde queremos salvar nosso log.

O problema é que a primeira delas exige o caminho completo do arquivo que queremos salvar. Isso nos remete a ter que criar mais injeções de XML, eventualmente criar um virtualType, outras classes, etc. Sendo assim, é melhor ficar com o exemplo clássico, não é mesmo?

Módulo de exemplo (Magento 2 logs)

Digite seu nome e e-mail abaixo para obter o módulo com os exemplos exibidos nesta série.

Nele você encontrará:

  • bin/magento magenteiro:logExample – com exemplo de uso dos logs comuns no Magento 2
  • bin/magento magenteiro:logCustomExample – com exemplo do nosso log customizado
  • bin/magento magenteiro:logZendLogExample – com exemplo “ruim” de uso da classe Zend\Log direto no método, sem injeção de dependência
Últimos posts por Ricardo Martins (exibir todos)
Comentários

Deixe seu comentário

[fbcomments url="https://www.magenteiro.com/blog/magento-2/log-personalizado-no-magento-2/"]