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;
75 my $log = $Get_Logger->();
77 $log->trace($code->(@_))
83 my $log = $Get_Logger->();
85 $log->debug($code->(@_))
91 my $log = $Get_Logger->();
93 $log->info($code->(@_))
99 my $log = $Get_Logger->();
101 $log->warn($code->(@_))
107 my $log = $Get_Logger->();
109 $log->error($code->(@_))
115 my $log = $Get_Logger->();
117 $log->fatal($code->(@_))
124 sub Dlog_trace (&@) {
128 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
133 sub DlogS_trace (&$) {
137 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
142 sub Dlog_debug (&@) {
146 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
151 sub DlogS_debug (&$) {
155 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
164 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
169 sub DlogS_info (&$) {
173 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
182 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
187 sub DlogS_warn (&$) {
191 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
196 sub Dlog_error (&@) {
200 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
205 sub DlogS_error (&$) {
209 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
214 sub Dlog_fatal (&@) {
218 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
223 sub DlogS_fatal (&$) {
227 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
238 Log::Contextual - Simple logging interface with a contextual log
243 use Log::Contextual qw( :log :dlog set_logger with_logger );
245 my $logger = sub { Log::Log4perl->get_logger };
247 set_logger { $logger };
249 log_debug { 'program started' };
252 with_logger(Log::Contextual::SimpleLogger->new({
253 levels => [qw( trace debug )]
255 log_trace { 'foo entered' };
256 my ($foo, $bar) = Dlog_trace { "params for foo: $_" } @_;
258 log_trace { 'foo left' };
264 This module is a simple interface to extensible logging. It is bundled with a
265 really basic logger, L<Log::Contextual::SimpleLogger>, but in general you
266 should use a real logger instead of that. For something more serious but not
267 overly complicated, take a look at L<Log::Dispatchouli>.
271 When you import this module you may use C<-logger> as a shortcut for
272 L<set_logger>, for example:
274 use Log::Contextual::SimpleLogger;
275 use Log::Contextual qw( :dlog ),
276 -logger => Log::Contextual::SimpleLogger->new({ levels => [qw( debug )] });
278 sometimes you might want to have the logger handy for other stuff, in which
279 case you might try something like the following:
282 BEGIN { $var_log = VarLogger->new }
283 use Log::Contextual qw( :dlog ), -logger => $var_log;
285 =head1 A WORK IN PROGRESS
287 This module is certainly not complete, but we will not break the interface
288 lightly, so I would say it's safe to use in production code. The main result
289 from that at this point is that doing:
293 will die as we do not yet know what the defaults should be. If it turns out
294 that nearly everyone uses the C<:log> tag and C<:dlog> is really rare, we'll
295 probably make C<:log> the default. But only time and usage will tell.
301 my $logger = WarnLogger->new;
304 Arguments: Ref|CodeRef $returning_logger
306 C<set_logger> will just set the current logger to whatever you pass it. It
307 expects a C<CodeRef>, but if you pass it something else it will wrap it in a
312 my $logger = WarnLogger->new;
313 with_logger $logger => sub {
315 log_fatal { 'Non Logical Universe Detected' };
317 log_info { 'All is good' };
321 Arguments: Ref|CodeRef $returning_logger, CodeRef $to_execute
323 C<with_logger> sets the logger for the scope of the C<CodeRef> C<$to_execute>.
324 As with L<set_logger>, C<with_logger> will wrap C<$returning_logger> with a
325 C<CodeRef> if needed.
331 Arguments: CodeRef $returning_message
333 All of the following six functions work the same except that a different method
334 is called on the underlying C<$logger> object. The basic pattern is:
337 if ($logger->is_$level) {
338 $logger->$level(shift->());
344 log_trace { 'entered method foo with args ' join q{,}, @args };
348 log_debug { 'entered method foo' };
352 log_info { 'started process foo' };
356 log_warn { 'possible misconfiguration at line 10' };
360 log_error { 'non-numeric user input!' };
364 log_fatal { '1 is never equal to 0!' };
370 Arguments: CodeRef $returning_message, @args
372 All of the following six functions work the same as their L<log_$level>
373 brethren, except they return what is passed into them and put the stringified
374 (with L<Data::Dumper::Concise>) version of their args into C<$_>. This means
375 you can do cool things like the following:
377 my @nicks = Dlog_debug { "names: $_" } map $_->value, $frew->names->all;
379 and the output might look something like:
389 my ($foo, $bar) = Dlog_trace { "entered method foo with args: $_" } @_;
393 Dlog_debug { "random data structure: $_" } { foo => $bar };
397 return Dlog_info { "html from method returned: $_" } "<html>...</html>";
401 Dlog_warn { "probably invalid value: $_" } $foo;
405 Dlog_error { "non-numeric user input! ($_)" } $port;
409 Dlog_fatal { '1 is never equal to 0!' } 'ZOMG ZOMG' if 1 == 0;
415 Arguments: CodeRef $returning_message, Item $arg
417 All of the following six functions work the same as the related L<Dlog_$level>
418 functions, except they only take a single scalar after the
419 C<$returning_message> instead of slurping up (and also setting C<wantarray>)
422 my $pals_rs = DlogS_debug { "pals resultset: $_" }
423 $schema->resultset('Pals')->search({ perlers => 1 });
428 DlogS_trace { "entered method foo with first arg $_" } $_[0], $_[1];
432 DlogS_debug { "random data structure: $_" } { foo => $bar };
436 return DlogS_info { "html from method returned: $_" } "<html>...</html>";
440 DlogS_warn { "probably invalid value: $_" } $foo;
444 DlogS_error { "non-numeric user input! ($_)" } $port;
448 DlogS_fatal { '1 is never equal to 0!' } 'ZOMG ZOMG' if 1 == 0;
450 =head1 LOGGER INTERFACE
452 Because this module is ultimately pretty looking glue (glittery?) with the
453 awesome benefit of the Contextual part, users will often want to make their
454 favorite logger work with it. The following are the methods that should be
455 implemented in the logger:
470 The first six merely need to return true if that level is enabled. The latter
471 six take the results of whatever the user returned from their coderef and log
472 them. For a basic example see L<Log::Contextual::SimpleLogger>.
476 frew - Arthur Axel "fREW" Schmidt <frioux@gmail.com>
480 mst - Matt S. Trout <mst@shadowcat.co.uk>
484 Copyright (c) 2010 the Log::Contextual L</AUTHOR> and L</DESIGNER> as listed
489 This library is free software and may be distributed under the same terms as