From: Jonathan S. <sw...@po...> - 2007-09-07 19:34:52
|
Hello, I'd be interested in feedback on a proposed module, Log::Abstract, described here: http://use.perl.org/~jonswar/journal/34366 This would be a tiny module designed to bridge CPAN modules that wish to log (e.g. LWP, DBI, ...) with existing logging frameworks (e.g. Log4perl), without the need for those modules to explicitly tie themselves to a single framework. I'm a longtime log4perl fan/user, and Log::Abstract is my way of increasing the input to log4perl in applications without resorting to tricks such as infiltrate_lwp(). :) Feedback most welcome, either here or on the use.perl forum. Thanks! Jon |
From: Mike S. <m...@pe...> - 2007-09-08 20:19:20
|
On Fri, 7 Sep 2007, Jonathan Swartz wrote: > I'd be interested in feedback on a proposed module, Log::Abstract, > described here: > > http://use.perl.org/~jonswar/journal/34366 > > This would be a tiny module designed to bridge CPAN modules that wish > to log (e.g. LWP, DBI, ...) with existing logging frameworks (e.g. > Log4perl), without the need for those modules to explicitly tie > themselves to a single framework. > > I'm a longtime log4perl fan/user, and Log::Abstract is my way of > increasing the input to log4perl in applications without resorting to > tricks such as infiltrate_lwp(). :) Hi Jonathan, you're addressing something really important here. It is really unfortunate that important CPAN modules like LWP or Rose::DB don't have usable logging mechanisms in place. Once you're used to category-based logging it's hard to go back to these home-grown and less convenient solutions. I think it's a great idea to promote standardized logging on CPAN and letting the user choose the actual implementation will definitely help to make strides towards that goal. By the way, I don't agree that "For small modules that want to minimize dependencies, depending on Log4perl (for example) is a non-starter." The Log4perl core doesn't have dependencies other than perl's core modules. One thing missing from your proposal is Log4perl's :easy mode. If you think about it, getting a logger and calling its method is a lot of typing, given that you just want to log something. That's why in Log4perl you can use DEBUG "Log this!"; and you're done. No getting a logger, no method calling, no category passing. It's all automatic. Behind the scenes, it gets a 'stealth logger' with the category set to the current package and calls the appropriate logging method on it. This feature is huge. I'm using it almost exclusively in everything I write. Any chance of adding that? Keep up the great work! -- Mike Mike Schilli m...@pe... |
From: Jonathan S. <sw...@po...> - 2007-09-09 04:14:59
|
> > On Sep 8, 2007, at 1:19 PM, Mike Schilli wrote: > > > On Fri, 7 Sep 2007, Jonathan Swartz wrote: > > > > I'd be interested in feedback on a proposed module, Log::Abstract, > > described here: > > > > http://use.perl.org/~jonswar/journal/34366 > > ... > > By the way, I don't agree that "For small modules that want to > minimize dependencies, depending on Log4perl (for example) is a > non-starter." The Log4perl core doesn't have dependencies other > than perl's core modules. Fair enough. > > One thing missing from your proposal is Log4perl's :easy mode > [sourceforge.net]. If you think about it, getting a logger and > calling its method is a lot of typing, given that you just want > to log something. That's why in Log4perl you can use > > DEBUG "Log this!"; > > and you're done. No getting a logger, no method calling, no > category passing. It's all automatic. Behind the scenes, it gets > a 'stealth logger' with the category set to the current package > and calls the appropriate logging method on it. This feature is > huge. I'm using it almost exclusively in everything I write. > > Any chance of adding that? Did you see this in the posting? As a convenient shorthand, you can use package Foo; use Log::Abstract qw($log); to create the logger, which is equivalent to the first example except that $log is (necessarily) a package-scoped rather than lexical variable. So this creates a logger for you with the category set to the current package, similar to easy mode. The syntax is pretty minimal. The problem I have with the DEBUG etc keywords is that they promote inefficient behavior. e.g. DEBUG "Current arguments: " . Dumper(\@_); will take the performance hit for Dumper() even when debug logging isn't turned on. This may be fine for a particular application where performance is not an issue, but I would never want to encourage any CPAN module author to do this. In fact, in this thread on perl.module-authors, http://groups.google.com/group/perl.module-authors/msg/ cbd5a168d5d780a8?hl=en& it was suggested that even the usual "fast" $log->is_debug() check is too much of a hit. So I proposed we export a live $log_is_debug variable that would change dynamically to reflect the current level. I suppose one could combine the syntaxes: DEBUG "Current arguments: " . Dumper(\@_) if $log_is_debug; but at this point you are only saving 6 characters or so. > > One thing to watch out for is performance. People don't want > their applications to slow down just because a module has a > logging capability. Exactly my point above. :) Thanks for your positive feedback! I will definitely need to have the support of major logging frameworks such as log4perl for this module to be a success. Best, Jon |
From: Mike S. <m...@pe...> - 2007-09-09 06:11:28
|
On Sat, 8 Sep 2007, Jonathan Swartz wrote: > Did you see this in the posting? > > As a convenient shorthand, you can use > > package Foo; > use Log::Abstract qw($log); > > to create the logger, which is equivalent to the first example > except that $log is > (necessarily) a package-scoped rather than lexical variable. > > So this creates a logger for you with the category set to the current > package, similar to easy mode. The syntax is pretty minimal. Ah, gotcha. So you would call $log->debug(...) instead of DEBUG "..." which is probably acceptable in terms of additional key strokes (although it might throw off novices). > The problem I have with the DEBUG etc keywords is that they promote >inefficient behavior. e.g. > > DEBUG "Current arguments: " . Dumper(\@_); > > will take the performance hit for Dumper() even when debug logging > isn't turned on. Sure, although I don't see how $log->debug("Current arguments: " . Dumper(\@_)); is any different. By the way, in Log4perl you can pass a subroutine ref to the method, which eliminates the problem: DEBUG sub { "Current arguments: " . Dumper(\@_) }; Efficient, but ugly :). While you're at it, here's my pipe dream: I want something like Dtrace, where the logging framework zeroes out the opcodes that are currently inactive, and the interpreter rushes through them at light speed with practically no overhead. -- Mike Mike Schilli m...@pe... |
From: Jim C. <jim...@gm...> - 2007-09-10 22:06:16
|
Mike Schilli wrote: > > While you're at it, here's my pipe dream: I want something like Dtrace, > where the logging framework zeroes out the opcodes that are currently > inactive, and the interpreter rushes through them at light speed with > practically no overhead. > > -- Mike > This sounds like what I did with Log4perl::AutoCategorize, ( which is unsupportable - due to breakage of B::Generate ) FWIW, it hacked the optree to cause an AUTOLOAD fn to instantiate a different sub for every call-point. that new sub could be customized for to the way the config applied to that call-point, thus inlining all the config decisions. Assuming B::Generate comes back to life (there is hope yet), it will be practical to truly no-op the call. |
From: Jonathan S. <sw...@po...> - 2007-09-10 22:53:29
|
>> The problem I have with the DEBUG etc keywords is that they promote >> inefficient behavior. e.g. >> >> DEBUG "Current arguments: " . Dumper(\@_); >> >> will take the performance hit for Dumper() even when debug logging >> isn't turned on. > > Sure, although I don't see how > > $log->debug("Current arguments: " . Dumper(\@_)); > > is any different. It isn't different, by itself, but it translates naturally into $log->debug("Current arguments: " . Dumper(\@_)) if $log->is_debug; whereas if you start off in easy mode, you don't have any way to get at the logger (as far as I can tell). > By the way, in Log4perl you can pass a subroutine ref > to the method, which eliminates the problem: > > DEBUG sub { "Current arguments: " . Dumper(\@_) }; > Right, I forgot about the subroutine syntax. I do think that is a little harder for novices, and a little more expensive, than the conditional (especially when the conditional is against a simple scalar). To be honest I have other problems with porting the DEBUG etc keywords into a generic, universally acceptable API. The all-caps is not in line with Perl standards, and it interferes with Carp::Assert's DEBUG. It also introduces a second, less-powerful API that isn't trivial to convert to the primary API when you need more features. IMHO it is better to just provide users with an easy way to create the default logger, and then maintain a single powerful OO API. My two cents. Jon |
From: Mike S. <m...@pe...> - 2007-09-11 05:37:44
|
On Mon, 10 Sep 2007, Jonathan Swartz wrote: > It isn't different, by itself, but it translates naturally into > > $log->debug("Current arguments: " . Dumper(\@_)) if $log->is_debug; > > whereas if you start off in easy mode, you don't have any way to get > at the logger (as far as I can tell). get_logger() without arguments defaults to the current package: DEBUG "Current arguments: " . Dumper(\@_) if get_logger()->is_debug; But I agree that that's a stretch. We could export IS_DEBUG(), but it hasn't come up yet, so I assume people don't stumble over it often. > > By the way, in Log4perl you can pass a subroutine ref to the method, > > which eliminates the problem: > > > > DEBUG sub { "Current arguments: " . Dumper(\@_) }; > > > > Right, I forgot about the subroutine syntax. I do think that is a > little harder for novices, and a little more expensive, than the > conditional (especially when the conditional is against a simple > scalar). Interesting. Have you benchmarked it? > To be honest I have other problems with porting the DEBUG etc > keywords into a generic, universally acceptable API. > The all-caps is not in line with Perl standards, Clearly, you could argue either way. I like it :). > and it interferes with > Carp::Assert's DEBUG. Clearly, an API like this will clash with one module or another. >It also introduces a second, less-powerful API that isn't trivial to >convert to the primary API when you need more features. IMHO it is >better to just provide users with an easy way to create the default >logger, and then maintain a single powerful OO API. My two cents. I disagree. Easy things should be easy, hard things possible. Sounds familiar? :) -- Mike Mike Schilli m...@pe... |