Magento themes and extensions

LOGGING APPROACH WITH MAGENTO 2

Share

In this post I discuss the traditional approach of logging in OOP (object-oriented programming) and how it is implemented in Magento.

Topics covered: what are logs and why do you need them, how applications should be built to satisfy various developer’s and customer’s needs, what Magento 2 provides out of the box and alternative approach such as Logging + AOP (aspect-oriented programming).

What are logs?

Logs are recorded information (in chronological order) about system events for analysis in the future. The classic example of such an event is the occurrence of an error.

In a sense, logs give a certain visibility into the system processes by allowing you to get information which would not be available without being stored somewhere. For example, debugging information helps developers understand when an error occurred or what lead to the error.

For the storage of logs, the most commonly used approach is a local file which rotates according to date or file size.

A more powerful solution is centralized application logging which enables more effective management of logging data. In particular:

  • It allows storage of logs on a server other than the application server and decreases disk I/O operations, simplifying support of the application server.
  • It makes processing of logs data more effective by using special tools without impact to a production server (e.g. logstashlogplex,fluentd)

The customer’s requirements will determine which logging solution should be used. For the application is important to be able to satisfy the requirements of the customers.

Logging during development (PSR-3)

In PHP web applications built using the OOP paradigm, generally code needs to obtain a logger object for writing to centralized application logs.

Usually, the code interacts with a PHP Interface rather than depending directly on a specific logging implementation. This provides the ability for the implementation to be replaced easily without worry that such replacement may break the application code.

PSR-3 is a standard which defines such a common Interface for logging libraries. The main goal of PSR-3 is to allow libraries to receive a Psr\Log\LoggerInterface object and write logs to it in a simple and universal way.

If you are 3-rd party Magento developer who uses logging in your extension communication via an Interface instead of a concrete implementation, this guarantees that your extension will work even when logger implementation is changed in a future version of the system.

If you are logging library developer, PSR-3 guarantees that your solution is portable throughout the application.

Magento logging out of the box

Magento 2 complies with the PSR-3 standard. As a default implementation of logger it uses Monolog.

To start working with a logger you need to obtain a \Psr\Logger\LoggerInterface instance.

Example of using logger in a model

01. class SomeModel
02. {
03. private $logger;
04.
05. public function __construct(\Psr\Logger\LoggerInterface $logger)
06.     {
07.         $this->logger = $logger;
08.     }
09.
10. public function doSomething()
11.     {
12. try {
13. //do something
14.         } catch (\Exception $e) {
15.             $this->logger->critical($e);
16.         }
17.     }
18. }

Here you can see that “SomeModel” receives a “\Psr\Logger\LoggerInterface” object via constructor injection.
In a method “doSomething” if some error occurred the information about exception will be written to log by calling a method “critical” ($this->logger->critical($e);).

There are eight RFC 5424 levels (debug, info, notice, warning, error, critical, alert, emergency) available depending on the importance of a log message.

This is all you need to know for writing to the application logs, just receive a logger instance and call appropriate method.

Default Magento 2 logger (Monolog)

Monolog provides a wide range of handlers that allow you to build advanced logging strategies. It is a popular PHP logging solution.

A detailed description of how Monolog works is beyond this post but the following touches on the main concepts.

In Monolog the logger is a channel that has its own set of handlers.
There is a large number of handlers provided by Monolog divided into groups by functional specification including:

  • log to files and syslog
  • send alerts and emails
  • log specific servers and networked logging
  • logging in development (integration with such solution as FireBug and ChromePHP), and
  • log to databases

Each handler may either process the input message and stop propagation or pass the control to the next handler in a chain.
Log message can be processed in many different ways. For example, you may want to store all debug information into a file on disk, put the messages with higher log levels into a database, and finally send messages with log level “critical” via email.

At the same time, another channel may have a different set of handlers and logic.

Magento comes with the following declaration of a channel and handlers.

<application_root>/app/etc/di.xml

01. <preference for="Psr\Log\LoggerInterface" type="Magento\Framework\Logger\Monolog" />
02. <type name="Magento\Framework\Logger\Monolog">
03.    <arguments>
04.        <argument name="name" xsi:type="string">main</argument>
05.        <argument name="handlers" xsi:type="array">
06.            <item name="system" xsi:type="object">Magento\Framework\Logger\Handler\System</item>
07.            <item name="debug" xsi:type="object">Magento\Framework\Logger\Handler\Debug</item>
08.        </argument>
09.    </arguments>
10. </type>

In the first line you can see a preference for LoggerInterface. It means that each time when the code requests a Psr\Log\LoggerInterface interface, an instance of Magento\Framework\Logger\Monolog will be supplied.

Then you can see in the configuration of Magento\Framework\Logger\Monolog the declaration of the channel “main” (line 4) and declaration of two handlers (“debug” and “system”) (lines 6, 7).

  • “debug” handler catches the messages with “debug” level and writes them to “/var/log/debug.log” file.
  • “system” handler catches the messages with other levels and writes them either to “/var/log/system.log” file or to “/var/log/exception.log” file in case of exception.

If you want to customize this logic, you need to specify your own handler(s) or extend an existing one. For example, you may want to forward all the messages to syslog or to a separate server through udp and then use a management tool for logs like Logstash.

So, the tandem of PSR-3 and Monolog provides an easy to use and really powerful logging solution.

Logging and AOP

In this post, the emphasis was on logging in object-oriented code. As an alternative solution AOP (Aspect-Oriented Programming) may be used. Many people think AOP as more suitable for solving logging issues.

One of strengths of AOP is separation of business logic and service code (logging, caching, etc).

For example, what if we don’t want to modify a method by adding logger call inside the method

Business logic of method shuffled with the logging logic

01. public function doSomething()
02. {
03. try {
04. //do something
05.     } catch (\Exception $e) {
06.         $this->logger->critical($e);
07.     }
08. }

Instead, some another class may intercepts every call to method doSomethig() and send the information if exception happened.

Here is an example of how the method may looks like in AOP.

The method contains only its own business logic

01. /**
02.  * @Logging
03.  */
04. public function doSomething()
05. {
06. //do something
07. }

Application performs the logging based on doc block notation of a method.

One of minuses of AOP can be some additional performance overheads.

Conclusions

This blog post briefly introduces that Magento 2 is now PSR-3 conformant and ships with Monolog for logging. This provides isolation between code needing to write log messages and while allowing a different logging implementation to be switched in.

What approach do you prefer and why? Please, feel free to discuss. Comments on known solutions for Logging + AOP + PHP are particularly welcome!

Comments are closed.