Wie kann ich mich in Perls Druck einhängen?

Hier ist ein Szenario. Sie haben eine große Anzahl von Legacy-Skripten, die alle eine gemeinsame Bibliothek verwenden. Diese Skripte verwenden die Anweisung 'print' für die Diagnoseausgabe. An den Skripten dürfen keine Änderungen vorgenommen werden - sie sind weit verbreitet, haben ihre Zulassungen und haben die fruchtbaren Täler der Kontrolle und Kontrolle längst verlasse

Jetzt ist ein neuer Bedarf eingetroffen: Die Protokollierung muss jetzt zur Bibliothek hinzugefügt werden. Dies muss automatisch und transparent erfolgen, ohne dass Benutzer der Standardbibliothek ihre Skripte ändern müssen. Gängigen Bibliotheksmethoden können einfach Protokollierungsaufrufe hinzugefügt werden. Das ist der einfache Teil. Das Schwierige daran ist, dass die Diagnoseausgabe dieser Skripte immer mit der Anweisung 'print' angezeigt wurde. Diese Diagnoseausgabe muss gespeichert, aber genauso wichtig verarbeitet werden.

Als Beispiel für diese Verarbeitung sollte die Bibliothek nur die gedruckten Zeilen aufzeichnen, die die Wörter "Warnung", "Fehler", "Hinweis" oder "Aufmerksamkeit" enthalten. Der folgende extrem triviale und erfundene Beispielcode (TM) würde einige der Ausgaben aufzeichnen:

sub CheckPrintOutput
{
    my @output = @_; # args passed to print eventually find their way here.
    foreach my $value (@output) {
         Log->log($value) if $value =~ /warning|error|notice|attention/i;
    }
}

(Ich möchte Themen wie "Was sollte protokolliert werden?", "Druck sollte nicht für Diagnosezwecke verwendet werden", "Perl ist zum Kotzen" oder "Dieses Beispiel weist die Fehler xy und z auf" ... auf ist der Kürze und Klarheit halber stark vereinfacht.)

Das Grundproblem besteht darin, Daten zu erfassen und zu verarbeiten, die an den Drucker übergeben werden (oder in Perl eingebaute, nach diesen Grundsätzen). Ist es möglich? Gibt es eine Möglichkeit, es sauber zu machen? Gibt es Protokollierungsmodule mit Hooks, mit denen Sie dies ausführen können? Oder ist es etwas, das vermieden werden sollte, wie die Pest, und ich sollte es aufgeben, jemals die gedruckte Ausgabe zu erfassen und zu verarbeiten?

Additional: Dies muss plattformübergreifend ausgeführt werden - Windows und * nix gleichermaßen. Die Ausführung der Skripte muss ebenso wie die Ausgabe des Skripts unverändert bleiben.

Additional additional: Ein interessanter Vorschlag in den Kommentaren der Antwort von codelogic:

Sie können eine Unterklasse von @ anleghttp: //perldoc.perl.org/IO/Handle.htm und erstellen Sie Ihr eigenes Dateihandle, das die Protokollierungsarbeit erledigt. - Kamil Kisiel

Dies könnte es mit zwei Einschränkungen tun:

1) Ich brauche eine Möglichkeit, diese Funktionalität für alle Benutzer der allgemeinen Bibliothek zu exportieren. Dies müsste automatisch für STDOUT und wahrscheinlich auch für STDERR gelten.

2)the IO :: Handle Dokumentation sagt, dass Sie es nicht unterordnen können, und meine Versuche waren bisher erfolglos. Ist etwas Besonderes erforderlich, damit die Unterklasse IO :: Handle funktioniert? Die Standardmethode 'use base' IO :: Handle 'und das anschließende Überschreiben der Methoden new / print scheinen nichts zu bewirken.

Final edit: Sieht aus wie IO :: Handle ist eine Sackgasse, aber Tie :: Handle kann es tun. Danke für all die Vorschläge; Sie sind alle wirklich gut. Ich werde die Route Tie :: Handle ausprobieren. Wenn es Probleme macht, komme ich wieder!

Addendum: Beachten Sie, dass ich nach ein wenig Arbeit festgestellt habe, dass Tie :: Handle funktioniert, wenn Sie nichts Schwieriges tun. Wenn Sie eine der Funktionen von IO :: Handle mit Ihrem gebundenen STDOUT oder STDERR verwenden, ist dies im Grunde genommen ein Crapshoot, um sie zuverlässig zum Laufen zu bringen. Ich konnte keinen Weg finden, die Autoflush-Methode von IO :: Handle für die Arbeit mit meinem gebundenen STDOUT oder STDERR zu verwenden Griff. Wenn ich die automatische Spülung vor dem Binden des Griffs aktivieren würde, würde dies funktionieren. Wenn das für Sie funktioniert, ist die Route Tie :: Handle möglicherweise akzeptabel.

Antworten auf die Frage(10)

Ihre Antwort auf die Frage