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->() };
132 sub DlogS_trace (&$) {
136 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
141 sub Dlog_debug (&@) {
145 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
149 sub DlogS_debug (&$) {
153 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
162 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
166 sub DlogS_info (&$) {
170 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
179 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
183 sub DlogS_warn (&$) {
187 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
192 sub Dlog_error (&@) {
196 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
200 sub DlogS_error (&$) {
204 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
209 sub Dlog_fatal (&@) {
213 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
217 sub DlogS_fatal (&$) {
221 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
232 Log::Contextual - Simple logging interface with a contextual log
237 use Log::Contextual qw( :log :dlog set_logger with_logger );
239 my $logger = sub { Log::Log4perl->get_logger };
241 set_logger { $logger };
243 log_debug { 'program started' };
246 with_logger(Log::Contextual::SimpleLogger->new({
247 levels => [qw( trace debug )]
249 log_trace { 'foo entered' };
250 my ($foo, $bar) = Dlog_trace { "params for foo: $_" } @_;
252 log_trace { 'foo left' };
258 This module is a simple interface to extensible logging. It is bundled with a
259 really basic logger, L<Log::Contextual::SimpleLogger>, but in general you
260 should use a real logger instead of that. For something more serious but not
261 overly complicated, take a look at L<Log::Dispatchouli>.
265 When you import this module you may use C<-logger> as a shortcut for
266 L<set_logger>, for example:
268 use Log::Contextual::SimpleLogger;
269 use Log::Contextual qw( :dlog ),
270 -logger => Log::Contextual::SimpleLogger->new({ levels => [qw( debug )] });
272 sometimes you might want to have the logger handy for other stuff, in which
273 case you might try something like the following:
276 BEGIN { $var_log = VarLogger->new }
277 use Log::Contextual qw( :dlog ), -logger => $var_log;
279 =head1 A WORK IN PROGRESS
281 This module is certainly not complete, but we will not break the interface
282 lightly, so I would say it's safe to use in production code. The main result
283 from that at this point is that doing:
287 will die as we do not yet know what the defaults should be. If it turns out
288 that nearly everyone uses the C<:log> tag and C<:dlog> is really rare, we'll
289 probably make C<:log> the default. But only time and usage will tell.
295 my $logger = WarnLogger->new;
298 Arguments: Ref|CodeRef $returning_logger
300 C<set_logger> will just set the current logger to whatever you pass it. It
301 expects a C<CodeRef>, but if you pass it something else it will wrap it in a
306 my $logger = WarnLogger->new;
307 with_logger $logger => sub {
309 log_fatal { 'Non Logical Universe Detected' };
311 log_info { 'All is good' };
315 Arguments: Ref|CodeRef $returning_logger, CodeRef $to_execute
317 C<with_logger> sets the logger for the scope of the C<CodeRef> C<$to_execute>.
318 As with L<set_logger>, C<with_logger> will wrap C<$returning_logger> with a
319 C<CodeRef> if needed.
325 Arguments: CodeRef $returning_message
327 All of the following six functions work the same except that a different method
328 is called on the underlying C<$logger> object. The basic pattern is:
331 if ($logger->is_$level) {
332 $logger->$level(shift->());
338 log_trace { 'entered method foo with args ' join q{,}, @args };
342 log_debug { 'entered method foo' };
346 log_info { 'started process foo' };
350 log_warn { 'possible misconfiguration at line 10' };
354 log_error { 'non-numeric user input!' };
358 log_fatal { '1 is never equal to 0!' };
364 Arguments: CodeRef $returning_message, @args
366 All of the following six functions work the same as their L<log_$level>
367 brethren, except they return what is passed into them and put the stringified
368 (with L<Data::Dumper::Concise>) version of their args into C<$_>. This means
369 you can do cool things like the following:
371 my @nicks = Dlog_debug { "names: $_" } map $_->value, $frew->names->all;
373 and the output might look something like:
383 my ($foo, $bar) = Dlog_trace { "entered method foo with args: $_" } @_;
387 Dlog_debug { "random data structure: $_" } { foo => $bar };
391 return Dlog_info { "html from method returned: $_" } "<html>...</html>";
395 Dlog_warn { "probably invalid value: $_" } $foo;
399 Dlog_error { "non-numeric user input! ($_)" } $port;
403 Dlog_fatal { '1 is never equal to 0!' } 'ZOMG ZOMG' if 1 == 0;
409 Arguments: CodeRef $returning_message, Item $arg
411 All of the following six functions work the same as the related L<Dlog_$level>
412 functions, except they only take a single scalar after the
413 C<$returning_message> instead of slurping up (and also setting C<wantarray>)
416 my $pals_rs = DlogS_debug { "pals resultset: $_" }
417 $schema->resultset('Pals')->search({ perlers => 1 });
422 DlogS_trace { "entered method foo with first arg $_" } $_[0], $_[1];
426 DlogS_debug { "random data structure: $_" } { foo => $bar };
430 return DlogS_info { "html from method returned: $_" } "<html>...</html>";
434 DlogS_warn { "probably invalid value: $_" } $foo;
438 DlogS_error { "non-numeric user input! ($_)" } $port;
442 DlogS_fatal { '1 is never equal to 0!' } 'ZOMG ZOMG' if 1 == 0;
444 =head1 LOGGER INTERFACE
446 Because this module is ultimately pretty looking glue (glittery?) with the
447 awesome benefit of the Contextual part, users will often want to make their
448 favorite logger work with it. The following are the methods that should be
449 implemented in the logger:
464 The first six merely need to return true if that level is enabled. The latter
465 six take the results of whatever the user returned from their coderef and log
466 them. For a basic example see L<Log::Contextual::SimpleLogger>.
470 frew - Arthur Axel "fREW" Schmidt <frioux@gmail.com>
474 mst - Matt S. Trout <mst@shadowcat.co.uk>
478 Copyright (c) 2010 the Log::Contextual L</AUTHOR> and L</DESIGNER> as listed
483 This library is free software and may be distributed under the same terms as