1

I would like to use a Perl variable from my script in a Log::Log4perl config file. I read the documentation and found that I can use a subroutine, but I would like to do it a little bit simpler, if possible.

I want to set the filename for my appender:

log4perl.appender.av_std_LOGFILE.filename="whateverfilename.log"

But doing this this way, it is a fixed value.

I have the filename in a variable within my script and would like to use this at runtime:

log4perl.appender.av_std_LOGFILE.filename=\
 sub { return &av_getLogfileName(); }

Where this is the subroutine:

sub av_getLogfileName
{
    return $av_std_LOGFILE;
}

This works, but I would like to avoid the sub inside my script since the return value is very simple.

The documentation says:

Each value starting with the string sub {... is interpreted as Perl code to be executed at the time the application parses the configuration...

So I tried something like this, but it did not work:

log4perl.appender.av_std_LOGFILE.filename=\
    sub { print "$av_std_LOGFILE"; }

Is there a way to get result of the variable without the sub inside my script?

2
  • You said $av_std_LOGFILE is set in a script a couple times and a module a couple times. Which is it? Commented May 12, 2016 at 15:44
  • Also, you shouldn't call subroutines with & unless you know what that does. return &av_getLogfileName(); should be return av_getLogfileName(); (or better yet, return av_get_logfile_name();, mixing snake case and camel case is really hard to read and snake case is generally preferred in Perl). Commented May 12, 2016 at 15:51

1 Answer 1

5

print returns 1 on success, so

sub { print "$av_std_LOGFILE"; }

returns 1, not the value of $av_std_LOGFILE. You also have to fully qualify variable names in hooks, which means you'll have to make $av_std_LOGFILE a package global.

Change your hook to:

sub { return $main::av_std_LOGFILE; } # double quotes are unnecessary

and set $av_std_LOGFILE in your script like this (before calling Log::Log4perl::init):

our $av_std_LOGFILE = '/path/to/logfile';

Generally, you should avoid global variables, so I would prefer using a subroutine.

Sign up to request clarification or add additional context in comments.

9 Comments

thanks; I get error messages: Can't open (Datei oder Verzeichnis nicht gefunden) at /home/fx42252/perl5/lib/perl5/Log/Log4perl/Appender/File.pm line 124. at /home/fx42252/perl5/lib/perl5/Log/Log4perl/Appender/File.pm line 129.
Either you're not setting $av_std_LOGFILE in package main, or you're setting it after you call Log::Log4perl::init. If you're setting the variable inside a module, you need to use the module's package name, e.g. if your module code is package Foo::Bar; our $av_std_LOGFILE = '/foo'; then your hook would be sub { return $Foo::Bar::av_std_LOGFILE; }
lets skip the expression "module". I am using perl up to now to replace a bash script. So there is not realy a structure like package, module, ..... What I understood so far is, by using perl that way, it is all "main::". Not sure. Anyhow: You can be sure the variable is set at the time init is used.
our $av_std_LOGFILE='test.log'; $av_std_DEBUG && say "debug \$av_std_LOGFILE: $av_std_LOGFILE"; Log::Log4perl::Config->utf8( 1 ); Log::Log4perl::init( "av_log4perl.conf" ); my $logger = get_logger();$logger->error("Blah"); that is all of the script- just for testing.
see my edits of the original question which now shows the whole script.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.