Logging with Monolog | Symfony

Anton Lytvynov
3 min readMay 28, 2018

Separate logs files in Symfony with Monolog

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.

Need professional help in web or mobile development?
Recommendation for planning or estimation of your project?
Feel free to contact me here.

--

--

Anton Lytvynov
Anton Lytvynov

Written by Anton Lytvynov

CEO & Founder of Lytvynov Production, Senior web developer, architect, cryptocurrencies trader, https://lytvynov-production.com

Responses (1)