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: 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: 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: CodeRef $returning_message
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:
408 if ($logger->is_$level) {
409 $logger->$level(shift->());
415 log_trace { 'entered method foo with args ' join q{,}, @args };
419 log_debug { 'entered method foo' };
423 log_info { 'started process foo' };
427 log_warn { 'possible misconfiguration at line 10' };
431 log_error { 'non-numeric user input!' };
435 log_fatal { '1 is never equal to 0!' };
441 Arguments: CodeRef $returning_message, @args
443 All of the following six functions work the same as their L<log_$level>
444 brethren, except they return what is passed into them and put the stringified
445 (with L<Data::Dumper::Concise>) version of their args into C<$_>. This means
446 you can do cool things like the following:
448 my @nicks = Dlog_debug { "names: $_" } map $_->value, $frew->names->all;
450 and the output might look something like:
460 my ($foo, $bar) = Dlog_trace { "entered method foo with args: $_" } @_;
464 Dlog_debug { "random data structure: $_" } { foo => $bar };
468 return Dlog_info { "html from method returned: $_" } "<html>...</html>";
472 Dlog_warn { "probably invalid value: $_" } $foo;
476 Dlog_error { "non-numeric user input! ($_)" } $port;
480 Dlog_fatal { '1 is never equal to 0!' } 'ZOMG ZOMG' if 1 == 0;
486 Arguments: CodeRef $returning_message, Item $arg
488 All of the following six functions work the same as the related L<Dlog_$level>
489 functions, except they only take a single scalar after the
490 C<$returning_message> instead of slurping up (and also setting C<wantarray>)
493 my $pals_rs = DlogS_debug { "pals resultset: $_" }
494 $schema->resultset('Pals')->search({ perlers => 1 });
499 DlogS_trace { "entered method foo with first arg $_" } $_[0], $_[1];
503 DlogS_debug { "random data structure: $_" } { foo => $bar };
507 return DlogS_info { "html from method returned: $_" } "<html>...</html>";
511 DlogS_warn { "probably invalid value: $_" } $foo;
515 DlogS_error { "non-numeric user input! ($_)" } $port;
519 DlogS_fatal { '1 is never equal to 0!' } 'ZOMG ZOMG' if 1 == 0;
521 =head1 LOGGER INTERFACE
523 Because this module is ultimately pretty looking glue (glittery?) with the
524 awesome benefit of the Contextual part, users will often want to make their
525 favorite logger work with it. The following are the methods that should be
526 implemented in the logger:
541 The first six merely need to return true if that level is enabled. The latter
542 six take the results of whatever the user returned from their coderef and log
543 them. For a basic example see L<Log::Contextual::SimpleLogger>.
547 frew - Arthur Axel "fREW" Schmidt <frioux@gmail.com>
551 mst - Matt S. Trout <mst@shadowcat.co.uk>
555 Copyright (c) 2010 the Log::Contextual L</AUTHOR> and L</DESIGNER> as listed
560 This library is free software and may be distributed under the same terms as