Magento 2: Penggantian untuk metode Mage :: log?


105

Di Magento 1, jika Anda ingin mengirim pesan ke log, Anda akan menggunakan metode statis di Magekelas global .

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

Apakah ada yang setara di Magento 2? Saya sudah mencari Google melalui situs docs dan belum melihat sesuatu yang jelas yang muncul. Ada artikel Inchoo ini, tapi sudah hampir setahun yang lalu dan sudah banyak yang berubah sejak saat itu.

Sebagai pengembang modul Magento 2, jika saya ingin mengganti kode seperti berikut ini di Magento 1

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

Apa minimum yang harus saya lakukan?

Jawaban:


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

Anda menggunakan debug, pengecualian, sistem untuk Pencatat PSR misalnya:

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

9
+1 Terima kasih, itu antarmuka / kelas / tipe yang berguna untuk diketahui - tetapi tidak jelas dari jawaban Anda di mana informasi akan dicatat dan bagaimana (jika mungkin) mengubah lokasi itu.
Alan Storm

Anda memeriksa Manager.php untuk mengikuti kelas Magento \ Framework \ Event dan menambahkan baris ini $ this-> logger-> debug ($ eventName); daripada setelah refresh halaman dan periksa file debug.txt Anda mendapatkan semua nama yang sama untuk halaman tertentu.
Pratik

2
Secara teknis, ini adalah cara yang 'benar' untuk membuat instance logger di kelas kustom Anda sendiri - terutama jika Anda ingin menyimpannya di sekitar daripada hanya beberapa debug cepat. Namun, ada beberapa kelas inti - terutama kelas Blok - yang secara otomatis membuat dan menyimpan properti _logger. Jika Anda memperpanjang salah satu dari kelas inti ini maka tidak perlu mengulang logika. Jawaban lain menggali pembuatan handler untuk mendefinisikan file log Anda sendiri, tetapi log default selalu /var/log/system.log atau /var/log/debug.log. Saya percaya fungsi logging spesifik menentukan mana yang digunakan.
Jeremy Rimpo

7
Bagi saya, level "debug" mulai berfungsi hanya ketika saya mengaktifkan "Log to file" di Konfigurasi> Lanjutan> Pengembang> Debug. Menggunakan 2.2
Omer Sabic

122

Di magento2, Anda juga dapat menulis ke log menggunakan Zendperpustakaan seperti di bawah ini:

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

Diedit

Anda juga dapat mencetak objek dan array PHP seperti di bawah ini:

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

7
+1 Berguna - tahukah Anda jika Zend logger akan secara otomatis memformat array / objek PHP, dll?
Alan Storm

1
@AlanStorm - Ya Anda bisa, periksa jawaban saya yang diperbarui.!
Manashvi Birla

2
@Manashvibirla: PHP objectstidak mencetak ...
zed Blackbeard

3
Beberapa jawaban ini memiliki tempat dan penggunaannya. Jelas solusi ini membutuhkan kode hampir sebanyak menggunakan DI untuk membuat instance logger standar - tetapi ini adalah drop-in in-place sederhana yang memungkinkan Anda mengatur file log Anda sendiri. Kadang-kadang agak menjengkelkan untuk mencari melalui file log standar - yang cenderung berantakan - untuk menemukan log Anda sendiri. Jadi ini adalah solusi 'cepat' yang bagus untuk itu.
Jeremy Rimpo

2
Ini adalah raja yang tidak memihak seberapa sering saya datang ke sini untuk menyalin dan menggunakan ini ... <3
Lez

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

6
+1 Terima kasih, itu antarmuka / kelas / tipe yang berguna untuk diketahui - tetapi tidak jelas dari jawaban Anda di mana informasi akan dicatat dan bagaimana (jika mungkin) mengubah lokasi itu.
Alan Storm

1
Itu jawaban yang benar.
medina

4
Saya tidak akan menyarankan untuk menggunakan ObjectManager secara langsung. Gunakan DI sebagai gantinya
7ochem

12
Meskipun saya setuju dengan @ 7ochem jika Anda membuat fungsi logging permanen, mungkin perlu menyuntikkan logging sementara ke kelas inti (atau pihak ketiga) dari waktu ke waktu untuk men-debug masalah. Melewati proses yang sulit menambahkan kelas Logger ke konstruktor adalah hal yang terlalu rumit dalam kasus ini. Untuk fungsi debug satu baris yang sederhana, ini mungkin solusi terbaik. Namun, Anda harus berurusan dengan pencarian melalui file log default untuk menemukan hasil debug Anda sendiri.
Jeremy Rimpo

Juga perlu diingat bahwa ada beberapa kelas inti - terutama kelas Blok - yang memiliki properti _logger yang dapat Anda akses tanpa membuat salinan baru.
Jeremy Rimpo

