2013-07-23 11 views
10

Ich verwende Supervisord, um ein PHP-Programm zu verwalten, das im Hintergrund ausgeführt werden muss. Dieses Programm protokolliert Ereignisse in einer Datei worker_log. Es ist einfach genug, dies zu konfigurieren, in den supervisord.conf Ich verwende:Timestamping-Protokolle von Programmen, die von supervisord verwaltet werden

stderr_logfile=/var/log/supervisord/worker_log; 

aber ich mag für die Ereignisse in das Protokoll geschrieben werden, sich zu einem Zeitstempel. Ich habe keine Kontrolle über das PHP-Programm, also dekorieren es ist keine Option. Ich dachte mir, dass das, was ich tun würde, ist die obige Protokollkonfiguration kommentieren und das Programm über Kommandozeilenleitungen in der Supervisor Befehl Konfiguration dekorieren:

command=php /www/myapp/worker.php 2>&1 | sed "s/^/`date` /" > /var/log/supervisord/worker_log; 

Wenn dieser Befehl ausgeführt wird manuell es scheint gut zu funktionieren. Allerdings scheint Supervisord irgendwie zu verhindern, dass es richtig funktioniert, und ich kann nicht sagen, wie. worker.php funktioniert gut, aber die Berichterstattung wird in dieser Konfiguration unterdrückt. Aus diesem Grund wird der Zeitstempel natürlich nicht hinzugefügt.

Weiß jemand genug darüber, um eine Anleitung zu geben, wie das Ziel der Zeitstempelung der Arbeit des Arbeiters erreicht werden kann?

+0

Ist ist es wahrscheinlich, dass der Befehlsparameter keine Pipe unterstützt? Oder kann der Befehl sein, wenn run das Terminal freigibt, welches Supervisord nicht unterstützt? –

Antwort

7

Sie könnten einen eigenen Wrapper-Skript schreiben, die einen Filter auf die stderr vor Ihrer Arbeiter Code Aufruf anhängen wird:

// filter to prepend date/time on all stderr output 
class eventdata_filter extends php_user_filter 
{ 
    function filter($in, $out, &$consumed, $closing) 
    { 
     while (($bucket = stream_bucket_make_writeable($in))) { 
      $bucket->data = date('c') . ' ' . $bucket->data; 
      $consumed += $bucket->datalen; 
      stream_bucket_append($out, $bucket); 
     } 
     return PSFS_PASS_ON; 
    } 
} 

// register our custom filter  
stream_filter_register('eventdata', 'eventdata_filter'); 

// keep a reference to the attached filter 
$filter = stream_filter_append(STDERR, 'eventdata', STREAM_FILTER_WRITE); 

// isolate the worker from any variables in this scope, such as $filter 
function run() 
{ 
    include 'worker.php'; 
} 

// run the worker 
run(); 

// remove the filter 
stream_filter_remove($filter); 

Btw, wenn Sie den Filter nicht entfernen sie einen Segmentierungsfehler verursacht (zumindest , getestet am 5.4).

+0

Ich werde das heute ausprobieren! Es ist ein wirklich guter Vorschlag, obwohl zugegebenermaßen eine Schicht Code, die unglücklich ist. –

+0

Dies wird keine Timestamps zu einer fatalen Fehlermeldung vorgeben, dies überspringt den gesamten Userland-Code und geht direkt zu 'Output message to STDERR and die' – StampyCode

+0

@Stampy Ja, das ist leider die Art von fatalen Fehlern, da diese mit keinem Fehler abgefangen werden können handler = (obwohl vielleicht ein Shutdown-Handler funktionieren könnte ... –

4

Eine vorherige Antwort (von Jack) ist korrekt, da Sie eine andere Codeebene benötigen, um jede Zeile mit einer Zeitmarke zu versehen. Dieser Einzeiler in Perl erzielt das gleiche Ergebnis:

perl -ne '@timeparts=localtime(); printf("%04d/%02d/%02d %02d:%02d:%02d %s",$timeparts[5]+1900,$timeparts[4]+1,@timeparts[3,2,1,0], $_);' 

Verwenden Sie dies anstelle des Sed Skript.

Ein Problem mit dem Ansatz, den Sie haben versucht, war keine Arbeit, dass das Datum von dem Shell an dem Punkt berechnet und ersetzt, dass der sed Befehl alle aufgerufen wurde, so dass die Linien, die den gleichen Protokollzeitstempel gehabt hätten

+0

Warum nicht einfach 'perl -ne 'scalar (localtime) drucken.". $ _' '? Oder vielleicht' perl -mPOSIX = strftime -ne 'drucke strftime ("% F% T", localtime), $ _; " – Otheus

+0

Das könnte auch funktionieren. Ich bevorzuge das Format, das ich gab, aber es ist eine Frage des Geschmacks – Nick