Skip to content

Instantly share code, notes, and snippets.

@alejobit
Last active September 14, 2024 21:24
Show Gist options
  • Save alejobit/adad4c846b34cc93a77f5dd89334fafc to your computer and use it in GitHub Desktop.
Save alejobit/adad4c846b34cc93a77f5dd89334fafc to your computer and use it in GitHub Desktop.
Symfony Monolog database handler
<?php
namespace App\Monolog;
use App\Entity\Client;
use App\Entity\Log;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\ORMException;
use Monolog\Handler\AbstractProcessingHandler;
use Symfony\Component\Security\Core\Security;
class DatabaseHandler extends AbstractProcessingHandler
{
/**
* @var EntityManagerInterface
*/
private $entityManager;
/**
* @var Security
*/
private $security;
public function __construct(
EntityManagerInterface $entityManager,
Security $security
) {
parent::__construct();
$this->entityManager = $entityManager;
$this->security = $security;
}
/**
* @param array $record
* @throws ORMException
*/
protected function write(array $record)
{
$log = new Log();
$log->setMessage($record['message']);
$log->setContext($record['context']);
$log->setLevel($record['level']);
$log->setLevelName($record['level_name']);
$log->setChannel($record['channel']);
$log->setExtra($record['extra']);
$log->setFormatted($record['formatted']);
$user = $this->security->getUser();
if ($user instanceof User) {
$log->setUser($user);
}
if (isset($record['context']['clientId']) && is_int($record['context']['clientId'])) {
$clientReference = $this
->entityManager
->getReference(Client::class, $record['context']['clientId']);
$log->setClient($clientReference);
}
$this->entityManager->persist($log);
$this->entityManager->flush();
}
}
<?php
namespace App;
use Psr\Log\LoggerInterface;
class Foo
{
/**
* @var LoggerInterface
*/
private $queueLogger;
public function __construct(LoggerInterface $queueLogger)
{
$this->queueLogger = $queueLogger;
}
public function foo()
{
$this->queueLogger->info('foo', [
'bar' => 'baz',
]);
}
}
<?php
namespace App\Entity;
use DateTime;
use Doctrine\ORM\Mapping as ORM;
use InvalidArgumentException;
/**
* @ORM\Entity(repositoryClass="App\Repository\LogRepository")
* @ORM\Table(name="log")
*/
class Log
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="text")
*/
private $message;
/**
* @ORM\Column(type="array")
*/
private $context = [];
/**
* @ORM\Column(type="smallint")
*/
private $level;
/**
* @ORM\Column(type="string", length=50)
*/
private $levelName;
/**
* @ORM\Column(type="string", length=255)
*/
private $channel;
/**
* @ORM\Column(type="array")
*/
private $extra = [];
/**
* @ORM\Column(type="datetime")
*/
private $createdAt;
/**
* @ORM\Column(type="text")
*/
private $formatted;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\User")
*/
private $user;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Client")
* @ORM\JoinColumn(referencedColumnName="Id")
*/
private $client;
public function __construct()
{
$this->createdAt = new DateTime();
}
public function getId(): ?int
{
return $this->id;
}
public function getMessage(): ?string
{
return $this->message;
}
public function setMessage(string $message): self
{
$this->message = $message;
return $this;
}
public function getContext(): ?array
{
return $this->context;
}
public function setContext(array $context): self
{
$this->context = $context;
return $this;
}
public function getLevel(): ?int
{
return $this->level;
}
public function setLevel(int $level): self
{
$this->level = $level;
return $this;
}
public function getLevelName(): ?string
{
return $this->levelName;
}
public function setLevelName(string $levelName): self
{
$this->levelName = $levelName;
return $this;
}
public function getChannel(): ?string
{
return $this->channel;
}
public function setChannel(string $channel): self
{
$this->channel = $channel;
return $this;
}
public function getExtra(): ?array
{
return $this->extra;
}
public function setExtra(array $extra): self
{
$this->extra = $extra;
return $this;
}
public function getCreatedAt(): ?\DateTimeInterface
{
return $this->createdAt;
}
public function setCreatedAt(\DateTimeInterface $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
public function getFormatted(): ?string
{
return $this->formatted;
}
public function setFormatted(string $formatted): self
{
$this->formatted = $formatted;
return $this;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): self
{
$this->user = $user;
return $this;
}
public function getClient(): ?Client
{
return $this->client;
}
public function setClient($client): self
{
if (isset($client) && !$client instanceof Client) {
throw new InvalidArgumentException();
}
$this->client = $client;
return $this;
}
}
monolog:
channels:
- "queue"
handlers:
queue:
type: service
id: App\Monolog\DatabaseHandler
channels: ["queue"]
services:
_defaults:
autowire: true
autoconfigure: true
public: false
App\Foo:
arguments:
- '@monolog.logger.queue'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment