adelton

Tie::STDERR

Send output of your STDERR to a process or mail

Synopsis

use Tie::STDERR;
if (;

use Tie::STDERR 'root';

use Tie::STDERR 'root', 'Errors in the script';

use Tie::STDERR '>> /tmp/log';

use Tie::STDERR '| mail -s Error root';

use Tie::STDERR \&func;

use Tie::STDERR \$append_to_scalar;

Description

Sends all output that would otherwise go to STDERR either by email to root or whoever is responsible, or to a file or a process, or calls your function at the end of the script. This way you can easily change the destination of your error messages from inside of your script. The mail will be sent or the system command or Perl function run only if there actually is some output detected -- something like cron would do.

The behaviour of the module is directed via the arguments to use, as shown above. If you do not give arguments, an e-mail to root is sent. You can give up to two scalars -- name of the recipient and the subject of the email. Argument that starts with | will send the output to a process. If it starts with > or >>, it will be written (appended) to a file. If the argument is explicit undef, if will untie previous tieness. Reference to a functions registers a callback Perl function that will be passed the string of the data sent to STDERR during your script and reference to scalar registers scalar, to which this data will be appended.

The module will catch all output, including your explicit prints to STDERR, warnings about undefined values, dies and even dies as a result of compilation error. You do not need any special treatment/functions -- Tie::STDERR will catch all. However, if you run external command (system, ``), stderr output from that process won't be caught. It is because we tie Perl's STDERR fileglob, not the external filehandle. This has the advantage that you can say

{
local *STDERR; untie *STDERR;
print STDERR "Now we go directly to STDERR\n";
}

My main goal was to provide a tool that could be used easily, especially (but not only) for CGI scripts. My assumption is that the CGI scripts should run without anything being sent to STDERR (and error_log, where it mixes up with other messages, even if you use CGI::Carp). We've found it usefull to get delivered the error and warning messages together with any relevant information (%ENV) via email.

Under mod_perl/Apache::Registry, Tie::STDERR tries to work as with normal scripts -- sends the message at the end of each request. This is done by registering a cleanup handler. If you

use Tie::STDERR 'arguments';

in your scripts, everything is fine, because the new parameters are reset each time the script is run. However, if you use some home grown module like we do (CGI::BuildPage, wrapper around CGI) that uses Tie::STDERR, that use will only be called once, during the compilation of the module and the arguments are not reset and the cleanup handler will not be registered. So next time your Apache::Registry script uses this CGI::BuildPage or however you call it, you won't probably get receive the e-mail. The solution is to call explicitely function Tie::STDERR::register_apache_cleanup in your module -- I've put it into the new method that is called in every reasonable script. (This is however subject to change. Let me know if you find better solution or if this explanation is unclear.)

Bugs

The Tie::STDERR catches the compile time errors, but it doesn't get the reason, only the fact that there was an error. I do not know how to fix this.

Version

0.26

Author

(c) 1998 Jan Pazdziora, jpx (dash) perl (at) adelton (dot) com, http://www.adelton.com/perl/