2

I am reading about Log4Perl from perl.com
I am trying to follow the tutorial but got "lost" in the part Logger Categories.
I tried to follow the tutorial and did the following scripts:

I created a directory Groceries and inside I created a pm file as follows:
Food.pm:

#!/usr/bin/perl  
use strict;  
use warnings;  

package Groceries::Food;  

use Log::Log4perl qw(get_logger);  

sub new {  
       my($class, $what) = @_;  
       my $logger = get_logger("Groceries::Food");  
       if(defined $what) {  
            $logger->debug("New food: $what");  
            return bless { what => $what }, $class;  
       }  
       $logger->error("No food defined");  
       return undef;  
}  
sub consume {  
        my($self) = @_;  
        my $logger = get_logger("Groceries::Food");  
        $logger->info("Eating $self->{what}");  
}  

This is copy/paste from perl.com mentioned above.
Then in the same directory that Groceries directories is in (i.e. not in the same directory that Food.pm resides) I created another script as follows:
test_script.pl:

#!/usr/bin/perl  
use strict;  
use warnings;  

######### System initialization section ###  
use Log::Log4perl qw(get_logger :levels);  
my $food_logger = get_logger("Groceries");   
$food_logger->level($INFO);   

sub test_log(){  
        my $what = @_;  
        if(defined $what){  
                $food_logger->info("Defined:", $what);  
        }  
        else{  
                $food_logger->error("Nothing defined");  
        }  
}  

test_log();  

But when I run the test script it does not work. I get:

Log4perl: Seems like no initialization happened. Forgot to call init()?

Also if I add:
test_log("something");

I get:

Too many arguments for main::test_log at testlogger.pl line 23, near ""something")" 
Execution of testlogger.pl aborted due to compilation errors.   

What am I doing wrong here?

UPDATE
I followed the tutorial and modified the way it says at listing 2: eat.pl

#!/usr/bin/perl  
use strict;  
use warnings;  

use Log::Log4perl qw(get_logger :levels);  

######### System initialization section ###  
my $food_logger = get_logger("Groceries::Food");  
$food_logger->level($INFO);  

#############Run it ###  
my $o = Groceries::Food->new("Chicken");  
$o->consume();  

####Application section ####  
package Groceries::Food;  

use Log::Log4perl qw(get_logger);  

sub new {  
       my($class, $what) = @_;  
       my $logger = $food_logger;#get_logger("Groceries::Food");  
       if(defined $what) {  
            $logger->debug("New food: $what");  
            return bless { what => $what }, $class;  
       }  
       $logger->error("No food defined");  
       return undef;  
}  


sub consume {  
        my($self) = @_;  
        my $logger = $food_logger;#get_logger("Groceries::Food");  
        $logger->info("Eating $self->{what}");  
}  

I still get Log4perl: Seems like no initialization happened. Forgot to call init()?

Jim
  • 18,826
  • 34
  • 135
  • 254
  • 2
    (1) I am not well versed with `Log::Log4Perl`, but please remove the `()` from the `test_log` declaration, unless you know exactly what *subroutine prototypes* are (You don't; this one states that `test_log` can't take any args). (2) The part of the article containing above code talks about inheriting configuration, and assumes that a `Groceries` class is fully set up to use Log4Perl. If you cover the `init` there, you don't have to repeat it in `Groceries::Food`. You don't seem to have prepared a `Groceries` class. – amon May 26 '13 at 12:05
  • 2
    Information on how to initialize can be found in the FAQ -- [What's the easiest way to use Log4perl?](http://log4perl.sourceforge.net/releases/Log-Log4perl/docs/html/Log/Log4perl/FAQ.html#f625e) – devnull May 26 '13 at 12:07
  • @toolic:But isn't `init` required when we provide a configuration file `Log::Log4perl->init("foo.conf");`? My configuration is in `######### System initialization section ###` in the script. Isn't it the same? – Jim May 26 '13 at 12:14
  • @devnull:Please see my previous comment – Jim May 26 '13 at 12:14

2 Answers2

0

You haven't mentioned appenders:

my $food_logger = get_logger("Groceries::Food");
$food_logger->level($INFO);

# Appenders
my $appender = Log::Log4perl::Appender->new(
    "Log::Dispatch::File",
    filename => "test.log",
    mode     => "append",
);

$food_logger->add_appender($appender);
Pradeep
  • 3,093
  • 17
  • 21
0

Adding the appenders as mentioned above should fix the error.

Additional:
Another option to simply get rid of this warning is to suppress the 'Log4perl: Seems like no initialization happened. Forgot to call init()?', by adding qw(get_logger :nowarn) to your Log4perl use statement:

use Log::Log4perl qw(get_logger :nowarn);

You can also run a check for initialization with Log::Log4perl::initialized().
i.e.

print "Logger initialized\n" if ( Log::Log4perl::initialized() );

More details can be found here (Log4perl FAQ): http://rpm.pbone.net/index.php3/stat/45/idpl/25575098/numer/3/nazwa/Log::Log4perl::FAQ

According to this documentation, the warning only appears once as a reminder to users not forget to initialize the logging system before using it.

Nevertheless, the first answer should be recommended.

lkisac
  • 2,007
  • 1
  • 26
  • 31