Как я могу подключиться к печати Perl?

Вот сценарий. У вас есть большое количество устаревших сценариев, и все они используют общую библиотеку. Указанные сценарии используют оператор print для диагностического вывода. Никакие изменения не допускаются в сценариях - они распространяются повсеместно, имеют свои одобрения и уже давно оставили плодотворные долины надзора и контроля.

Теперь пришла новая потребность: регистрация должна быть добавлена ​​в библиотеку. Это должно быть сделано автоматически и прозрачно, без необходимости изменения скриптов пользователями стандартной библиотеки. К обычным библиотечным методам можно просто добавить журналы вызовов; это легкая часть. Сложность заключается в том, что диагностический вывод этих сценариев всегда отображался с использованием оператора print. Этот диагностический вывод должен быть сохранен, но, что не менее важно, обработан.

В качестве примера такой обработки библиотека должна записывать только напечатанные строки, содержащие слова «предупреждение», «ошибка», «уведомление» или «внимание». Приведенный ниже чрезвычайно простой и надуманный пример кода (tm) будет записывать некоторые из указанных выходных данных:

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

(Я бы хотел избежать таких проблем, как «что на самом деле должно быть зарегистрировано», «печать не должна использоваться для диагностики», «perl sucks» или «в этом примере есть недостатки xy и z» ... это значительно упрощено для краткости и ясности.)

Основная проблема сводится к захвату и обработке данных, переданных на печать (или любой другой встроенный perl, в соответствии с этими соображениями). Является ли это возможным? Есть ли способ сделать это чисто? Существуют ли какие-либо модули журналирования, которые имеют зацепки, чтобы позволить вам это сделать? Или это что-то, чего следует избегать, как чумы, и я должен отказаться от того, чтобы когда-либо захватывать и обрабатывать печатную продукцию?

Дополнительно: Это должно работать кроссплатформенно - Windows и * nix одинаково. Процесс запуска сценариев должен оставаться таким же, как и вывод из сценария.

Дополнительный дополнительный: интересное предложение, сделанное в комментариях ответа codelogic:

Вы можете подклассhttp://perldoc.perl.org/IO/Handle.html и создайте свой собственный дескриптор файла, который будет выполнять регистрацию. - Камил Кисиэль

Это может сделать это с двумя оговорками:

1) Мне нужен способ экспортировать эту функциональность любому, кто использует общую библиотеку. Это должно автоматически применяться к STDOUT и, вероятно, к STDERR.

2)IO :: Ручка Документация гласит, что вы не можете создать подкласс, и мои попытки до сих пор были бесплодными. Есть ли что-то особенное, что нужно для создания подклассов IO :: Handle? Стандартный «use base» IO :: Handle и последующее переопределение методов new / print, похоже, ничего не делают.

Окончательное редактирование: похоже, IO :: Handle - тупик, но Tie :: Handle может это сделать. Спасибо за все предложения; они все действительно хороши. Я собираюсь попробовать маршрут Tie :: Handle. Если это вызовет проблемы, я вернусь!

Приложение: Обратите внимание, что немного поработав с этим, я обнаружил, что Tie :: Handle будет работать, если вы не сделаете ничего хитрого. Если вы используете какие-либо функции IO :: Handle с вашими связанными STDOUT или STDERR, то, по сути, это чушь, чтобы они работали надежно - я не смог найти способ заставить метод autoflush IO :: Handle работать с моими связанными справиться. Если бы я включил автозапуск до того, как связал ручку, это сработало бы. Если это работает для вас, маршрут Tie :: Handle может быть приемлемым.

Ответы на вопрос(5)

Ваш ответ на вопрос