Magento 2でカスタムログファイルを作成する方法


57

Magento 1では、ログを異なるファイルに分割することが一般的でした(支払い方法などのログを分離するため)。これは、の$fileパラメーターを変更するのと同じくらい簡単ですMage::log

Magento 2はMonologを使用するように変更されました。

Monolog(またはMagento2の実装)は、フレームワーク全体のすべてのログを重大度別にハンドラーに分割しているようです。ファイルに書き込むいくつかのハンドラーがあります。

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

Magento 1の場合のように、var / logの各ファイルにログを記録します。

特定の重大度(IE、通知をに書き込むvar/log/notice.log)のハンドラーを追加できます。拡張し\Magento\Framework\Logger\Handler\Base、ハンドラーをに登録しdi.xmlます。

この記事では、そのプロセスについておおまかに説明します。http//semaphoresoftware.kinja.com/how-to-create-a-custom-log-in-magento-2-1704130912

しかし、1つのクラス(Magentoのすべてではない)のすべてのログ(1つの重大度だけでなく)を選択したファイルに書き込むにはどうすればよいですか?

の独自のバージョンを作成する必要があるように見えますがMagento\Framework\Logger\Monolog、それが実際に機能するためにはすべてがどのように組み合わされますか?

これがMagento 2の大きなNo-Noの場合、代替手段は何ですか?クライアントサイトで必要に応じてデバッグするために、この拡張機能のログを分離するものが必要です。その情報をsystem.log、exception.logなどに書き込んで、他のすべてのモジュールのログと混ぜることは実用的ではありません。

回答:


99

Magento2のログをカスタマイズしたり、拡張したりする必要はありません。あなたが言ったように、わずかなカスタマイズでMonologを使用しています。Monologを拡張する独自のロガーを作成するだけで、ほとんど労力を要しません。

モジュールが次の場所にあると仮定しますYourNamespace/YourModule

1)ロガークラスを記述しLogger/Logger.phpます。

<?php
namespace YourNamespace\YourModule\Logger;

class Logger extends \Monolog\Logger
{
}

2)でHandlerクラスを記述しLogger/Handler.phpます。

<?php
namespace YourNamespace\YourModule\Logger;

use Monolog\Logger;

class Handler extends \Magento\Framework\Logger\Handler\Base
{
    /**
     * Logging level
     * @var int
     */
    protected $loggerType = Logger::INFO;

    /**
     * File name
     * @var string
     */
    protected $fileName = '/var/log/myfilename.log';
}

注:これは、Magentoコードを使用する唯一の手順です。\Magento\Framework\Logger\Handler\BaseMonologを拡張しStreamHandler、たとえば、Magentoベースパスを$ fileName属性に追加します。

3)ロガーを依存性注入に登録しますetc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
    <type name="YourNamespace\YourModule\Logger\Handler">
        <arguments>
            <argument name="filesystem" xsi:type="object">Magento\Framework\Filesystem\Driver\File</argument>
        </arguments>
    </type>
    <type name="YourNamespace\YourModule\Logger\Logger">
        <arguments>
            <argument name="name" xsi:type="string">myLoggerName</argument>
            <argument name="handlers"  xsi:type="array">
                <item name="system" xsi:type="object">YourNamespace\YourModule\Logger\Handler</item>
            </argument>
        </arguments>
    </type>
</config>

注:これは厳密に必須ではありませんが、DIが特定の引数をコンストラクターに渡すことを許可します。このステップを実行しない場合、コンストラクターを調整してハンドラーを設定する必要があります。

4)Magentoクラスでロガーを使用します。

これは、依存性注入によって行われます。以下に、ログエントリのみを書き込むダミー​​クラスを見つけます。

<?php
namespace YourNamespace\YourModule\Model;

class MyModel
{
    /**
     * Logging instance
     * @var \YourNamespace\YourModule\Logger\Logger
     */
    protected $_logger;

    /**
     * Constructor
     * @param \YourNamespace\YourModule\Logger\Logger $logger
     */
    public function __construct(
        \YourNamespace\YourModule\Logger\Logger $logger
    ) {
        $this->_logger = $logger;
    }

    public function doSomething()
    {
        $this->_logger->info('I did something');
    }
}

