SmallHttpLoggerBundle

From small iceberg
Revision as of 10:09, 26 January 2021 by Seb (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Target

SmallHttpLoggerBundle is a Symfony logger for log server like logstash, sending logs accross http protocol.

Repository

The source code is available on githut : https://github.com/sebk69/SmallHttpLoggerBundle

Installation

This bundle require :

  • Php >= 7.0
  • An installation of Symfony 5
  • composer

At the root of your symfony project, type :

composer require sebk/small-http-logger-bundle dev-master

Register bundle in config/bundles.php :

<?php

return [
    Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
    Sebk\SmallHttpLoggerBundle\SebkSmallHttpLoggerBundle::class => ['all' => true],
];

Configuration

In the configuration, you can supply server ip (or dns) and port used by you're logger collector.

Create a new file in config/packages folder : sebk_small_http_logger.yaml

sebk_small_http_logger:
  http_logger_server: "%env(HTTP_LOGGER_SERVER)%"
  http_logger_port: "%env(HTTP_LOGGER_PORT)%"

Usage

Declare log format

In order to log message you must crate a class extending Sebk\SmallHttpLoggerBundle\Logger\AbstractLog

Of course, you can use as many log class as you have type of logs (Ex : OrderLog, EventLog, ProductLog, ...). For example, ELK stack allow you to have differents formats for logs.

For example, login event that have two fields more that mandatory fields :

  • applicationId : The id of application
  • event : The emitted event name
<?php


namespace App\Logger;

use Sebk\SmallHttpLoggerBundle\Logger\AbstractLog;


class EventLog extends AbstractLog
{
    /** @var string */
    protected $applicationId;
    /** @var string */
    protected $event;

    public function __construct(string $applicationId, string $event, string $level, string $message)
    {
        $this->setApplicationId($applicationId);
        $this->setLevel($level);
        $this->setMessage($message);
        $this->setEvent($event);
    }

    /**
     * @return string
     */
    public function getApplicationId()
    {
        return $this->applicationId;
    }

    /**
     * @param string $applicationId
     */
    public function setApplicationId($applicationId)
    {
        $this->applicationId = $applicationId;
    }

    /**
     * @return string
     */
    public function getEvent(): string
    {
        return $this->event;
    }

    /**
     * @param string $event
     */
    public function setEvent(string $event): void
    {
        $this->event = $event;
    }

    public function JsonSerialize()
    {
        return [
            "timestamp" => $this->getUTCTimestamp(),
            "level" => $this->getLevel(),
            "application_id" => $this->getApplicationId(),
            "event" => $this->getEvent(),
            "message" => $this->getMessage(),
        ];
    }
}

We must implement accessors, optionnaly a constructor to simplify caller code and a JsonSerialize function to build the log in json format.

Logging action

After creating that log class, you can simply use it using Sebk\SmallEventsBundle\Dispatcher\SmallDispatcher service :

$this->logger->log(new EventLog("test", "testEvent", "info", "Emit"));

Here is a complete example of a command sending two events and log emission :

<?php


namespace App\Command;


use App\Logger\EventLog;
use Sebk\SmallEventsBundle\Dispatcher\SmallDispatcher;
use Sebk\SmallEventsBundle\Event\SmallEvent;
use Sebk\SmallHttpLoggerBundle\Logger\Logger;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;

class TestCommand extends Command
{
    protected $dispatcher;
    protected $logger;
    protected static $defaultName = "app:test";

    public function __construct(SmallDispatcher $dispatcher, Logger $logger)
    {
        $this->dispatcher = $dispatcher;
        $this->logger = $logger;

        parent::__construct();
    }

    public function execute(InputInterface $input, OutputInterface $output)
    {
        while(true) {
            $helper = $this->getHelper('question');
            $question = new Question('Message : ', "");
            $message = $helper->ask($input, $output, $question);

            $event = new SmallEvent();
            $event->setEventName("testEvent");
            $this->dispatcher->dispatch($event);
            $this->logger->log(new EventLog("test", "testEvent", "info", "Emit"));

            $event2 = new SmallEvent();
            $event2->setEventName("testMessage");
            $event2->setData($message);
            $this->dispatcher->dispatch($event2);
            $this->logger->log(new EventLog("test", "testMessage", "info", "Emit : $message"));

        }

        return 0;
    }
}

Author

Sébastien Kus
Web developer at La Bécanerie