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?

War es hilfreich?

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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top