Como posso conectar-me à impressão do Perl?

Aqui está um cenário. Você tem uma grande quantidade de scripts herdados, todos usando uma biblioteca comum. Os referidos scripts usam a instrução 'print' para saída de diagnóstico. Nenhuma mudança é permitida nos scripts - eles variam muito, têm suas aprovações e há muito deixaram os vales frutíferos de supervisão e controle.

Agora chegou uma nova necessidade: o registro agora deve ser adicionado à biblioteca. Isso deve ser feito de forma automática e transparente, sem que os usuários da biblioteca padrão precisem alterar seus scripts. Os métodos comuns de biblioteca podem simplesmente incluir chamadas de log; essa é a parte fácil. A parte difícil está no fato de que a saída de diagnóstico desses scripts sempre foi exibida usando a instrução 'print'. Essa saída de diagnóstico deve ser armazenada, mas igualmente importante, processada.

Como exemplo desse processamento, a biblioteca deve registrar apenas as linhas impressas que contêm as palavras 'aviso', 'erro', 'aviso' ou 'atenção'. O Código de Exemplo Extremamente Trivial e Contribuído (tm) abaixo registraria algumas dessas saídas:

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

(Gostaria de evitar problemas como 'o que realmente deve ser registrado', 'impressão não deve ser usada para diagnóstico', 'perl sucks' ou 'este exemplo tem as falhas xy e z' ... muito simplificado para concisão e clareza.)

O problema básico se resume à captura e processamento de dados passados para impressão (ou qualquer perl embutido, seguindo essas linhas de raciocínio). É possível? Existe alguma maneira de fazer isso de forma limpa? Existem módulos de registro que possuem ganchos para permitir que você faça isso? Ou é algo que deve ser evitado como a praga, e devo desistir de capturar e processar a saída impressa?

Adicional: deve ser executado em várias plataformas - Windows e * Nix da mesma forma. O processo de execução dos scripts deve permanecer o mesmo, assim como a saída do script.

Adicional adicional: Uma sugestão interessante feita nos comentários da resposta da codelogic:

Você pode subclassehttp://perldoc.perl.org/IO/Handle.html e crie seu próprio identificador de arquivo, que fará o trabalho de registro. - Kamil Kisiel

Isso pode ser feito, com duas ressalvas:

1) Eu precisaria de uma maneira de exportar essa funcionalidade para quem usa a biblioteca comum. Teria que se aplicar automaticamente ao STDOUT e provavelmente ao STDERR também.

2)o IO :: Handle a documentação diz que você não pode subclassificá-la, e minhas tentativas até agora foram infrutíferas. É necessário algo especial para fazer com que a sublclassing IO :: Handle funcione? O padrão 'use base' IO :: Handle 'e substituindo os novos métodos de impressão parecem não fazer nada.

Edição final: parece que IO :: Handle é um beco sem saída, mas Tie :: Handle pode fazê-lo. Obrigado por todas as sugestões; são todos muito bons. Vou tentar a rota Tie :: Handle. Se causar problemas, voltarei!

Adendo: Observe que, depois de trabalhar um pouco com isso, descobri que o Tie :: Handle funcionará, se você não fizer nada complicado. Se você usar qualquer um dos recursos do IO :: Handle com seu STDOUT ou STDERR amarrado, é basicamente um crapshoot fazê-los funcionar de maneira confiável - não encontrei uma maneira de obter o método de autoflush do IO :: Handle para trabalhar no meu lidar com. Se eu habilitasse o autoflush antes de amarrar a alça, ele funcionaria. Se isso funcionar para você, a rota Tie :: Handle pode ser aceitável.

questionAnswers(5)

yourAnswerToTheQuestion