Magento 2: การเปลี่ยนสำหรับ Mage :: log method?


105

ในวีโอไอพี 1 ถ้าคุณต้องการที่จะส่งข้อความไปยังบันทึกคุณจะใช้วิธีการแบบคงที่ในระดับโลกMageระดับ

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

Magento 2 มีความเท่าเทียมกันหรือไม่? ฉันไปที่ไซต์ dev docs แล้วและไม่เห็นสิ่งใดที่โผล่ออกมา มีบทความ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;
}

คุณใช้ debug, exception, ระบบสำหรับ PSR Logger เช่น:

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

9
+1 ขอบคุณนั่นเป็นอินเทอร์เฟซ / คลาส / ประเภทที่มีประโยชน์ที่ควรทราบ - แต่มันไม่ชัดเจนจากคำตอบของคุณว่าข้อมูลจะถูกบันทึกไว้อย่างไรและจะเปลี่ยนตำแหน่งอย่างไร (ถ้าเป็นไปได้)
Alan Storm

คุณตรวจสอบ Manager.php สำหรับคลาส Magento \ Framework \ Event ต่อไปนี้และเพิ่มบรรทัดนี้ $ this-> logger-> debug ($ eventName); กว่าหลังจากรีเฟรชหน้าและตรวจสอบไฟล์ debug.txt คุณจะได้รับชื่อ evant ทั้งหมดสำหรับหน้าเฉพาะ
Pratik

2
ในทางเทคนิคนี่เป็นวิธีที่ 'ถูกต้อง' ในการสร้างอินสแตนซ์ของคนตัดไม้ในคลาสที่คุณกำหนดเองโดยเฉพาะอย่างยิ่งถ้าคุณตั้งใจจะเก็บมันไว้รอบตัว อย่างไรก็ตามมีคลาสหลักหลายคลาสโดยเฉพาะคลาสบล็อกซึ่งสร้างอินสแตนซ์และเก็บคุณสมบัติ _logger โดยอัตโนมัติ หากคุณขยายคลาสหลักเหล่านี้ไปหนึ่งคลาสคุณไม่จำเป็นต้องทำซ้ำตรรกะ คำตอบอื่น ๆ ขุดลงไปในการสร้างตัวจัดการเพื่อกำหนดไฟล์บันทึกของคุณเอง แต่บันทึกเริ่มต้นมักจะเป็น /var/log/system.log หรือ /var/log/debug.log ฉันเชื่อว่าฟังก์ชั่นการบันทึกที่เฉพาะเจาะจงจะกำหนดว่าจะใช้อะไร
Jeremy Rimpo

7
สำหรับฉันแล้วระดับ "debug" เริ่มทำงานเมื่อฉันเปิดใช้งาน "Log to file" ในการกำหนดค่า> ขั้นสูง> ผู้พัฒนา> ดีบัก ใช้ 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 อาร์เรย์ / วัตถุ ฯลฯ โดยอัตโนมัติหรือไม่
Alan Storm

1
@AlanStorm - ใช่คุณสามารถตรวจสอบคำตอบที่อัปเดตของฉัน!
Manashvi Birla

2
@Manashvibirla: PHP objectsไม่ได้พิมพ์ ...
zed Blackbeard

1
@KeyurShah วิธีการแก้ปัญหาได้รับการรักษาโดยคำนึงถึงอูบุนตูเป็นฉันใช้อูบุนตู! ขอบคุณสำหรับคำติชม
Manashvi Birla

3
หลายคำตอบเหล่านี้มีที่และการใช้งาน เห็นได้ชัดว่าโซลูชันนี้ต้องการรหัสเกือบเท่าการใช้ DI เพื่อสร้างอินสแตนซ์ของตัวบันทึกมาตรฐาน - แต่เป็นแบบดรอปอินแบบธรรมดาซึ่งช่วยให้คุณตั้งค่าไฟล์บันทึกของคุณเอง บางครั้งมันค่อนข้างน่ารำคาญในการค้นหาไฟล์บันทึกมาตรฐาน - ซึ่งมักจะทำให้รก - เพื่อค้นหาบันทึกของคุณเอง ดังนั้นนี่คือทางออก 'ด่วน' ที่ดีสำหรับสิ่งนั้น
Jeremy Rimpo

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

6
+1 ขอบคุณนั่นเป็นอินเทอร์เฟซ / คลาส / ประเภทที่มีประโยชน์ที่ควรทราบ - แต่มันไม่ชัดเจนจากคำตอบของคุณว่าข้อมูลจะถูกบันทึกไว้อย่างไรและจะเปลี่ยนตำแหน่งอย่างไร (ถ้าเป็นไปได้)
Alan Storm

1
นั่นคือคำตอบที่ถูกต้อง
เมดินา