2
先日、私は建築家の一人に似た何かを尋ねていたので、この例に感謝します!DIフレームワークが異なるクラスに「正しい」ロガーを挿入できるようにクラス名に基づいてサポートを追加し、このようなコードを変更せずにフラグをオン/オフするスイッチを管理者に持つことを考えていました。この種の機能は人々にどれほど役立つでしょうか?
アランケント

1
Manoj、参照しているテンプレートにロガー付きのブロッククラスがある場合は、パブリックメソッドを作成して、メッセージをロガーに渡すことができます。_loggerが保護されているので、それがすべてで存在する場合、あなたの例では、文句を言わない仕事
halk

3
私の意見では、現在のアプローチはM1が持っていたものから一歩後退したものです。ロギングも開発者ツールである必要があり、ライブアプリケーションを監視するためだけのものではありません。私は、オプションの多目的簡素化ライブラリは現在の実装をオーバーライド開発に使用されているために作成した後、本番環境での使用のために置き換えることができますどのように見ることができます
barbazul

2
@AlanKentここでbarbazulに同意します。M1でレベルをすばやく指定して、必要なファイルに簡単にログを記録する機能は素晴らしかったです。これは(動的に)柔軟ではないので残念です。デフォルトのロガー呼び出しのパラメーターとしてファイル名を使用するとよいでしょう。答えてくれてありがとう!
ロビー

2
私にとっては、常に/var/log/system.logを取得していますが、それはなぜでしょうか?
MagePsycho

20

このようなファイルにデータを記録できます。

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

$logger->info("Info". $product->getSku() . "----- Id  ". $product->getId() );
$logger->info("preorder qty ". $product->getPreorderQty());

2
これは、迅速かつ簡単です
PMB

9

最も簡単な方法:

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

6

HalkとPradeep Kumarの回答に加えて、実際に別のファイルにログを記録することが唯一の懸念事項である場合、少し簡単な方法があります。特に、それを複数のモジュールに組み込みたい場合、またはモジュール内に異なるログファイルが必要な場合。このメソッドを使用すると、カスタムハンドラーを作成する必要がありません。

モジュールがMyNamespace/MyModuleあり、カスタムファイルにログを記録するクラスがであると仮定しますMyClass。クラスのコンストラクターが既に注入している場合は、\Psr\Log\LoggerInterfaceステップ2)にスキップします。それ以外の場合は、コンストラクタに挿入する必要があります。

1)LoggerInterfaceをクラスに挿入しますMyClass.php

<?php

namespace MyNamespace\MyModule;

use Psr\Log\LoggerInterface;

class MyClass
{
    /**
     * @var \Psr\Log\LoggerInterface
     */
    protected $logger;

    public function __construct(
        LoggerInterface $logger
    ) {
        $this->logger = $logger;
    }
}

ロガー(など\Magento\Framework\App\Helper\AbstractHelper)をすでに含むクラスを拡張する場合、別のメンバー$_loggerを使用する代わりに、そのメンバーを(通常は)上書きすることもできます。親コンストラクタディレクティブの$this->_logger = $logger 後に追加するだけです。

<?php

namespace MyNamespace\MyModule;

use Magento\Framework\App\Helper\Context;
use Psr\Log\LoggerInterface;

class MyClass extends \Magento\Framework\App\Helper\AbstractHelper
{
    public function __construct(
        Context $context,
        LoggerInterface $logger
    ) {
        parent::__construct(
            $context
        );

        $this->_logger = $logger;
    }
}

2)依存性注入を介してロガーを構成しetc/di.xmlます。

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <virtualType name="MyNamespace\MyModule\Logger\Handler" type="Magento\Framework\Logger\Handler\Base">
        <arguments>
            <argument name="filesystem" xsi:type="object">Magento\Framework\Filesystem\Driver\File</argument>
            <argument name="fileName" xsi:type="string">/var/log/mymodule.log</argument>
        </arguments>
    </virtualType>
    <virtualType name="MyNamespace\MyModule\Logger\Logger" type="Magento\Framework\Logger\Monolog">
        <arguments>
            <argument name="name" xsi:type="string">MyModule Logger</argument>
            <argument name="handlers" xsi:type="array">
                <item name="system" xsi:type="object">MyNamespace\MyModule\Logger\Handler</item>
            </argument>
        </arguments>
    </virtualType>

    <type name="MyNamespace\MyModule\MyClass">
        <arguments>
            <argument name="logger" xsi:type="object">MyNamespace\MyModule\Logger\Logger</argument>
        </arguments>
    </type>
