Magento 2: замена для метода Mage :: log?


105

В Magento 1, если вы хотите отправить сообщение в журналы, вы бы использовали статический метод в глобальном Mageклассе.

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

Есть ли эквивалент в Magento 2? Я просмотрел сайт разработчиков документации и не увидел ничего очевидного. Есть эта статья для Inchoo , но она написана почти год назад, и с тех пор многое изменилось.

Как разработчик модуля Magento 2, если я хочу заменить код, как показано ниже, в Magento 1

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

Какой минимум мне нужно сделать?

Ответы:


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

Вы используете отладку, исключение, систему для PSR Logger, например:

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

9
+1 Спасибо, это полезный интерфейс / класс / тип, о котором нужно знать - но из вашего ответа неясно, куда будет записываться информация и как (если возможно) изменить это местоположение.
Алан Шторм

Вы проверяете Manager.php на наличие следующего класса Magento \ Framework \ Event и добавляете эту строку $ this-> logger-> debug ($ eventName); чем после обновления страницы и проверки файла debug.txt вы получаете все имена для определенной страницы.
Pratik

2
Технически, это «правильный» способ создания логгера в ваших собственных пользовательских классах - особенно, если вы хотите сохранить его, а не просто быструю отладку. Однако существует несколько базовых классов, в частности, блочных классов, которые автоматически создают и сохраняют свойство _logger. Если вы расширяете один из этих базовых классов, нет необходимости повторять логику. Другие ответы копаются в создании обработчиков для определения вашего собственного файла журнала, но журналы по умолчанию всегда /var/log/system.log или /var/log/debug.log. Я считаю, что конкретная функция регистрации определяет, какая используется.
Джереми Римпо

7
Для меня уровень «отладки» начал работать, только когда я включил «Записать в файл» в «Конфигурация»> «Дополнительно»> «Разработчик»> «Отладка». Использование 2.2
Omer Sabic

122

В magento2 вы также можете записывать в журналы, используя Zendбиблиотеку, как показано ниже:

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

отредактированный

Вы также можете распечатать PHP-объекты и массивы, как показано ниже:

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

7
+1 Полезно - знаете ли вы, если Zend logger автоматически форматирует PHP массивы / объекты и т. Д.?
Алан Шторм

1
@AlanStorm - Да, вы можете проверить мой обновленный ответ.!
Манашви Бирла

2
@Manashvibirla: PHP objectsне печатаю ...
Зед Черная Борода

3
Некоторые из этих ответов имеют свое место и применение. Очевидно, что это решение требует почти столько же кода, сколько использует DI для создания экземпляра стандартного логгера, но это простое встроенное окно, которое позволяет вам установить свой собственный лог-файл. Иногда довольно раздражает поиск по стандартным файлам журналов, которые часто загромождаются, чтобы найти ваши собственные журналы. Так что это хорошее «быстрое» решение для этого.
Джереми Римпо

2
Это король смущаться, как часто я прихожу сюда, чтобы скопировать и использовать это ... <3
Лез

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

6
+1 Спасибо, это полезный интерфейс / класс / тип, о котором нужно знать - но из вашего ответа неясно, куда будет записываться информация и как (если возможно) изменить это местоположение.
Алан Шторм

1
Это правильный ответ.
Медина

4
Я бы не советовал использовать ObjectManager напрямую. Вместо этого используйте DI
7ochem

12
Хотя я согласен с @ 7ochem, если вы создаете постоянную функцию ведения журнала, может потребоваться время от времени внедрять временную регистрацию в базовые (или сторонние) классы для устранения проблем. Выполнение трудного процесса добавления класса Logger в конструктор в этих случаях бессмысленно чрезмерно сложно. Для простой однострочной функции отладки это, вероятно, лучшее решение. Тем не менее, вам придется иметь дело с поиском в файлах журналов по умолчанию, чтобы найти свой собственный вывод отладочной информации.
Джереми Римпо

Также имейте в виду, что есть несколько базовых классов, в частности, блочных классов, которые имеют свойство _logger, к которому вы можете обращаться без создания новой копии.
Джереми Римпо

28

Временная печать журнала с новым файлом

$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

Заводской метод

Вам нужно вставить класс \ Psr \ Log \ LoggerInterface в конструктор для вызова объекта регистратора

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

}

Или вы напрямую используете этот код в файле phtml:

