Q: Why Perl warn() or other STDERR output is not shown/logged/saved/flushed into my log file?
A: You may have encountered the well-known feature of stream buffering which is enabled by default.
An excerpt from the perlvar documentation says that “…STDOUT will typically be line buffered if output is to the terminal and block buffered otherwise”. Thus it is always buffered, also for STDERR.
Usually people remember to set STDOUT as auto-flush, but you should enable this for STDERR as well, or else your messages to STDERR may not appear in your log file immediately, if you are redirecting STDERR to a file.
The following piece of code sets an auto-flush for both STDOUT and STDERR:
select(STDERR); $| = 1; select(STDOUT); # default $| = 1;
Alternatively, you can also use IO::Handle to achieve the same result:
use IO::Handle; STDERR->autoflush(1); STDOUT->autoflush(1);
I never realized why stream buffering for both STDOUT and STDERR is enabled by default for most scripting languages… But that’s just me.