Zeigt den aktuellen Benutzer im Protokoll an
-
26-12-2019 - |
Frage
Ich versuche, einen benutzerdefinierten Monolog-Prozessor zu erstellen, um den aktuellen Benutzer an einen Fehler-Mailer anzuhängen.
Wenn Sie einen Dienst wie diesen deklarieren:
monolog.processor.mail:
class: MyVendor\Monolog\Processor\MailProcessor
arguments:
- @mailer
- @security.context
tags:
- { name: monolog.processor, method: processRecord }
Ich erhalte einen Zirkelverweis:
[Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException]
Circular reference detected for service "monolog.processor.mail",
path: "router -> monolog.logger.router -> monolog.processor.mail
-> security.context -> security.authentication.manager
-> fos_user.user_provider.username_email-> fos_user.user_manager
-> doctrine.orm.default_entity_manager -> doctrine.dbal.default_connection
-> doctrine.dbal.logger -> monolog.logger.doctrine".
Was würde das sein beste Übung Lösung hier?
Ein verwandter Forenthread:http://forum.symfony-project.org/viewtopic.php?t=40306&p=131081#p131143
Dieser Thread zeigt Folgendes:
- Die Setter-Injektion löst das Problem nicht (ich habe es auch versucht)
- Das Einfügen des Containers führt zu einer Infinitivrekursion (dies habe ich nicht bestätigt)
Habe auch dieses Skript ausprobiert http://pastebin.com/AuvFgTY3 um den Benutzer aus der Sitzung zu holen.
if ($this->session !== null) {
if ($this->session->has($this->securityKey)) {
$token = unserialize($this->session->get($this->securityKey));
$this->currentUser = $token->getUser();
}
}
Dies ergab den folgenden Fehler:
Warning: ini_set(): A session is active. You cannot change the session module's ini settings at this time in
C:\inetpub\symfony23\vendor\symfony\symfony\src\Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeFileSessionHandler.php
on line 56
Ich verstehe, dass der security.context noch nicht für Dienste erstellt wurde, die den Logger sehr früh anfordern.Für meine Klasse ist das kein Problem, da ich den Benutzer auf festlegen werde undefined
.Also idealerweise die security.context
Der Setter würde NACH dem eingespritzt security.context
Der Dienst wurde erstellt.Allerdings kann ich die Priorität des zu erstellenden Loggers nicht sehr spät ändern, da er früh benötigt wird.Vielleicht lässt sich die Frage wie folgt auflösen:Wie kann der Dienst nach der Initialisierung von security.context erneut erstellt werden?Ich bin mir nicht sicher, ob der Scope-Prototyp hier helfen würde?
Lösung
Erstellen Sie einen Handler auf Kernel-Anfrage und extrahieren Sie den Benutzer:
// src/AppBundle/Monolog/UserProcessor.php
namespace AppBundle\Monolog;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
class UserProcessor
{
private $tokenStorage;
private $user;
public function __construct(TokenStorageInterface $tokenStorage)
{
$this->tokenStorage = $tokenStorage;
}
public function __invoke(array $record)
{
if (null !== $this->user) {
$record['extra']['user'] = $this->user->getUsername();
}
return $record;
}
public function onKernelRequest(GetResponseEvent $event)
{
if (null === $token = $this->tokenStorage->getToken()) {
return;
}
if (!is_object($user = $token->getUser())) {
// e.g. anonymous authentication
return;
}
$this->user = $user;
}
}
Neuen Prozessor registrieren:
# app/config/services.yml
services:
monolog.processor.user:
class: AppBundle\Monolog\UserProcessor
arguments: ["@security.token_storage"]
tags:
- { name: monolog.processor }
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
Es liegt ein Problem mit der Symfony-Dokumentation vor