1 package Log::Contextual;
6 our $VERSION = '0.00100';
9 use Data::Dumper::Concise;
11 BEGIN { our @ISA = qw(Exporter) }
14 Dlog_debug DlogS_debug
15 Dlog_trace DlogS_trace
18 Dlog_error DlogS_error
19 Dlog_fatal DlogS_fatal
33 qw( set_logger with_logger )
44 die 'Log::Contextual does not have a default import list'
47 for my $idx ( 0 .. $#_ ) {
48 if ( $_[$idx] eq '-logger' ) {
49 set_logger($_[$idx + 1]);
54 $package->export_to_level(1, $package, @_);
61 $logger = do { my $l = $logger; sub { $l } }
62 if ref $logger ne 'CODE';
63 $Get_Logger = $logger;
68 $logger = do { my $l = $logger; sub { $l } }
69 if ref $logger ne 'CODE';
70 local $Get_Logger = $logger;
77 my $log = $Get_Logger->();
79 $log->trace($code->(@_))
85 my $log = $Get_Logger->();
87 $log->debug($code->(@_))
93 my $log = $Get_Logger->();
95 $log->info($code->(@_))
101 my $log = $Get_Logger->();
103 $log->warn($code->(@_))
109 my $log = $Get_Logger->();
111 $log->error($code->(@_))
117 my $log = $Get_Logger->();
119 $log->fatal($code->(@_))
125 sub logS_trace (&$) {
126 my $log = $Get_Logger->();
129 $log->trace($code->($value))
134 sub logS_debug (&$) {
135 my $log = $Get_Logger->();
138 $log->debug($code->($value))
144 my $log = $Get_Logger->();
147 $log->info($code->($value))
153 my $log = $Get_Logger->();
156 $log->warn($code->($value))
161 sub logS_error (&$) {
162 my $log = $Get_Logger->();
165 $log->error($code->($value))
170 sub logS_fatal (&$) {
171 my $log = $Get_Logger->();
174 $log->fatal($code->($value))
181 sub Dlog_trace (&@) {
185 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
189 sub Dlog_debug (&@) {
193 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
201 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
209 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
213 sub Dlog_error (&@) {
217 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
221 sub Dlog_fatal (&@) {
225 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
231 sub DlogS_trace (&$) {
235 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
239 sub DlogS_debug (&$) {
243 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
247 sub DlogS_info (&$) {
251 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
255 sub DlogS_warn (&$) {
259 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
263 sub DlogS_error (&$) {
267 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
271 sub DlogS_fatal (&$) {
275 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
285 Log::Contextual - Simple logging interface with a contextual log
290 use Log::Contextual qw( :log :dlog set_logger with_logger );
292 my $logger = sub { Log::Log4perl->get_logger };
294 set_logger { $logger };
296 log_debug { 'program started' };
299 with_logger(Log::Contextual::SimpleLogger->new({
300 levels => [qw( trace debug )]
302 log_trace { 'foo entered' };
303 my ($foo, $bar) = Dlog_trace { "params for foo: $_" } @_;
305 log_trace { 'foo left' };
311 This module is a simple interface to extensible logging. It is bundled with a
312 really basic logger, L<Log::Contextual::SimpleLogger>, but in general you
313 should use a real logger instead of that. For something more serious but not
314 overly complicated, take a look at L<Log::Dispatchouli>.
318 When you import this module you may use C<-logger> as a shortcut for
319 L<set_logger>, for example:
321 use Log::Contextual::SimpleLogger;
322 use Log::Contextual qw( :dlog ),
323 -logger => Log::Contextual::SimpleLogger->new({ levels => [qw( debug )] });
325 sometimes you might want to have the logger handy for other stuff, in which
326 case you might try something like the following:
329 BEGIN { $var_log = VarLogger->new }
330 use Log::Contextual qw( :dlog ), -logger => $var_log;
332 =head1 A WORK IN PROGRESS
334 This module is certainly not complete, but we will not break the interface
335 lightly, so I would say it's safe to use in production code. The main result
336 from that at this point is that doing:
340 will die as we do not yet know what the defaults should be. If it turns out
341 that nearly everyone uses the C<:log> tag and C<:dlog> is really rare, we'll
342 probably make C<:log> the default. But only time and usage will tell.
348 my $logger = WarnLogger->new;
351 Arguments: Ref|CodeRef $returning_logger
353 C<set_logger> will just set the current logger to whatever you pass it. It
354 expects a C<CodeRef>, but if you pass it something else it will wrap it in a
359 my $logger = WarnLogger->new;
360 with_logger $logger => sub {
362 log_fatal { 'Non Logical Universe Detected' };
364 log_info { 'All is good' };
368 Arguments: Ref|CodeRef $returning_logger, CodeRef $to_execute
370 C<with_logger> sets the logger for the scope of the C<CodeRef> C<$to_execute>.
371 As with L<set_logger>, C<with_logger> will wrap C<$returning_logger> with a
372 C<CodeRef> if needed.
378 Arguments: CodeRef $returning_message
380 All of the following six functions work the same except that a different method
381 is called on the underlying C<$logger> object. The basic pattern is:
384 if ($logger->is_$level) {
385 $logger->$level(shift->());
391 log_trace { 'entered method foo with args ' join q{,}, @args };
395 log_debug { 'entered method foo' };
399 log_info { 'started process foo' };
403 log_warn { 'possible misconfiguration at line 10' };
407 log_error { 'non-numeric user input!' };
411 log_fatal { '1 is never equal to 0!' };
417 Arguments: CodeRef $returning_message, @args
419 All of the following six functions work the same as their L<log_$level>
420 brethren, except they return what is passed into them and put the stringified
421 (with L<Data::Dumper::Concise>) version of their args into C<$_>. This means
422 you can do cool things like the following:
424 my @nicks = Dlog_debug { "names: $_" } map $_->value, $frew->names->all;
426 and the output might look something like:
436 my ($foo, $bar) = Dlog_trace { "entered method foo with args: $_" } @_;
440 Dlog_debug { "random data structure: $_" } { foo => $bar };
444 return Dlog_info { "html from method returned: $_" } "<html>...</html>";
448 Dlog_warn { "probably invalid value: $_" } $foo;
452 Dlog_error { "non-numeric user input! ($_)" } $port;
456 Dlog_fatal { '1 is never equal to 0!' } 'ZOMG ZOMG' if 1 == 0;
462 Arguments: CodeRef $returning_message, Item $arg
464 All of the following six functions work the same as the related L<Dlog_$level>
465 functions, except they only take a single scalar after the
466 C<$returning_message> instead of slurping up (and also setting C<wantarray>)
469 my $pals_rs = DlogS_debug { "pals resultset: $_" }
470 $schema->resultset('Pals')->search({ perlers => 1 });
475 DlogS_trace { "entered method foo with first arg $_" } $_[0], $_[1];
479 DlogS_debug { "random data structure: $_" } { foo => $bar };
483 return DlogS_info { "html from method returned: $_" } "<html>...</html>";
487 DlogS_warn { "probably invalid value: $_" } $foo;
491 DlogS_error { "non-numeric user input! ($_)" } $port;
495 DlogS_fatal { '1 is never equal to 0!' } 'ZOMG ZOMG' if 1 == 0;
497 =head1 LOGGER INTERFACE
499 Because this module is ultimately pretty looking glue (glittery?) with the
500 awesome benefit of the Contextual part, users will often want to make their
501 favorite logger work with it. The following are the methods that should be
502 implemented in the logger:
517 The first six merely need to return true if that level is enabled. The latter
518 six take the results of whatever the user returned from their coderef and log
519 them. For a basic example see L<Log::Contextual::SimpleLogger>.
523 frew - Arthur Axel "fREW" Schmidt <frioux@gmail.com>
527 mst - Matt S. Trout <mst@shadowcat.co.uk>
531 Copyright (c) 2010 the Log::Contextual L</AUTHOR> and L</DESIGNER> as listed
536 This library is free software and may be distributed under the same terms as