Re: [log4perl-devel] Appender::File and Layout question
On Mon, 09 Mar 2009 12:09 -0700, Mike Schilli m...@perlmeister.com wrote: A, gotcha, I forgot that you have a long-running process and want to switch log files for every request. To do that, you can write your own appender (it's very easy, check http://search.cpan.org/dist/Log-Log4perl/lib/Log/Log4perl/FAQ.pm#How_can_I_write_my_own_appender?) or, alternatively, when you get a request, run Log::Log4perl-appender_by_name(LogApp)-file_switch(log$$.log); given that LogApp is the name of the appender in your Log4perl configuration (if you're using :easy, its name is app001). I like the use of file_switch, because this seems to map perfectly well to the design I have right now. If I use easy_init like this: Log::Log4perl-easy_init( {level = $log_level, file = 'STDOUT', layout = '%.1p %d{HH:mm} %M(%L) %m%n' }, {level = $log_level, file = main.log, layout = '%.1p %d{dd.MM. HH:mm:ss (EEE)} %M(%L) %m%n' } {level = $log_level, file = 'dummy.log'), layout = '%.1p %d{HH:mm} %M(%L) %m%n' }, ); I guess the name of the dummy.log appender then is app003, so I would have to switch it by Log::Log4perl-appender_by_name('app003')-file_switch(get_request_logfile()); or alternatively that I explicitly provide logger names, i.e. Log::Log4perl-easy_init( {level = $log_level, file = 'STDOUT', layout = '%.1p %d{HH:mm} %M(%L) %m%n' }, {level = $log_level, file = main.log, layout = '%.1p %d{dd.MM. HH:mm:ss (EEE)} %M(%L) %m%n' } {level = $log_level, file = 'dummy.log'), layout = '%.1p %d{HH:mm} %M(%L) %m%n', name = 'requestlogger' }, ); ... Log::Log4perl-appender_by_name('requestlogger')-file_switch(get_request_logfile()); Is this correct? Regards, Ronald -- Ronald Fischer rona...@eml.cc + If a packet hits a pocket on a socket on a port, + and the bus is interrupted and the interrupt's not caught, + then the socket packet pocket has an error to report. + (cited after Peter van der Linden) -- ___ log4perl-devel mailing list log4perl-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/log4perl-devel
Re: [log4perl-devel] Appender::File and Layout question
Resent of my posting from 24 Feb which seems to have been lost. - Original message - From: Ronald Fischer yn...@mm.st To: Mike Schilli m...@perlmeister.com Cc: Mike Schilli m...@perlmeister.com, log4perl MailingList log4perl-devel@lists.sourceforge.net Date: Tue, 24 Feb 2009 09:52:06 +0100 Subject: Re: [log4perl-devel] Appender::File and Layout question On Mon, 23 Feb 2009 08:34 -0800, Mike Schilli m...@perlmeister.com wrote: The other problem is that I would strongly prefer a solution without l4p configuration file. The reason is that one requirement for our application was one config file only, so we have an application specific configuration file, so I'm using easy_init to initialize the logging. Everything you can do in a configuration file can be done in code with the Log4perl API, problem is just that it might get confusing if you're trying to figure out what's going on by looking at the configuration file, while application code is pulling the rug under it :). Right, but this is a decision I don't want to (actually, I must not) decide by myself, but this must be done by the project leader, which means that I have to at least demonstrate both ways. Thanks to your explanations, I understand how to do it in a config file, but I don't see how to do it in my code. Probably it is not possible at all with easy_init (which I would like to continue to use) - at least I can't find anything suitable in the perldoc of Log::Log4perl. There is something in the section Advanced Perl Configuration, but I don't see how to use it in my case. This is how far I got: # This is my current initialization Log::Log4perl-easy_init( # ... Details left out ); # Now define the request-specific logger use Log::Log4perl::Layout; use Log::Log4perl::Level; my $req_logger= Log::Log4perl-get_logger(???); my $req_appender = Log::Log4perl::Appender-new( Log::Log4perl::Appender::File, name = ???, mode = 'clobber', utf8 = 1, create_at_logtime = 1 filename = \get_current_logfile); # ??? $req_appender-layout(Log::Log4perl::Layout::PatternLayout-new(...)); $req_logger-add_appender($req_appender); $req_logger-level($INFO); And when it comes to logging something to the request logger, I would write i.e. $req_logger-loginfo(my message goes here); I don't know whether the general idea is right or whether there is a shorter way to write it, but still there are a few open points, which I have marked in my code above with ???. First, what category string should I pass to get_logger? We don't work with categories, and we have none defined with easy_init, so it would make sense to me to pass the default category. Could this be done by passing, say, the null string? Second, what is the name parameter used for when creating the Appender. I found the usage of name = in the perldoc, but what's its purpose? Finally, is my usage of passing a code reference to filename correct? Kind regards, Ronald -- Mike Mike Schilli m...@perlmeister.com -- Ronald Fischer rona...@eml.cc + If a packet hits a pocket on a socket on a port, + and the bus is interrupted and the interrupt's not caught, + then the socket packet pocket has an error to report. + (cited after Peter van der Linden) -- Ronald Fischer rona...@eml.cc + If a packet hits a pocket on a socket on a port, + and the bus is interrupted and the interrupt's not caught, + then the socket packet pocket has an error to report. + (cited after Peter van der Linden) -- Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H ___ log4perl-devel mailing list log4perl-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/log4perl-devel
Re: [log4perl-devel] Appender::File and Layout question
On Fri, 6 Mar 2009, Ronald Fischer wrote: I understand how to do it in a config file, but I don't see how to do it in my code. Probably it is not possible at all with easy_init (which I would like to continue to use) easy_init() and init() are using the same underlying internal Log4perl API functions, so it doesn't matter which one you're using. # This is my current initialization Log::Log4perl-easy_init( # ... Details left out ); # Now define the request-specific logger use Log::Log4perl::Layout; use Log::Log4perl::Level; my $req_logger= Log::Log4perl-get_logger(???); Since you don't want categories, use the root logger here: my $req_logger= Log::Log4perl-get_logger(); my $req_appender = Log::Log4perl::Appender-new( Log::Log4perl::Appender::File, name = ???, You can omit the name. mode = 'clobber', utf8 = 1, create_at_logtime = 1 filename = \get_current_logfile); # ??? You don't want to pass a reference here, you want to call the function right here: filename = get_current_logfile() ); and define it like sub get_current_logfile { return logfile.dat; } or whatever fance logic you want it to use, but it needs to return the name of the file. So, a working version of what you want would look something like this: use strict; use Log::Log4perl qw(:easy); # This is my current initialization Log::Log4perl-easy_init($DEBUG); use Log::Log4perl::Layout; use Log::Log4perl::Level; my $req_logger= Log::Log4perl-get_logger(); my $req_appender = Log::Log4perl::Appender-new( Log::Log4perl::Appender::File, mode = 'clobber', utf8 = 1, create_at_logtime = 1, filename = get_current_logfile()); $req_appender-layout(Log::Log4perl::Layout::SimpleLayout-new()); $req_logger-add_appender($req_appender); DEBUG waah; ### sub get_current_logfile { ### return logfile.dat; } One more thing: A logger (the root logger in your case) can only have one level. So if you initialize with easy_init($DEBUG), that's the level it's gonna have. If you want different levels for the file appender you're setting up manually, use appender thresholds or a filter. Hope that helps! -- Mike Mike Schilli m...@perlmeister.com -- Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H ___ log4perl-devel mailing list log4perl-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/log4perl-devel
Re: [log4perl-devel] Appender::File and Layout question
On Thu, 19 Feb 2009, Ronald Fischer wrote: What you think is a 'logger' is really an appender in Log4perl lingo. An appender has no concept of a level like 'debug', only loggers do. I see, and that's why it also can't understand about layouts. Actually, just for the record, you can set an appender's layout: $appender-layout($layout); # perldoc Log::Log4perl::Appender Now I would like to incorporate the possibility that in addition to that normal, continually going logfile, the logs occuring to each request should be written into a separate, request-specific logfile, so that, if we hav 100 requests on a day, we would end up having 100 extra logfiles in addition to the main logfile. Add another appender to your category and have it name its log files according to a function get_request_name() that your application provides: log4perl.logger = DEBUG, FooApp, BarApp, AnotherAppender # ... log4perl.appender.AnotherAppender.filename = \ sub { mylog. . get_request_name() . .log } Each of these extra logfiles is named after the request. This means that whenever a new request arrives, we have to create a new logfile. Since the requests are handled in parallel (but non-preemtive, i.e. no threads involved), we have a central logging handler which knows which request is the currently active one, and sends each logging event to the standard log, plus to the request-specific one. I'm assuming that each 'request' starts the app anew. The continually going logfile appender is in 'append' mode and the request-based logfile appender is in 'clobber' mode. -- Mike Mike Schilli m...@perlmeister.com -- Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H ___ log4perl-devel mailing list log4perl-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/log4perl-devel
Re: [log4perl-devel] Appender::File and Layout question
On Wed, 18 Feb 2009, Ronald of Steiermark wrote: Reason for this probably slightly unusual way of using Log::Log4perl is the following: Hi Ronald, indeed, you're using Log4perl in a very unusual, not to say confusing way. What you think is a 'logger' is really an appender in Log4perl lingo. An appender has no concept of a level like 'debug', only loggers do. An appender only has a log() method, and it will normally log the message you're passing to it unconditionally. The reason why you get the error message 'on an undefined value' is an internal autoload mechanism within the appender that's not defined in your case. The error message is confusing and needs to be fixed, what it should say instead is that logdebug() doesn't exist. Ideally, you would integrate your logging needs into the main log4perl configuration -- can you explain in more detail why this isn't possible? -- Mike Mike Schilli m...@perlmeister.com My application uses one common logging facility (hence the easy_init). Certain parts of the application want to create occasionally their various other logfiles with their own layout and shorter lifetime than the common logging system (demonstrated here by the variable $logger). This is the condensed code of my application just for demonstrating my problem: use strict; use warnings; use Log::Log4perl qw(:easy); use Log::Log4perl::Appender::File; Log::Log4perl-easy_init({file='STDOUT',layout = '%d{HH:mm} %m%n', level=$DEBUG}); my $logger=Log::Log4perl::Appender::File-new(filename = dummy.log, mode = 'clobber'); $logger-log(message=test\n); $logger-layout(Log::Log4perl::Layout::PatternLayout-new('%c %C %m%n')); $logger-log(message = abc); $logger-logdebug('xyz'); Running this program results in a file dummy.log containing test abc and the message Can't call method logdebug on an undefined value Now my questions: (1) Why does the second call to log() not obey the pattern layout I have defined the line before? After all, a Appender::File inherits from Appender, and hence layout() should have the desired effect. (2) Why does the error message say on an undefined value, when $logger (the object where method is called on) is obviously not undefined? (3) I guess one of my mistakes is that Appender::File is not a suitable logger type for my purpose. Should I use a different logger instead, and if yes, which one? Ronald -- Ronald Fischer austria_ru...@yepmail.net There are 10 types of people in the world: those who understand binary and those who don't. -- Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H ___ log4perl-devel mailing list log4perl-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/log4perl-devel -- Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H ___ log4perl-devel mailing list log4perl-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/log4perl-devel