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.