Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

Accessing Log::Log4perl Configuration Values

by valdez (Monsignor)
on Mar 18, 2007 at 15:42 UTC ( #605366=perlquestion: print w/replies, xml ) Need Help??

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

Dear Monks,

Log::Log4perl is my preferred tool for logging and this time I want to access some values of its configuration from another application. I've read the documentation, but I didn't find any suitable method; so I started from parsing a configuration file, but very soon I realized that I also needed the variable expansion feature provided by Log4perl; after that I dived into the source and came back with the following class to accomplish the task:

package Log::Log4perl::Config::Standalone; use Log::Log4perl::Config; use Log::Log4perl::Config::PropertyConfigurator; use Carp; sub new { my ($class, $filename) = @_; confess "configuration '$filename' not found\n" unless -f $filename; my $cp = Log::Log4perl::Config::PropertyConfigurator->new; $cp->file( $filename ); my $self = { data => $cp->parse() }; return bless $self, $class; } sub value { my ($self, $path, $default) = @_; my @p = split /\./, $path; shift @p if $p[0] eq 'log4perl'; my $found = 1; my $r = $self->{data}; while (my $n = shift @p) { if (exists $r->{$n}) { $r = $r->{$n}; } else { $found = 0; } } return $found ? $r->{value} : $default; } 1; __END__
Given the following configuration file:
# filename: l4p.conf global_var = /var/log/some/file.log log4perl.rootLogger = DEBUG, LOGFILE log4perl.appender.LOGFILE = Log::Log4perl::Appender::File log4perl.appender.LOGFILE.filename = ${global_var} log4perl.appender.LOGFILE.mode = append log4perl.appender.LOGFILE.layout = PatternLayout log4perl.appender.LOGFILE.layout.ConversionPattern = %d{ISO8601} [%P] +%C %p %m%n
this code retrieves a value:
use Log::Log4perl::Config::Standalone; my $c = Log::Log4perl::Config::Standalone->new('./l4p.conf'); print $c->value('log4perl.appender.LOGFILE.filename'), "\n";
What do you think about it? How would you solve the same problem?

Thanks, Valerio

Replies are listed 'Best First'.
Re: Accessing Log::Log4perl Configuration Values
by andyford (Curate) on Mar 18, 2007 at 18:03 UTC

        Sorry I should have explained my thoughts in more detail.

        What I'm thinking is that your write your log4perl configs in XML. Log::Log4perl::Config::DOMConfigurator is used in your perl programs that are actually using Log::Log4perl. Then when you want to get at your config elements from somewhere else, you parse the XML with a DTD and an XML parser. That buys you a clean way to get at everything in the log4perl configs.

        Of course this is a lot of work and it may be overkill for your needs. However it does "future-proof" you in the case of later requirements causing your home grown parsing to become unwieldy or hard to maintain.

        non-Perl: Andy Ford

Re: Accessing Log::Log4perl Configuration Values
by whereiskurt (Friar) on Mar 18, 2007 at 19:07 UTC

    I'm feeling some sort of 'O'Reilly tribute' <Saint Patty's just passed>

    Happy St. Patty's (I'm actually a tad late, somewhere)

    I have always found that to be an excellent log4perl article series, but as I refer to it I can't seem to see any reference to it. Here's a better source:

    Variable Substitution (are you not a troll? :L)

    " To avoid having to retype the same expressions over and over again, Log::Log4perl's configuration files support simple variable substitution. New variables are defined simply by adding

    varname = value

    lines to the configuration file before using

    afterwards to recall the assigned values. Here's an example:
    layout_class = Log::Log4perl::Layout::PatternLayout layout_pattern = %d %F{1} %L> %m %n log4perl.category.Bar.Twix = WARN, Logfile, Screen log4perl.appender.Logfile = Log::Log4perl::Appender::File log4perl.appender.Logfile.filename = test.log log4perl.appender.Logfile.layout = ${layout_class} log4perl.appender.Logfile.layout.ConversionPattern = ${layout_patt +ern} log4perl.appender.Screen = Log::Log4perl::Appender::Screen log4perl.appender.Screen.layout = ${layout_class} log4perl.appender.Screen.layout.ConversionPattern = ${layout_patte +rn}

    This is a convenient way to define two appenders with the same layout without having to retype the pattern definitions.


    After rereading your post (I tend to do that) I think that perhaps this more inline with what you're getting at. This is analagous to writing log4perl eval statment - pick your favourite Templater for flavour. Kurt

    Dirty Tricks Example (Sorry about the Troll comment :))

    A simple example to cut-and-paste and get started:

    use Log::Log4perl qw(get_logger); my $conf = q( log4perl.category.Bar.Twix = WARN, Logfile log4perl.appender.Logfile = Log::Log4perl::Appender::File log4perl.appender.Logfile.filename = test.log log4perl.appender.Logfile.layout = \ Log::Log4perl::Layout::PatternLayout log4perl.appender.Logfile.layout.ConversionPattern = %d %F{1} %L> +%m %n ); Log::Log4perl::init(\$conf); my $logger = get_logger("Bar::Twix"); $logger->error("Blah");

    This will log something like:

    2002/09/19 23:48:15 t1 25> Blah

    to the log file 'test.log', which Log4perl will append to or create it if it doesn't exist already.

      Ciao whereiskurt,

      I know how to use Log4perl configuration files :)) The problem was different, let me rephrase it: I want to access l4p configuration values from outside l4p itself, how? An home-made parser is not the solution, as I should implement also variable substitution; on the other side, l4p Config classes are not so friendly. Now, I'm asking myself if the way I used the Log4perl classes is correct or not.

      Thanks, Valerio

        Valerio, after looking at your home node it's pretty clear that you would know how to use log4perl :) <kneels humbly>

        I wonder how you moved forward on this problem? It would seem there are only two ways to go: either you're building a config on the fly and using the log4perl::init call, or you're letting log4perl parse through a config already made and working with the log4perl->value madness. :)

        I wonder <outloud apparently> if slupring the 'l4p.conf' and munging it might really be your best option? I suspect that the variable substitution wouldn't be that tricky afterall... regards!


        PS: I realise that you said *do not* want yet another home made parser but here's one just incase anyone was interested (or incase you changed your mind :))

      Patty is a girl. Like Patty Hearst, for example, machine-gun and all.

      An Irish Patrick is Paddy.


Re: Accessing Log::Log4perl Configuration Values
by saintmike (Vicar) on Mar 21, 2007 at 06:22 UTC
    Actually, Log::Log4perl already offers access to certain parts of the configuration: You can find appenders by name via Log::Log4perl->appender_by_name, for example. Make sure to read the explanation in the manual for this.

    If you're just after the name of a file used by a file appender, that'd be the route I'd recommend for you to use. If you're after a custom appender, there's an FAQ for that.

    If you need anything else, just let me know what it is you're after, and if it's of general interest, I can put it into Log::Log4perl for you.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://605366]
Approved by ikegami
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (2)
As of 2022-05-22 14:48 GMT
Find Nodes?
    Voting Booth?
    Do you prefer to work remotely?

    Results (80 votes). Check out past polls.