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 (&@) {
186 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
188 do { local $_ = '()'; $code->() };
193 sub Dlog_debug (&@) {
198 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
200 do { local $_ = '()'; $code->() };
210 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
212 do { local $_ = '()'; $code->() };
222 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
224 do { local $_ = '()'; $code->() };
229 sub Dlog_error (&@) {
234 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
236 do { local $_ = '()'; $code->() };
241 sub Dlog_fatal (&@) {
246 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
248 do { local $_ = '()'; $code->() };
255 sub DlogS_trace (&$) {
259 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
263 sub DlogS_debug (&$) {
267 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
271 sub DlogS_info (&$) {
275 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
279 sub DlogS_warn (&$) {
283 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
287 sub DlogS_error (&$) {
291 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
295 sub DlogS_fatal (&$) {
299 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
309 Log::Contextual - Simple logging interface with a contextual log
314 use Log::Contextual qw( :log :dlog set_logger with_logger );
316 my $logger = sub { Log::Log4perl->get_logger };
318 set_logger { $logger };
320 log_debug { 'program started' };
323 with_logger(Log::Contextual::SimpleLogger->new({
324 levels => [qw( trace debug )]
326 log_trace { 'foo entered' };
327 my ($foo, $bar) = Dlog_trace { "params for foo: $_" } @_;
329 log_trace { 'foo left' };
335 This module is a simple interface to extensible logging. It is bundled with a
336 really basic logger, L<Log::Contextual::SimpleLogger>, but in general you
337 should use a real logger instead of that. For something more serious but not
338 overly complicated, take a look at L<Log::Dispatchouli>.
342 When you import this module you may use C<-logger> as a shortcut for
343 L<set_logger>, for example:
345 use Log::Contextual::SimpleLogger;
346 use Log::Contextual qw( :dlog ),
347 -logger => Log::Contextual::SimpleLogger->new({ levels => [qw( debug )] });
349 sometimes you might want to have the logger handy for other stuff, in which
350 case you might try something like the following:
353 BEGIN { $var_log = VarLogger->new }
354 use Log::Contextual qw( :dlog ), -logger => $var_log;
356 =head1 A WORK IN PROGRESS
358 This module is certainly not complete, but we will not break the interface
359 lightly, so I would say it's safe to use in production code. The main result
360 from that at this point is that doing:
364 will die as we do not yet know what the defaults should be. If it turns out
365 that nearly everyone uses the C<:log> tag and C<:dlog> is really rare, we'll
366 probably make C<:log> the default. But only time and usage will tell.
372 my $logger = WarnLogger->new;
375 Arguments: C<Ref|CodeRef $returning_logger>
377 C<set_logger> will just set the current logger to whatever you pass it. It
378 expects a C<CodeRef>, but if you pass it something else it will wrap it in a
383 my $logger = WarnLogger->new;
384 with_logger $logger => sub {
386 log_fatal { 'Non Logical Universe Detected' };
388 log_info { 'All is good' };
392 Arguments: C<Ref|CodeRef $returning_logger, CodeRef $to_execute>
394 C<with_logger> sets the logger for the scope of the C<CodeRef> C<$to_execute>.
395 As with L</set_logger>, C<with_logger> will wrap C<$returning_logger> with a
396 C<CodeRef> if needed.
402 Arguments: C<CodeRef $returning_message, @args>
404 All of the following six functions work the same except that a different method
405 is called on the underlying C<$logger> object. The basic pattern is:
407 sub log_$level (&@) {
408 if ($logger->is_$level) {
409 $logger->$level(shift->(@_));
414 Note that the function returns it's arguments. This can be used in a number of
415 ways, but often it's convenient just for partial inspection of passthrough data
417 my @friends = log_trace {
418 'friends list being generated, data from first friend: ' .
419 Dumper($_[0]->TO_JSON)
420 } generate_friend_list();
422 If you want complete inspection of passthrough data, take a look at the
423 L</Dlog_$level> functions.
427 log_trace { 'entered method foo with args ' join q{,}, @args };
431 log_debug { 'entered method foo' };
435 log_info { 'started process foo' };
439 log_warn { 'possible misconfiguration at line 10' };
443 log_error { 'non-numeric user input!' };
447 log_fatal { '1 is never equal to 0!' };
453 Arguments: C<CodeRef $returning_message, Item $arg>
455 This is really just a special case of the L</log_$level> functions. It forces
456 scalar context when that is what you need. Other than that it works exactly
459 my $friend = logS_trace {
460 'I only have one friend: ' . Dumper($_[0]->TO_JSON)
463 See also: L</DlogS_$level>.
469 Arguments: C<CodeRef $returning_message, @args>
471 All of the following six functions work the same as their L</log_$level>
472 brethren, except they return what is passed into them and put the stringified
473 (with L<Data::Dumper::Concise>) version of their args into C<$_>. This means
474 you can do cool things like the following:
476 my @nicks = Dlog_debug { "names: $_" } map $_->value, $frew->names->all;
478 and the output might look something like:
488 my ($foo, $bar) = Dlog_trace { "entered method foo with args: $_" } @_;
492 Dlog_debug { "random data structure: $_" } { foo => $bar };
496 return Dlog_info { "html from method returned: $_" } "<html>...</html>";
500 Dlog_warn { "probably invalid value: $_" } $foo;
504 Dlog_error { "non-numeric user input! ($_)" } $port;
508 Dlog_fatal { '1 is never equal to 0!' } 'ZOMG ZOMG' if 1 == 0;
514 Arguments: C<CodeRef $returning_message, Item $arg>
516 Like L</logS_$level>, these functions are a special case of L</Dlog_$level>.
517 They only take a single scalar after the C<$returning_message> instead of
518 slurping up (and also setting C<wantarray>) all the C<@args>
520 my $pals_rs = DlogS_debug { "pals resultset: $_" }
521 $schema->resultset('Pals')->search({ perlers => 1 });
523 =head1 LOGGER INTERFACE
525 Because this module is ultimately pretty looking glue (glittery?) with the
526 awesome benefit of the Contextual part, users will often want to make their
527 favorite logger work with it. The following are the methods that should be
528 implemented in the logger:
543 The first six merely need to return true if that level is enabled. The latter
544 six take the results of whatever the user returned from their coderef and log
545 them. For a basic example see L<Log::Contextual::SimpleLogger>.
549 frew - Arthur Axel "fREW" Schmidt <frioux@gmail.com>
553 mst - Matt S. Trout <mst@shadowcat.co.uk>
557 Copyright (c) 2010 the Log::Contextual L</AUTHOR> and L</DESIGNER> as listed
562 This library is free software and may be distributed under the same terms as