Logging with Monolog | Symfony

Monolog

Monolog sends your logs to files, sockets, inboxes, databases and various web services. See the complete list of handlers below. Special handlers allow you to build advanced logging strategies.

Officiel github repository https://github.com/Seldaek/monolog

Install Monolog on Symfony

It’s really easy to install monolog. Officiel symfony documentation : http://symfony.com/doc/current/logging.html

Separate logs files

First of all it is a good practice to create a separated bundle for logs. So I created LoggerBundle. If you don’t know how to work with bundles look this documentation https://symfony.com/doc/bundles/.

Let’s add two different handlers and channels to separate our logs into two different files. Add this code to your app/config.yml

monolog:
handlers:
main:
type:
stream
path: '%kernel.logs_dir%/%kernel.environment%.log'
level: debug
channels: ['!event']
handler_a:
type:
stream
path: '%kernel.logs_dir%/%kernel.environment%.yobit.log'
channels: [channel_a]
handler_b:
type:
stream
path: '%kernel.logs_dir%/%kernel.environment%.gate.log'
channels: [channel_b]

After that we need to create a basic logger class and two separated services for every chanel.

Here we have an example of BasicLogger class

<?php

namespace
LoggerBundle\Logger;

use Monolog\Logger;

class BaseLogger
{
/**
*
@var Logger
*/
protected $logger;

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

/**
*
@param string $level
*
@param string $message
*
@param array $context
*/
public function log(string $level, string $message, array $context)
{
$this->logger->addRecord($level, $message, $context);
}


/**
*
@param string $message
*
@param array $context
*/
public function logError(string $message, array $context = [])
{
$this->log(Logger::ERROR, $message, $context);
}

/**
*
@param string $message
*
@param array $context
*/
public function logWarning(string $message, array $context = [])
{
$this->log(Logger::WARNING, $message, $context);
}

/**
*
@param string $message
*
@param array $context
*/
public function logNotice(string $message, array $context = [])
{
$this->log(Logger::NOTICE, $message, $context);
}

/**
*
@param string $message
*
@param array $context
*/
public function logInfo(string $message, array $context = [])
{
$this->log(Logger::INFO, $message, $context);
}
}

The advantage of BasicLogger and log method that you can reorganize your logs easy in the same method if you need someday.

Class for channel_a :

<?php

namespace
LoggerBundle\Logger;

class ChannelALogger extends BaseLogger
{
}

And class for channel_b :

<?php

namespace
LoggerBundle\Logger;

class ChannelBLogger extends BaseLogger
{
}

Let’s declare our services. I prefer to use xml in services, you can make it in yaml or php, as you wish :

<service id="logger.logger.channel_a_logger" class="LoggerBundle\Logger\ChannelALogger" public="true">
<argument type="service" id="logger"/>
<tag name="monolog.logger" channel="channel_a"/>
</service>

<service id="logger.logger.channel_b_logger" class="LoggerBundle\Logger\ChannelBLogger" public="true">
<argument type="service" id="logger"/>
<tag name="monolog.logger" channel="channel_b"/>
</service>

This services we can use anywhere we want. The result of these logs will be saved in two separated files :

  • dev.channel_a.log / prod.channel_a.log
  • dev.channel_a.log / prod.channel_b.log

Other articles

By the way, probably Symfony perfect entity, dates and data article can be interesting for you.

Thank you for your attention

Thank you for your attention. If you have any questions or advices please feel free to contact me. I‘ll be glad to help you.

LinkedIn, Twitter, Google+, lytvynov.anton@gmail.com, https://lytvynov-anton.com

Senior web developer, architect, cryptocurrencies trader, https://lytvynov-anton.com

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store