¿Cómo puedo conectarme a la impresión de Perl?

Aquí hay un escenario. Tiene una gran cantidad de scripts heredados, todos con una biblioteca común. Dichos scripts usan la declaración 'print' para la salida de diagnóstico. No se permiten cambios en los guiones: varían mucho, tienen su aprobación y desde hace mucho tiempo han dejado los valles fructíferos de supervisión y control.

Ahora ha llegado una nueva necesidad: el registro ahora debe agregarse a la biblioteca. Esto debe hacerse de forma automática y transparente, sin que los usuarios de la biblioteca estándar necesiten cambiar sus scripts. Los métodos de biblioteca comunes pueden simplemente agregarles llamadas de registro; Esa es la parte fácil. La parte difícil radica en el hecho de que los resultados de diagnóstico de estos scripts siempre se muestran utilizando la instrucción 'print'. Esta salida de diagnóstico debe almacenarse, pero igual de importante, procesarse.

Como ejemplo de este procesamiento, la biblioteca solo debe registrar las líneas impresas que contienen las palabras 'advertencia', 'error', 'aviso' o 'atención'. El siguiente Código de ejemplo extremadamente trivial y controlado (tm) registraría parte de dicha salida:

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;
    }
}

(Me gustaría evitar problemas como 'lo que realmente debería registrarse', 'la impresión no debería usarse para diagnósticos', 'perl apesta' o 'este ejemplo tiene los defectos xy y z' ... esto es simplificado en gran medida por brevedad y claridad.)

El problema básico se reduce a capturar y procesar los datos pasados a la impresión (o cualquier perl incorporado, en esa línea de razonamiento). ¿Es posible? ¿Hay alguna manera de hacerlo limpiamente? ¿Hay algún módulo de registro que tenga ganchos para permitirte hacerlo? ¿O es algo que debería evitarse como la peste, y debería renunciar a capturar y procesar la salida impresa?

Adicional: Esto debe ejecutarse multiplataforma - Windows y * nix por igual. El proceso de ejecución de los scripts debe permanecer igual, al igual que el resultado del script.

Adicional adicional: Una sugerencia interesante hecha en los comentarios de la respuesta de codelogic:

Puedes subclasehttp://perldoc.perl.org/IO/Handle.html y cree su propio identificador de archivo que hará el trabajo de registro. - Kamil Kisiel

Esto podría hacerlo, con dos advertencias:

1) Necesitaría una forma de exportar esta funcionalidad a cualquiera que use la biblioteca común. Tendría que aplicarse automáticamente a STDOUT y probablemente también a STDERR.

2)the IO :: Handle La documentación dice que no se puede subclasificar, y mis intentos hasta ahora han sido infructuosos. ¿Se necesita algo especial para hacer que sublclassing IO :: Handle funcione? El estándar 'use base' IO :: Handle 'y luego anular los métodos new / print parecen no hacer nada.

Edición final: Parece que IO :: Handle es un callejón sin salida, pero Tie :: Handle puede hacerlo. Gracias por todas las sugerencias; Todos son realmente buenos. Voy a probar la ruta Tie :: Handle. Si causa problemas volveré!

Anexo: Tenga en cuenta que después de trabajar un poco con esto, descubrí que Tie :: Handle funcionará, si no hace nada complicado. Si utiliza alguna de las características de IO :: Handle con su STDOUT o STDERR atado, es básicamente una trampa para que funcionen de manera confiable; no pude encontrar una manera de obtener el método de auto lavado de IO :: Handle para trabajar en mi atado encargarse de. Si habilitara el lavado automático antes de atar el mango, funcionaría. Si eso funciona para usted, la ruta Tie :: Handle puede ser aceptable.

Respuestas a la pregunta(5)

Su respuesta a la pregunta