2017-03-24 2 views
0

Ich verschärfe die Protokollierung für unsere Yii2-Anwendung und habe Probleme damit, den Logger dazu zu bringen, Nachrichten in eine Log-Datei zu schreiben, wenn es um bestimmte Kategorien geht.Yii2 Logger exportiert keine Nachrichten von Log-Zielen

Unser Projekt besteht aus den folgenden Yii2 'Anwendungen': Konsole, Common, Frontend, Backend und die Protokollierung für jede dieser Komponenten funktionieren gut für Exceptions, die von Yii generiert werden und allgemeine PHP Exceptions. Wenn ich jedoch einige info Nachrichten für eine bestimmte Kategorie im console Teil (die ich durch Ausführung von Befehlen über SHH ausführe) hinzufüge, wird das Verzeichnis, in dem die Datei enthalten sein soll, erstellt, aber die Datei selbst nicht. Ich sehe, dass die neu angegebenen Log-Nachrichten innerhalb der richtigen "FileTarget" sind, wenn ich eine var_dump davon mache.

Ich habe die flushInterval der 'Protokoll' -Komponente auf 1 und die exportInterval des logTarget auf 1 gesetzt, um sicherzustellen, dass die Nachrichten direkt auf die Ziele geschrieben werden sollen. Ich bin mir bewusst, dass dies irgendwann auf einen größeren Wert eingestellt werden sollte, aber im Moment möchte ich sicherstellen, dass die Logs tatsächlich gespeichert werden. Das Ändern der Intervallwerte scheint keine Auswirkungen zu haben.

Eine Problemumgehung, die ich kam, ist target->export() für das spezifische FileTarget manuell aufzurufen. Dies ist, wie ich zur Zeit stellen Sie sicher, Protokolle geschrieben werden:

im Controller, wo ich will Nachricht loggt ich

Yii::info('Report created succesfully.', 'reports-create'); 
UtilitiesController::forceLogExport('reports-create'); 

Die forceLogExport Methode tut dies:

public function forceLogExport($categoryName = ''){ 
     $logger = \Yii::getLogger(); 
     foreach($logger->dispatcher->targets as $target){ 
       if(!empty($categoryName)){ 
        foreach($target->categories as $category){ 
         if($category == $categoryName){ 
          $target->export(); 
         }  
        }  
       } 
     } 
     $logger->flush(true); 
    } 

Dies tut eigentlich schreibe die Logs in die .log-Datei, aber es scheint jetzt doppelte Einträge im Log zu geben und es fühlt sich einfach falsch an, nach jeder Nachricht einen Export aufzurufen.

Wie ich in den Dokumenten lese das tatsächliche Schreiben von Protokollen nur passiert, wenn entweder diese Intervalle erfüllt sind ODER wenn die Anwendung endet. Ich könnte mir vorstellen, dass die Anwendung nicht richtig beendet wird, also habe ich versucht, dies zu erzwingen, indem ich direkt nach dem Protokollieren der Nachricht Yii:$app->end() aufgerufen habe, aber die Datei bleibt leer.

Da das Problem weder die Anwendung endet nicht (I kann sehen, dass es endet) noch das Intervall erfüllt ist (Ich sehe mindestens eine Nachricht in dem Ziel und das Intervall wird auf 1 gesetzt) I Ich bin irgendwie am Ende meines Wissens, warum die Logs nicht exportiert werden. Wenn irgendjemand vielleicht weiter ausführen könnte, wenn/wo Yii die -> export() -Methode selbst nennt, wäre das eine große Hilfe.

EDIT: hinzugefügt die console/config/main.php Einstellungen. Meine Geschichte änderte sich etwas, zuerst schrieb ich, dass "die Log-Datei erstellt wurde, aber die Nachrichten nicht darin geschrieben wurden." Tatsächlich wurde jedoch nur das Verzeichnis erstellt, das die Dateien enthalten sollte, nicht die Protokolldatei selbst.

