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.
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.
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?
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
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.
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.