Diversity w polskim IT
Anton Lytvynov
Anton LytvynovTeam Lead @ WYND

Tworzenie logów w Symfony z biblioteką Monolog

Sprawdź, jak tworzyć logi we frameworku Symfony, wykorzystując do tego bibliotekę o nazwie Monolog.
17.11.20203 min
Tworzenie logów w Symfony z biblioteką Monolog

W tym artykule zajmiemy się tworzeniem logów we frameworku Symfony. A zrobimy to przy pomocy programu o nazwie Monolog. Monolog potrafi wysłać Twoje logi do plików, gniazd, skrzynek odbiorczych oraz różnych serwisów webowych. Cała lista handlerów znajduje się w linku poniżej, a specjalne handlery pozwalają na tworzenie zaawansowanych strategii logowania. Kliknij tutaj, aby odwiedzić oficjalne repozytorium Monolog na GitHubie.

Instalacja Monolog w Symfony

Instalacja Monolog w Symfony jest bardzo prosta i nie wymaga zbyt wielu zadań do wykonania. Warto też zapoznać się z oficjalną dokumentacją frameworku. 

Oddzielne pliki z logami 

Dobrą praktyką jest umieszczenie obsługi logów w osobny bundle — stworzyłem więc LoggerBundle. Jeśli nie wiesz, jak pracować z elementami bundle, zajrzyj do dokumentacji Symfony. Dodajmy dwa handlery i kanały, tak aby podzielić nasze logi na dwa pliki. Wprowadźmy poniższy kod do 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]


Następnie musimy stworzyć podstawową klasę logger oraz dwa oddzielne serwisy dla każdego kanału. Spójrzcie na poniższy przykład klasy BasicLogger:

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


Zaletą BasicLogger oraz metody log jest to, że można łatwo przeorganizować logi w tej metodzie w miarę potrzeby. 

Klasa dla channel_a:

<?php

namespace LoggerBundle\Logger;

class ChannelALogger extends BaseLogger
{
}


Klasa dla channel_b:

<?php

namespace LoggerBundle\Logger;

class ChannelBLogger extends BaseLogger
{
}


Zadeklarujmy nasze serwisy. W tym wypadku wolę używać XML, ale Ty możesz też to zrobić w YAML lub PHP.

<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>


Możemy tutaj użyć tych serwisów, gdzie chcemy. Wyniki logów zostanie zapisany w dwóch oddzielnych plikach.

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


Dziękuję za uwagę! 


Oryginał tekstu w języku angielskim możesz przeczytać tutaj.

<p>Loading...</p>