Đây là một kịch bản. Bạn có một số lượng lớn tập lệnh cũ, tất cả đều sử dụng một thư viện chung. Các tập lệnh được sử dụng sử dụng câu lệnh 'in' cho đầu ra chẩn đoán. Không có thay đổi nào được cho phép đối với các tập lệnh - chúng có phạm vi rộng và rộng, có sự chấp thuận của chúng và từ lâu đã rời khỏi các thung lũng có hiệu quả về giám sát và kiểm soát.Làm thế nào tôi có thể móc vào bản in của Perl?
Bây giờ, một nhu cầu mới đã đến: việc ghi nhật ký bây giờ phải được thêm vào thư viện. Điều này phải được thực hiện tự động và minh bạch, mà không cần người dùng của thư viện chuẩn cần thay đổi tập lệnh của họ. Các phương thức thư viện phổ biến có thể chỉ đơn giản là có các cuộc gọi ghi nhật ký được thêm vào chúng; đó là phần dễ dàng. Phần cứng nằm trong thực tế là đầu ra chẩn đoán từ các tập lệnh này luôn được hiển thị bằng cách sử dụng câu lệnh 'in'. Đầu ra chẩn đoán này phải được lưu trữ, nhưng cũng quan trọng, được xử lý.
Ví dụ về quy trình xử lý này, thư viện chỉ nên ghi lại các dòng in có chứa các từ 'cảnh báo', 'lỗi', 'thông báo' hoặc 'chú ý'. Dưới đây cực kỳ không đáng kể và giả tạo Mã Ví dụ (tm) sẽ ghi lại một số đầu ra nói:
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;
}
}
(Tôi muốn tránh các vấn đề như 'những gì thực sự cần phải đăng nhập', 'in không nên được sử dụng cho chẩn đoán ',' perl sucks ', hoặc' ví dụ này có lỗ hổng xy và z '... điều này được đơn giản hóa rất nhiều cho ngắn gọn và rõ ràng.)
Vấn đề cơ bản đi xuống để thu thập và xử lý dữ liệu được truyền đến in (hoặc bất kỳ nội trang perl nào, cùng với các dòng lập luận đó). Có thể không? Có cách nào để làm sạch không? Có bất kỳ mô-đun đăng nhập nào có móc để cho phép bạn làm điều đó không? Hay nó là thứ gì đó nên tránh như bệnh dịch hạch, và tôi nên từ bỏ việc bắt giữ và xử lý đầu ra đã in?
Bổ sung: Điều này phải chạy nhiều nền tảng - windows và * nix. Quá trình chạy các tập lệnh phải giữ nguyên, giống như đầu ra của tập lệnh.
bổ sung thêm: Một gợi ý thú vị làm trong các ý kiến của câu trả lời codelogic của:
Bạn có thể phân lớp http://perldoc.perl.org/IO/Handle.html và tạo xử lý tập tin riêng của bạn mà sẽ làm công việc khai thác gỗ. - Kamil Kisiel
Điều này có thể làm điều đó, hãy cẩn thận với hai:
1) Tôi muốn cần một cách để xuất khẩu chức năng này cho bất cứ ai sử dụng thư viện chung. Nó sẽ phải tự động áp dụng cho STDOUT và có thể là STDERR.
2) the IO::Handle tài liệu nói rằng bạn không thể phân loại nó và nỗ lực của tôi cho đến nay đã không kết quả. Có điều gì đặc biệt cần thiết để làm cho sublclassing IO :: Xử lý công việc? Tiêu chuẩn 'sử dụng cơ sở' IO :: Xử lý 'và sau đó ghi đè các phương pháp mới/in dường như không làm gì cả.
Chỉnh sửa cuối cùng: Có vẻ như IO :: Xử lý là kết thúc chết, nhưng Tie :: Xử lý có thể thực hiện. Cảm ơn tất cả những lời đề nghị; tất cả đều thực sự tốt. Tôi sẽ thử Tie :: Handle route. Nếu nó gây ra vấn đề tôi sẽ trở lại!
Phụ lục: Lưu ý rằng sau khi làm việc với điều này một chút, tôi thấy rằng Tie :: Xử lý sẽ hoạt động, nếu bạn không làm bất cứ điều gì phức tạp. Nếu bạn sử dụng bất kỳ tính năng nào của IO :: Xử lý với STDOUT gắn hoặc STDERR của bạn, về cơ bản nó là một crapshoot để làm cho chúng hoạt động đáng tin cậy - Tôi không thể tìm cách để có được phương pháp autoflush của IO :: Xử lý để làm việc trên gắn của tôi xử lý. Nếu tôi bật autoflush trước khi tôi gắn tay cầm nó sẽ hoạt động.Nếu điều đó phù hợp với bạn, tuyến đường Tie :: Handle có thể chấp nhận được.
Vậy điều gì * là * bạn được phép thay đổi? Dòng lệnh? Tệp tham số? Ví dụ: giả sử tôi đã nói "Có thể bạn có thể móc in", phạm vi của những gì bạn có thể làm là gì? – Axeman
Tôi có thể thay đổi bất kỳ thứ gì trong thư viện chung. Người dùng không nhất thiết phải chạy các kịch bản của mình theo bất kỳ cách nào khác hoặc phải chuyển bất kỳ thứ gì mới vào trên dòng lệnh. Luồng dữ liệu cuối cùng trên STDOUT và STDERR phải giống như trước đây. –
điều gì xảy ra với đầu ra ban đầu? bạn có thể tail -f nó và xử lý từ đó? – user44511