Create a custom virtual class logger in Magento2
Tags: magento, magento2, logging, php
Published: 2021-09-16 20:38:38

There are a number of ways to create a custom log in Magento2 and one of the nicest ways to do is by creating a Virtual class by using the Dependancy Injection mechanism.

Create a typical skeleton module, in this case I named it YourVendor_Module and follow these steps

### 1. Create app/code/YourVendor/Module/Logger/Reporter.php
*If you already have a class with a logger, adapt it to fit this basic structure.*

At this stage this class writes info and error messages to the standard log filenames.

```
<?php
namespace YourVendor\Module\Logger;
use Psr\Log\LoggerInterface;

/**
 * Class Reporter
 * @package YourVendor\Module\Logger
 */
class Reporter
{
    /**
     * @var LoggerInterface
     */
    protected $logger;

    /**
     * Reporter constructor.
     * @param LoggerInterface $logger
     */
    public function __construct(
        LoggerInterface $logger
    )
    {
        $this->logger = $logger;
    }

    /**
     * @param string $message
     * @param bool $print prints messages from command line
     */
    public function log(string $message, bool $print = true)
    {
        if ($print) {
            echo __($message . PHP_EOL);
        }
        $this->logger->info($message);
     }

    /**
     * @param string $message
     * @param bool $print prints messages from command line
     */
    public function logError(string $message, bool $print = true)
    {
        if ($print) {
            echo __($message . PHP_EOL);
        }
        $this->logger->error($message);
     }
}
```

### 2. Create virtual logger in app/code/YourVendor/Module/etc/di.xml

This virtual class overrides `Magento\Framework\Logger\Monolog` and links to Logger Handlers which is where the filenames are specified.
 
As a matter of code readability namespace virtual classes under `YourVendor\Module\Virtual`. 

```
<virtualType name="YourVendor\Module\Virtual\Logger"
                 type="Magento\Framework\Logger\Monolog"
    >
        <arguments>
            <argument name="handlers" xsi:type="array">
                <item name="debug" xsi:type="object">
                    YourVendor\Module\Virtual\LoggerHandler
                </item>
            </argument>
        </arguments>
    </virtualType>
```

### 3. Create and Link to the DebugLoggerHandler virtual class in di.xml

For simplicity, we log all messages to the yourvendor_module file by preferring the Base Logger, but if you require you can create as many virtual types as you want to route to what you like [More Info](https://devdocs.magento.com/guides/v2.4/config-guide/log/custom-logger-handler.html)

```
<virtualType name="YourVendor\Module\Virtual\LoggerHandler"
                 type="Magento\Framework\Logger\Handler\Base"
    >
        <arguments>
            <argument name="fileName" xsi:type="string">/var/log/yourvendor_module.log</argument>
        </arguments>
    </virtualType>
```

If you want to route Errors you can do something like:

```
<virtualType name="YourVendor\Module\Virtual\ErrorLoggerHandler"
                 type="Magento\Framework\Logger\Handler\Exception"
    >
        <arguments>
            <argument name="fileName" xsi:type="string">/var/log/yourvendor_module_errors.log</argument>
        </arguments>
    </virtualType>
```

Then go back to Step 2 in the xml and add the following argument to the arguments handler

```
<item name="error" xsi:type="object">
                    YourVendor\Module\Virtual\ErrorLoggerHandler
                </item>
```

### 4. Link the virtual classes with actual class in di.xml
To override any Psr\Log\LoggerInterface in any class, you need to replace the type name and fill the logger argument with your virtual class

```
<type name="YourVendor\Module\Logger\Reporter">
        <arguments>
            <argument name="logger" xsi:type="object">YourVendor\Module\Virtual\Logger</argument>
        </arguments>
</type>
```

### 5. Generate the files and upgrade

1. `rm -rf generated/*` or `bin/magento setup:di:compile`
2. `bin/magento setup:upgrade`
3. `rm -rf var/cache/*` or `bin/magento c:f`

If this helped you out send me some virtual love and subscribe!