Erweiterung Shopware Logging

Hallo,

hat jemand Erfahrung damit, das Shopware Logging anzupassen, sodass z.B. die Ausgabe nicht in einem Logfile geschieht, sondern in die Datenbank geschrieben wird?
Am saubersten wäre es ja wohl, den Shopware Logger ( in /engine/Shopware/Components/Logger.php , wenn ich das richtig verstehe) zu decoraten, ich bin mir aber unsicher, was für Möglichkeiten ich habe, den Ausgabeort zu ändern, ohne direkt im Monolog-Library Änderungen vorzunehmen.

Ich bin für jeden Input dankbar!

VG Thomas
 

 

Hi Thomas,

kenne es zwar nur aus Symfony Projekten aber an sich sollte das bei Shopware genauso funktionieren. Du kannst über die services.xml (neue Plugin-Struktur), ein eigenes Log-Handling + LoggerService definieren.

   %kernel.logs_dir%/custom%kernel.environment%.log
   14
   
       
   



    ott

 

und statt monolog.handler.rotating_file einen der hier aufgelisteten Handler ansprechen 

So solltest Du einen eigenen Datenbankhandler definieren und ansprechen können.

1 „Gefällt mir“

Danke dir @mowlwurf‍ für die schnelle Antwort! Das werde ich ausprobieren.

Hallo nochmal, auch @mowlwurf‍.

Konnte es jetzt mal ausprobieren. Auf diese Art wird ja nur die Logger-Instanz modifiziert, die im entsprechenden Plugin genutzt wird. Mein Plan ist allerdings, möglichst das gesamte Logging zu verändern, d.h. wann immer (auch z.B. von shopware-eigenen Komponenten oder von Fremd-Plugins) eine neue Logger-Instanz erstellt wird, soll diese bereits modifiziert sein.

Mir fiele da jetzt nur ein, im Konstruktor entweder direkt bei der Logger.php in Monolog oder der Components/Logger.php in Shopware den pushHandler aufzurufen und den neuen Handler zu übergeben. Beides natürlich extrem unsaubere Methoden. Gäbe es da noch eine andere?

Hi Thomas,

da die Funktion pushHandler public ist müsstest Du theoretisch via Plugin den folgenden Event nutzen können um das möglichst sauber zu überschreiben. 

 Shopware\Components\Logger::pushHandler::replace 

Wenn das klappt könnte man sogar hingehen, und die einzelnen debug levels unterschiedlich behandeln. Z.B. nur addError ersetzen und den Rest weiterhin über den default Handler laufen lassen. Evtl. komme ich die Tage mal dazu das auszuprobieren, denn das würde mich auch interessieren. Falls Du schneller bist, würde ich mich freuen Dein Ergebnis hier zu lesen :slight_smile:

1 „Gefällt mir“

Das ist ja ne clevere Idee. Wenn ich was rausgekriegt habe, hörst du von mir.

Hi @mowlwurf:

Mein hook hat nicht funktioniert, und ich ahne auch, warum…

https://developers.shopware.com/developers-guide/event-guide/#hooks

“we don’t allow hooks on every class, but only for controllers, core classes and repositories.”

Hi nochmal,

habe es mir jetzt mal angeschaut und Du hast Recht, der Hook ist hier nicht möglich aber ich habe einen Weg gefunden. Du überschreibst einfach den Service im Container mit Deinem eigenen Childservice.

// in der Bootstrap

public static function getSubscribedEvents()
    {
        return [
            'Enlight_Bootstrap_AfterInitResource_corelogger' => 'afterInitLogger',
        ];
    }

public function afterInitLogger(\Enlight_Event_EventArgs $arguments)
    {
        if(Shopware()->Container()->has('corelogger')){
            $newLog = new CoreLogger();
            $newLog->initFromOldObject(Shopware()->Container()->get('corelogger'));
            Shopware()->Container()->set('corelogger', $newLog);
        }
    }

// der neue Service

namespace DeinPlugin\Service;

use Shopware\Components\Logger;

class CoreLogger extends Logger
{
    public function initFromOldObject(Logger $obj)
    {
        $this->setHandlers($obj->getHandlers());
        $this->withName($obj->getName());

        foreach ($obj->getProcessors() as $processor) {
            $this->pushProcessor($processor);
        }
    }

    public function addError($message, array $context = array())
    {
        var_dump('here we go');
    }
}

Gibt nun bei mir wenn ich den corelogger mit addError() aufrufe ‘here we go’ aus. So kannst Du also alle Log-Levels oder im init die Handler und Processor beliebig anpassen.

Wenn Du Deinen neuen Service dann sowohl für die corelogger als auch pluginlogger service ids registrierst hast Du alle LogEvents abgefangen, mit Ausnahme von denen, welchen ihren Eigenen verwenden.

1 „Gefällt mir“

Danke für den Code. Das AfterInitResource-Event ist ja sehr mächtig, vielen Dank für diesen guten Input!
Bei mir läuft die Grundfunktionalität jetzt auch, muss nur noch entsprechende Handler reinladen.