4
ฉันจะไม่แนะนำให้ใช้ ObjectManager โดยตรง ใช้ DI แทน
7ochem

12
แม้ว่าฉันจะเห็นด้วยกับ @ 7ochem หากคุณกำลังสร้างฟังก์ชั่นการบันทึกอย่างถาวร แต่ก็จำเป็นต้องฉีดการบันทึกชั่วคราวลงในคลาสหลัก (หรือบุคคลที่สาม) เป็นครั้งคราวเพื่อแก้ไขข้อบกพร่อง การผ่านกระบวนการที่ยากลำบากในการเพิ่มคลาส Logger ให้กับ Constructor นั้นซับซ้อนเกินไปในกรณีเหล่านี้ สำหรับฟังก์ชั่นการดีบักแบบบรรทัดเดียวที่เรียบง่ายนี่น่าจะเป็นทางออกที่ดีที่สุด อย่างไรก็ตามคุณจะต้องจัดการกับการค้นหาผ่านไฟล์บันทึกเริ่มต้นเพื่อค้นหาผลลัพธ์การดีบักของคุณเอง
Jeremy Rimpo

โปรดทราบว่ามีคลาสหลักหลายคลาสโดยเฉพาะคลาสบล็อกที่มีคุณสมบัติ _logger ที่คุณสามารถเข้าถึงได้โดยไม่ต้องคัดลอกสำเนาใหม่ทันที
Jeremy Rimpo

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

ย้อนกลับไปอย่างสะดวกสบาย IMO


+1 ข้อมูลที่เป็นประโยชน์ขอขอบคุณ! อย่างไรก็ตามยังไม่ชัดเจนว่าคุณใช้บริบทตัวบันทึกนี้อย่างไรกับอินเทอร์เฟซตัวโหลดอัตโนมัติ PSR-3 - เช่นถ้าคุณกำลังเข้าสู่ระบบ$this->logger->info($message, $level);- คุณจะพูดว่า "ใช้บริบทของฉัน" ได้อย่างไร?
Alan Storm

2
สิ่งที่ดีคือมีการใช้ตัวจัดการทั้งหมดที่มีให้กับ Monolog และอันดับแรกที่สามารถจัดการกับระดับของการบันทึก (DEBUG, INFO เป็นต้น) ดังนั้นวิธีเดียวที่ฉันเห็นจะแน่ใจว่าใช้ตัวจัดการของคุณอย่างแน่นอนคือการผลักมันก่อนที่คุณต้องการดังนั้นที่ด้านบนสุดของสแต็กและมาก่อนในลูป อีกวิธีหนึ่งก็คือเพียงแค่ตั้งค่าให้เป็นตัวจัดการลบสิ่งอื่น ๆ ทั้งหมด แต่นั่นไม่ใช่สิ่งที่เป็นมิตรที่ต้องทำ
Petar Dzhambazov

หากคุณพยายามแนะนำตัวจัดการเพิ่มเติมใน 2.0.0 GA หรือทำงานกับการระบุตัวจัดการใน di.xml คุณอาจต้องระวังปัญหานี้github.com/magento/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 ขอบคุณ! อย่างไรก็ตาม - คำตอบอื่น ๆ ทำให้ดูเหมือนว่าอาจมีคนตัดไม้คนเดียวและการขยาย / สร้างวิธีการจัดการไม่จำเป็นอีกต่อไป คุณรู้หรือไม่ว่ามันเป็นเรื่องจริง?
Alan Storm

4

รวมคลาสตัวบันทึก psr ในไฟล์ของคุณโดยใช้การใช้แล้วเรียก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
คุณไม่ควรใช้ ujse addDebug เนื่องจากนั่นไม่ใช่ psr logger ที่เข้ากันได้ ใช้เพียงแค่ดีบักแทน
Maciej Paprocki

4

ปรับปรุง: 19/08/2019

หากคุณกำลังมองหาตัวจัดการบันทึกที่กำหนดเองที่สง่างามฉันขอแนะนำให้คุณใช้ประเภทเสมือน (ซึ่งไม่จำเป็นต้องเพิ่มรหัส PHP ใด ๆ )

แรงบันดาลใจจากคำตอบของPetar Dzhambazovและhalkผู้หญิงและสุภาพบุรุษฉันแนะนำวิธีที่ดีกว่าและสั้นกว่าแทนรหัสบันทึกที่กำหนดเองซ้ำตลอดเวลา

StackOverflow \ ตัวอย่าง \ 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>

การใช้งาน

ผู้ขาย \ บางสิ่งบางอย่าง \ รุ่น \ 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 \ ตัวอย่าง \ etc \ ส่วนหน้า \ 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
@ 7ochem โอ้ใช่แล้วคือ: v
Toan Nguyen

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คลาสInject ใน Constructor \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);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.