28

Log cetak sementara dengan file baru

$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

Metode Pabrik

Anda perlu menyuntikkan kelas \ Psr \ Log \ LoggerInterface ke konstruktor untuk memanggil objek 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));

}

Atau Anda langsung menggunakan kode ini dalam file phtml:

Untuk mencetak string Output di debug.log

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

Untuk mencetak Output array di 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

Jika Anda ingin menggunakan logger default tetapi file kustom untuk logging (atau logika kustom lainnya), Anda perlu menggunakan handler logger kustom:

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

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

Kemudian tambahkan itu sebagai penangan di suatu tempat di dalam kode Anda:

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

Langkah mundur dalam kenyamanan IMO


+1 Informasi yang berguna, terima kasih! Namun, tidak jelas bagaimana Anda menggunakan konteks logger ini dengan antarmuka autoloader PSR-3 - yaitu jika Anda masuk dengan $this->logger->info($message, $level);- bagaimana Anda mengatakan "gunakan konteks saya"?
Alan Storm

2
Yah masalahnya adalah bahwa semua penangan yang tersedia untuk Monolog dilingkarkan dan pertama yang dapat menangani tingkat catatan (DEBUG, INFO dll) digunakan. Jadi satu-satunya cara saya melihat untuk benar-benar yakin bahwa pawang Anda digunakan, adalah dengan mendorongnya sebelum Anda membutuhkannya, jadi itu ada di atas tumpukan dan berada di urutan pertama dalam loop. Cara lain adalah dengan hanya SET sebagai handler, menghapus semua yang lain, tetapi itu tidak akan sangat ramah untuk dilakukan.
Petar Dzhambazov

Jika Anda mencoba memperkenalkan penangan tambahan di 2.0.0 GA, atau bekerja dengan menentukan penangan di di.xml Anda mungkin ingin mengetahui masalah ini github.com/magento/magento2/issues/2529 Saya mengalami masalah ini mencoba untuk mendapatkan logger kustom untuk memiliki pegangan file log kustom, dan penangan kustom yang menulis beberapa entri ke tabel database.
mttjohnson

9

Dengan cara sederhana jika Anda tidak ingin membuat injeksi ketergantungan atau hal lain yang menggunakan kode di bawah ini akan menyimpan system.logfile login

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

Itu saja..


5

Tidak, tidak ada padanan langsung. Agak rumit sekarang.

Lihat: Masuk ke file khusus di Magento 2


1
+1, terima kasih! Namun - jawaban lain membuatnya terdengar seperti mungkin ada logger tunggal, dan memperluas / membuat pendekatan pegangan tidak lagi diperlukan. Apakah Anda tahu kalau itu benar?
Alan Storm

4

Sertakan kelas psr logger di file Anda menggunakan use dan kemudian panggil addDebug()metode. Ini akan mencetak pesan log dalam var/log/debug.logfile

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
Anda tidak boleh mengujikan addDebug karena itu tidak kompatibel dengan psr logger. gunakan hanya debug saja.
Maciej Paprocki

4

DIPERBARUI: 19/08/2019

Jika Anda mencari penangan log kustom yang elegan, saya sarankan Anda menggunakan Jenis Virtual (yang tidak perlu menambahkan kode PHP)

Terinspirasi dari jawaban Petar Dzhambazov dan halk , hadirin yang saya perkenalkan kepada Anda dengan cara yang lebih baik dan lebih pendek daripada selalu menggandakan kode log kustom.

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>

PEMAKAIAN

Vendor \ Sesuatu \ 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>

Itu saja, tidak ada file atau baris PHP tambahan - gunakan keunggulan Magento 2: Jenis Virtual !!!

Semoga ini membantu ;)


3
Apakah kode ini menerapkan PSI? (Injeksi Pernyataan Politik): P
7ochem

1
@ 7ochem Oh ya, itu: v
Toan Nguyen

2

Ada satu pembaruan untuk logger di 2.2. Anda dapat mengaktifkan logger untuk mode produksi dengan menjalankan SQL:

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

Kemudian Anda dapat menggunakan \Psr\Log\LoggerInterface untuk log cetak seperti jawaban di atas:

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

terima kasih, dan Anda juga dapat menggunakan ini alih-alih 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
    Ini dicapai dengan melewatkan $ logger sebagai argumen.

  2. Inisialisasi $loggerdalam konstruktor

    $this->logger = $logger
  3. Berfungsi dalam kelas yang ingin Anda masuki, gunakan baris di bawah ini

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

1

Jika Anda membutuhkannya dalam satu kelas dengan file log khusus:

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

Tempatkan kode logger PSR di konstruktor Anda:

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

maka Anda dapat menggunakan fungsi Anda seperti:

$this->logger->info($message);
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.