bowei_99 has asked for the wisdom of the Perl Monks concerning the following question:

Hi all, I'm trying to pass a filename into Log::Std, as is noted in the documenation for Log::StdLog:

use Log::StdLog { file => $filename };

Normally, Log::StdLog logs messages to a file named "$0.log" (that is, the current filename with .log appended. But if you pass a 'file' option, it uses that file as its logfile instead.

However, this only works if I specify the filename as $0.log and not $filename.

I found what I thought might have been the answer at the CPAN RT page for Log::Std, where someone posted a test script with the following code:

use Log::StdLog { file => "$0.log" }; # OK #use Log::StdLog { file => $filename }; # NOT OK
where the second option is commented out because it doesn't work (but it's what I want). Similarly, I tried using the following code suggested as a workaround on that same page:
use Log::StdLog; # at compile time my $file = "$config{dir}". basename($0) .".log.$$"; # at run time my $level = 'warn'; # specify file at runtime (below). Log::StdLog->import ({ level => $level, file => $file } ); # works, ru +ntime
Although this is what I want, it only works if you don't specify  use strict; use warnings;. And, of course, I have these in my code, and want to stick with them.

Doing a Supersearch and google turned up nothing that I haven't already seen. Anybody ran into this before or have any thoughts as to how I can pass in a filename?

-- Burvil

Replies are listed 'Best First'.
Re: Passing filename to Log::Std
by borisz (Canon) on Apr 12, 2006 at 20:04 UTC
    The module is working fine. You just initialize the var $filename to late. use implies a BEGIN block. So your $filename is undef unless you initialize it also in a BEGIN block.
    our $filename; BEGIN { $filename = '/tmp/mylogfile'; } use Log::StdLog { file => $filename }; print {*STDLOG} warn => 'Works fine!!!';
    or call import yourself.
    my $filename = '/tmp/mylogfile'; require Log::StdLog; Log::StdLog->import({ file => $filename }); print {*STDLOG} warn => 'Works fine!!!';
    Boris
      OK, that makes sense. However, I'm trying to set $file and $level according to what's passed into the subroutine. But, when I run my code below, it still complains of an uninitialized value(s)...

      sub StartLogging { our $ref = shift @_; # ref to config hash our ($file, $level); BEGIN { $file = $ref->{log}{file_base} . ".$ref->{hostname}{target}.$ +0.$$.log"; $level = $ref->{log}{level}; } if ( $ref->{log}{method} eq "StdLog" ) { print "Logging to file $file at minimum loglevel $level\n"; use Log::StdLog { level => $level, file => $file, }; #now, log messages can be written to {*STDLOG} my $print_rc = print {*STDLOG} warn => "warn - this is a test" +; } }

      -- Burvil

        Use require and import(), not use if you're going to do it that way. As soon as the Perl parser finishes parsing the use statement, it runs it. This happens before StartLogging even finishes compiling, and much before anything calls the subroutine.

        your code just move the problem. Try this: (untested)
        sub StartLogging { my $ref = shift @_; # ref to config hash my ( $file, $level ); $file = $ref->{log}{file_base} . ".$ref->{hostname}{target}.$0.$$.l +og"; $level = $ref->{log}{level}; if ( $ref->{log}{method} eq "StdLog" ) { print "Logging to file $file at minimum loglevel $level\n"; require Log::StdLog; Log::StdLog->import( { level => $level, file => $file, } ); #now, log messages can be written to {*STDLOG} print {*STDLOG} warn => "warn - this is a test"; } }
        Boris
Re: Passing filename to Log::Std
by bowei_99 (Friar) on Apr 12, 2006 at 22:57 UTC
    OK, so I got borisz's code to work. Just that, it doesn't seem to take a full pathname, e.g. H:\working_files\test, only the basename...

    And that I took care of by passing the filehandle, not the filename.

    -- Burvil