</config>

これにより、すべてがログに記録され/var/log/mymodule.logます。

別のクラスの別のファイルにログを記録する必要がある場合は、別の仮想ハンドラーを使用して別の仮想ロガーを作成し、そのクラスに挿入するだけです。


5

単一のクラス内でのみ必要な場合:

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

pushHandlerはインターフェイスのメソッドとして公開されておらず、実装は機能していないようです...
George

Magentoのバージョンは?
mshakeel

Magento CE 2.2.0
ジョージ

CE 2.2.0で試して、ご連絡いたします。2.1
mshakeel

2

praxigento / mage2_ext_logging」モジュールを試してください。このモジュールは、Magento 2に「Monolog Cascade」サポートを追加します。「Monolog Cascade」を使用すると、単一の構成ファイルでログ出力を構成できます。独自のコードを変更せずに、さまざまなファイル、データベースにログを印刷したり、電子メールアラートを送信したりできます。

これは設定ファイルのサンプルです(デフォルトでは 'var / log / logging.yaml'):

disable_existing_loggers: true
formatters:
    dashed:
        class: Monolog\Formatter\LineFormatter
        format: "%datetime%-%channel%.%level_name% - %message%\n"
handlers:
    debug:
        class: Monolog\Handler\StreamHandler
        level: DEBUG
        formatter: dashed
        stream: /.../var/log/cascade_debug.log
    system:
        class: Monolog\Handler\StreamHandler
        level: INFO
        formatter: dashed
        stream: /.../var/log/cascade_system.log
    exception:
        class: Monolog\Handler\StreamHandler
        level: EMERGENCY
        formatter: dashed
        stream: /.../log/cascade_exception.log
processors:
    web_processor:
        class: Monolog\Processor\WebProcessor
loggers:
    main:
        handlers: [debug, system, exception]
        processors: [web_processor]

1

ロジックの変更がなく、カスタムログファイル名のみを変更する必要がある場合、カスタムロガークラスを作成する必要もありません。以下の手順に従ってください。

1. di.xmlで

 <type name="Magento\Framework\Logger\Monolog">
        <arguments>
            <argument name="name" xsi:type="string">test</argument>
            <argument name="handlers"  xsi:type="array">
                <item name="test" xsi:type="object">NAME_SPACE\Test\Model\Logger\Handler\Debug</item>
            </argument>
        </arguments>
    </type>

2.ハンドラー

<?php
/**
 * Copyright © 2017 Alshaya, LLC. All rights reserved.
 * See LICENSE.txt for license details.
 *
 */
namespace NAME_SPACE\Test\Model\Logger\Handler;

use Magento\Framework\Logger\Handler\Base;

/**
 * Log handler for reports
 */
class Debug extends Base
{
    /**
     * @var string
     */
    protected $fileName = '/var/log/test.log';
}

あなたは、デフォルトのPSRログ呼び出す必要があるデータのログインに必要なこれまでのところ
です

<?php
/**
 *
 * Copyright © 2013-2017 Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace NAME_SPACE\Test\Controller\Index;

use Psr\Log\LoggerInterface;
class Index extends \Magento\Framework\App\Action\Action
{


    /**
     * @var LoggerInterface
     */
    private $logger;

    /**
     * Show Contact Us page
     *
     * @return void
     */


    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        LoggerInterface $logger
    ) {
        parent::__construct($context);
        $this->logger = $logger;
    }


    public function execute()
    {
        $this->logger->critical((string) 'Test');
        $this->_view->loadLayout();
        $this->_view->renderLayout();
    }
}

したがって、システムを変更する必要がある場合、上記の例ではすべてのデバッグデータがtest.logに記録されます。また、di.xmlに次の行を追加することもできます。


0

ログ情報を取得したいサードパーティのモジュールでロガーオブジェクトコードを下に試しました

$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/custom.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info('Your log details: ' .$variable);

ここで詳細なコメントが必要な場合は、返信します。ありがとうございました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.