Вывести строку вывода в debug.log

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

Вывести массив вывода в 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

Если вы хотите использовать регистратор по умолчанию, но пользовательский файл для ведения журнала (или другую пользовательскую логику), вам нужно использовать собственный обработчик регистратора:

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

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

Затем добавьте его в качестве обработчика где-то в вашем коде:

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

Шаг назад в удобстве ИМО


+1 Полезная информация, спасибо! Однако, не ясно, как вы используете этот контекст регистратора с интерфейсом автозагрузчика PSR-3 - то есть, если вы входите в систему $this->logger->info($message, $level);- как вы говорите «использовать мой контекст»?
Алан Сторм

2
Дело в том, что все обработчики, которые доступны для Monolog, зациклены и в первую очередь используются для обработки уровня записи (DEBUG, INFO и т. Д.). Таким образом, единственный способ убедиться в том, что ваш обработчик используется, - это нажать его до того, как он вам понадобится, поэтому он находится на вершине стека и занимает первое место в цикле. Другим способом было бы просто установить его в качестве обработчика, удалив все остальные, но это не будет очень дружелюбным делом.
Петар Джамбазов

Если вы попытаетесь ввести дополнительные обработчики в 2.0.0 GA или будете работать с указанием обработчиков в di.xml, вы можете захотеть знать об этой проблеме github.com/magento/magento2/issues/2529 Я столкнулся с этой проблемой, пытаясь чтобы пользовательский регистратор имел собственный дескриптор файла журнала и собственный обработчик, который записывает некоторые записи в таблицу базы данных.
Mttjohnson

9

Проще говоря, если вы не хотите создавать инъекцию зависимостей или что-либо еще, используйте приведенный ниже код, он сохранит журнал в system.logфайле

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

Вот и все..


5

Нет, прямого эквивалента нет. Это немного сложно сейчас.

Смотрите: Вход в пользовательский файл в Magento 2


1
+1, спасибо! Тем не менее - другие ответы заставляют его звучать так, как будто может быть один регистратор, и подход «расширение / создание дескриптора» больше не нужен. Вы знаете, правда ли это?
Алан Шторм

4

Включите класс psr logger в ваш файл, используя use, а затем вызовите addDebug()метод. Это напечатает сообщение журнала в var/log/debug.logфайле

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
Вы не должны использовать addDebug, так как он не совместим с psr logger. используйте вместо этого просто отладку.
Мацей Папроцки

4

ОБНОВЛЕНО: 19/08/2019

Если вы ищете элегантный пользовательский обработчик журналов, я рекомендую вам использовать виртуальные типы (для этого не нужно добавлять код PHP)

Вдохновленный из ответа Петар Dzhambazov и Halk , дамы и господа , я представил вам лучше и более короткий путь вместо дублированный пользовательского кода журнала все время.

StackOverflow \ Пример \ и т.д. \ 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>

ИСПОЛЬЗОВАНИЕ

Производитель \ Что-то \ 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 \ Пример \ и т.д. \ фронтенд \ di.xml

<type name="Vendor\Something\Model\DonaldTrump">
    <arguments>
        <argument name="logger" xsi:type="object">StackOverflow\Example\Model\Logger\VirtualLogger</argument>
    </arguments>
</type>

Вот и все, никаких дополнительных файлов или строк PHP - используйте преимущества Magento 2: Виртуальные типы !!!

Надеюсь это поможет ;)


3
Этот код реализует PSI? (Инъекция политических заявлений): P
7ochem

1
@ 7очем О да, это так: v
Тоан Нгуен

2

В 2.2 есть одно обновление для логгера. Вы можете включить регистратор для производственного режима, запустив SQL:

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

Затем вы можете использовать \Psr\Log\LoggerInterface для печати журнала, как и выше ответы:

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

спасибо, и вы также можете использовать это вместо 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. Внедрить $loggerкласс в конструктор. \Psr\Log\LoggerInterface $logger
    Это достигается передачей $ logger в качестве аргумента.

  2. Инициализировать $loggerв конструкторе

    $this->logger = $logger
  3. В функции внутри класса, который вы хотите войти, используйте строку ниже

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

1

Если вам это нужно в вашем отдельном классе с пользовательским файлом журнала:

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

Поместите код регистратора PSR в свой конструктор:

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

тогда вы можете использовать в своей функции, как:

$this->logger->info($message);
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.