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->(@_))
126 sub Dlog_trace (&@) {
130 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
134 sub Dlog_debug (&@) {
138 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
146 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
154 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
158 sub Dlog_error (&@) {
162 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
166 sub Dlog_fatal (&@) {
170 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
176 sub DlogS_trace (&$) {
180 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
185 sub DlogS_debug (&$) {
189 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
194 sub DlogS_info (&$) {
198 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
203 sub DlogS_warn (&$) {
207 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
212 sub DlogS_error (&$) {
216 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
221 sub DlogS_fatal (&$) {
225 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
236 Log::Contextual - Simple logging interface with a contextual log
241 use Log::Contextual qw( :log :dlog set_logger with_logger );
243 my $logger = sub { Log::Log4perl->get_logger };
245 set_logger { $logger };
247 log_debug { 'program started' };
250 with_logger(Log::Contextual::SimpleLogger->new({
251 levels => [qw( trace debug )]
253 log_trace { 'foo entered' };
254 my ($foo, $bar) = Dlog_trace { "params for foo: $_" } @_;
256 log_trace { 'foo left' };
262 This module is a simple interface to extensible logging. It is bundled with a
263 really basic logger, L<Log::Contextual::SimpleLogger>, but in general you
264 should use a real logger instead of that. For something more serious but not
265 overly complicated, take a look at L<Log::Dispatchouli>.
269 When you import this module you may use C<-logger> as a shortcut for
270 L<set_logger>, for example:
272 use Log::Contextual::SimpleLogger;
273 use Log::Contextual qw( :dlog ),
274 -logger => Log::Contextual::SimpleLogger->new({ levels => [qw( debug )] });
276 sometimes you might want to have the logger handy for other stuff, in which
277 case you might try something like the following:
280 BEGIN { $var_log = VarLogger->new }
281 use Log::Contextual qw( :dlog ), -logger => $var_log;
283 =head1 A WORK IN PROGRESS
285 This module is certainly not complete, but we will not break the interface
286 lightly, so I would say it's safe to use in production code. The main result
287 from that at this point is that doing:
291 will die as we do not yet know what the defaults should be. If it turns out
292 that nearly everyone uses the C<:log> tag and C<:dlog> is really rare, we'll
293 probably make C<:log> the default. But only time and usage will tell.
299 my $logger = WarnLogger->new;
302 Arguments: Ref|CodeRef $returning_logger
304 C<set_logger> will just set the current logger to whatever you pass it. It
305 expects a C<CodeRef>, but if you pass it something else it will wrap it in a
310 my $logger = WarnLogger->new;
311 with_logger $logger => sub {
313 log_fatal { 'Non Logical Universe Detected' };
315 log_info { 'All is good' };
319 Arguments: Ref|CodeRef $returning_logger, CodeRef $to_execute
321 C<with_logger> sets the logger for the scope of the C<CodeRef> C<$to_execute>.
322 As with L<set_logger>, C<with_logger> will wrap C<$returning_logger> with a
323 C<CodeRef> if needed.
329 Arguments: CodeRef $returning_message
331 All of the following six functions work the same except that a different method
332 is called on the underlying C<$logger> object. The basic pattern is:
335 if ($logger->is_$level) {
336 $logger->$level(shift->());
342 log_trace { 'entered method foo with args ' join q{,}, @args };
346 log_debug { 'entered method foo' };
350 log_info { 'started process foo' };
354 log_warn { 'possible misconfiguration at line 10' };
358 log_error { 'non-numeric user input!' };
362 log_fatal { '1 is never equal to 0!' };
368 Arguments: CodeRef $returning_message, @args
370 All of the following six functions work the same as their L<log_$level>
371 brethren, except they return what is passed into them and put the stringified
372 (with L<Data::Dumper::Concise>) version of their args into C<$_>. This means
373 you can do cool things like the following:
375 my @nicks = Dlog_debug { "names: $_" } map $_->value, $frew->names->all;
377 and the output might look something like:
387 my ($foo, $bar) = Dlog_trace { "entered method foo with args: $_" } @_;
391 Dlog_debug { "random data structure: $_" } { foo => $bar };
395 return Dlog_info { "html from method returned: $_" } "<html>...</html>";
399 Dlog_warn { "probably invalid value: $_" } $foo;
403 Dlog_error { "non-numeric user input! ($_)" } $port;
407 Dlog_fatal { '1 is never equal to 0!' } 'ZOMG ZOMG' if 1 == 0;
413 Arguments: CodeRef $returning_message, Item $arg
415 All of the following six functions work the same as the related L<Dlog_$level>
416 functions, except they only take a single scalar after the
417 C<$returning_message> instead of slurping up (and also setting C<wantarray>)
420 my $pals_rs = DlogS_debug { "pals resultset: $_" }
421 $schema->resultset('Pals')->search({ perlers => 1 });
426 DlogS_trace { "entered method foo with first arg $_" } $_[0], $_[1];
430 DlogS_debug { "random data structure: $_" } { foo => $bar };
434 return DlogS_info { "html from method returned: $_" } "<html>...</html>";
438 DlogS_warn { "probably invalid value: $_" } $foo;
442 DlogS_error { "non-numeric user input! ($_)" } $port;
446 DlogS_fatal { '1 is never equal to 0!' } 'ZOMG ZOMG' if 1 == 0;
448 =head1 LOGGER INTERFACE
450 Because this module is ultimately pretty looking glue (glittery?) with the
451 awesome benefit of the Contextual part, users will often want to make their
452 favorite logger work with it. The following are the methods that should be
453 implemented in the logger:
468 The first six merely need to return true if that level is enabled. The latter
469 six take the results of whatever the user returned from their coderef and log
470 them. For a basic example see L<Log::Contextual::SimpleLogger>.
474 frew - Arthur Axel "fREW" Schmidt <frioux@gmail.com>
478 mst - Matt S. Trout <mst@shadowcat.co.uk>
482 Copyright (c) 2010 the Log::Contextual L</AUTHOR> and L</DESIGNER> as listed
487 This library is free software and may be distributed under the same terms as