<?php 
return [ 
    'id' => 'console', 
    'basePath' => dirname(__DIR__), 
    'bootstrap' => ['log'], 
    'controllerNamespace' => 'console\controllers', 
    'components' => [ 
     'user' => [ 
      'class' => 'yii\web\User', 
      'identityClass' => 'app\models\User', 
      //'enableAutoLogin' => true, 
     ], 
     'session' => [ // for use session in console application 
      'class' => 'yii\web\Session' 
     ], 
     'log' => [ 
      'flushInterval' => 1, 
      'traceLevel' => YII_DEBUG ? 3 : 0, 
      'targets' => [ 
       [ 
        'class' => 'yii\log\FileTarget', 
        'levels' => ['error','info', 'warning'], 
        'categories' => ['reports-schedule'], 
        'exportInterval' => 1, 
        'logVars' => [null], 
        'logFile' => '@app/../logs/console/'. date('Y') . '/' . date('m') . '/reports-schedule/' . 'reports-schedule_' . date('d-m-Y') . '.log' 
       ], 
     [ 
        'class' => 'yii\log\FileTarget', 
        'levels' => ['error','info', 'warning'], 
        'categories' => ['reports-create'], 
        'exportInterval' => 1, 
        'logVars' => [null], 
        'logFile' => '@app/../logs/console/'. date('Y') . '/' . date('m') . '/reports-create/' . 'reports-create_' . date('d-m-Y') . '.log' 
       ], 
     // and 6 other similarly structured targets 
     [...], 
     [...], 
     [...], 
     [...], 
     [...], 
     [...], 
     ], 
    ] 
]; 

UPDATE: es scheint, wie ich manuell ->export() auf das gewünschte Protokollziel aufrufen müssen bleiben werde. Das Problem, das ich mit doppelten Protokolleinträgen (gleiche Nachricht, gleichen Zeitstempel) hatte, war aufgrund der Tatsache, dass ich die exportInterval Eigenschaft auf 1 für das Ziel festgelegt hatte (was ich zunächst getan habe, um sicherzustellen, dass die Nachrichten überhaupt exportiert wurden). Ich nehme an, dass der Logger Nachrichten speichert, bis der Wert exportInterval erreicht ist, und erwarte dann, dass diese Nachrichten auf die Ziele geschrieben werden.Ich habe doppelte Einträge korrigiert, weil die Eigenschaft exportInterval entfernt wurde, so dass Yii den Standardwert (1000) verwendet. Für meinen Fall wäre das ausreichend, da ich auf diese Zahlen nicht eingehen würde, aber für jeden, der dies liest, bedenken Sie bitte Ihren Anwendungsfall und prüfen Sie, ob Sie in einem einzigen Zyklus auf irgendetwas stoßen würden.

+0

Beendet der Konsolenbefehl die Verarbeitung? – Bizley

+0

Ja, und das Erzwingen des Endes (mit $ app-> end() 'oder' exit() ') ändert das Ergebnis nicht. – bsavdh

+0

In der Konsolenkonfiguration hast du ''bootstrap' => ['log']'? – Bizley

Antwort

0

Ich hatte ein ähnliches Problem zu einem bestimmten Zeitpunkt und ich denke, das sollte für Ihren Fall ausreichend sein.

Auf diese Weise können Sie einen dynamischen Protokollpfad innerhalb Ihres Zeitplanziels angeben, und nach dem Leeren wird der Protokollierer so fortgesetzt, wie er sollte.

+0

Vielen Dank! Aber das wirft einige Fragen für mich auf. Für mich ist targets ein numerisches Array und ich kann nicht auf das Ziel zugreifen, indem ich seinen Kategorienamen anrufe, so wie du es tust, aber ich nehme an, das ist nicht der Punkt, den du versuchst zu machen. Auch wenn ich ein var_dump des Zielobjekts mache, hat '' logFile' 'bereits den richtigen Pfad, daher kann ich den Pfad nicht festlegen. Und durch den Aufruf von 'flush()' werden die Nachrichten an die Ziele gesendet und nicht richtig exportiert? Ich habe versucht, flush() aufzurufen, um diese Angelegenheit früher zu lösen, aber das hatte keine Wirkung. – bsavdh

+0

Ich glaube, ich habe die ganze Geschichte zuerst nicht gelesen: P Meine beste Wette wäre, dass wenn Sie Konsolenaktionen ausführen, Sie keine Rechte für die Dateierstellung haben. Weil Flush das Abschreiben von Dateien erzwingen und von vorne beginnen sollte. Sie könnten diese Theorie testen, indem Sie versuchen, etwas im Frontend/Backend zu protokollieren und dann dasselbe in der Konsolenaktion zu tun – user2831723

Verwandte Themen