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->();
76 $log->trace($_[0]->())
81 my $log = $Get_Logger->();
82 $log->debug($_[0]->())
87 my $log = $Get_Logger->();
93 my $log = $Get_Logger->();
99 my $log = $Get_Logger->();
100 $log->error($_[0]->())
105 my $log = $Get_Logger->();
106 $log->fatal($_[0]->())
112 sub Dlog_trace (&@) {
116 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
121 sub DlogS_trace (&$) {
125 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
130 sub Dlog_debug (&@) {
134 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
139 sub DlogS_debug (&$) {
143 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
152 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
157 sub DlogS_info (&$) {
161 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
170 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
175 sub DlogS_warn (&$) {
179 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
184 sub Dlog_error (&@) {
188 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
193 sub DlogS_error (&$) {
197 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
202 sub Dlog_fatal (&@) {
206 do { local $_ = Data::Dumper::Concise::Dumper @values; $code->() };
211 sub DlogS_fatal (&$) {
215 do { local $_ = Data::Dumper::Concise::Dumper $value; $code->() };
226 Log::Contextual - Simple logging interface with a contextual log
231 use Log::Contextual qw( :log :dlog set_logger with_logger );
233 my $logger = sub { Log::Log4perl->get_logger };
235 set_logger { $logger };
237 log_debug { 'program started' };
240 with_logger(Log::Contextual::SimpleLogger->new({
241 levels => [qw( trace debug )]
243 log_trace { 'foo entered' };
244 my ($foo, $bar) = Dlog_trace { "params for foo: $_" } @_;
246 log_trace { 'foo left' };
252 This module is a simple interface to extensible logging. It is bundled with a
253 really basic logger, L<Log::Contextual::SimpleLogger>, but in general you
254 should use a real logger instead of that. For something more serious but not
255 overly complicated, take a look at L<Log::Dispatchouli>.
259 When you import this module you may use C<-logger> as a shortcut for
260 L<set_logger>, for example:
262 use Log::Contextual::SimpleLogger;
263 use Log::Contextual qw( :dlog ),
264 -logger => Log::Contextual::SimpleLogger->new({ levels => [qw( debug )] });
266 sometimes you might want to have the logger handy for other stuff, in which
267 case you might try something like the following:
270 BEGIN { $var_log = VarLogger->new }
271 use Log::Contextual qw( :dlog ), -logger => $var_log;
273 =head1 A WORK IN PROGRESS
275 This module is certainly not complete, but we will not break the interface
276 lightly, so I would say it's safe to use in production code. The main result
277 from that at this point is that doing:
281 will die as we do not yet know what the defaults should be. If it turns out
282 that nearly everyone uses the C<:log> tag and C<:dlog> is really rare, we'll
283 probably make C<:log> the default. But only time and usage will tell.
289 my $logger = WarnLogger->new;
292 Arguments: Ref|CodeRef $returning_logger
294 C<set_logger> will just set the current logger to whatever you pass it. It
295 expects a C<CodeRef>, but if you pass it something else it will wrap it in a
300 my $logger = WarnLogger->new;
301 with_logger $logger => sub {
303 log_fatal { 'Non Logical Universe Detected' };
305 log_info { 'All is good' };
309 Arguments: Ref|CodeRef $returning_logger, CodeRef $to_execute
311 C<with_logger> sets the logger for the scope of the C<CodeRef> C<$to_execute>.
312 As with L<set_logger>, C<with_logger> will wrap C<$returning_logger> with a
313 C<CodeRef> if needed.
319 Arguments: CodeRef $returning_message
321 All of the following six functions work the same except that a different method
322 is called on the underlying C<$logger> object. The basic pattern is:
325 if ($logger->is_$level) {
326 $logger->$level(shift->());
332 log_trace { 'entered method foo with args ' join q{,}, @args };
336 log_debug { 'entered method foo' };
340 log_info { 'started process foo' };
344 log_warn { 'possible misconfiguration at line 10' };
348 log_error { 'non-numeric user input!' };
352 log_fatal { '1 is never equal to 0!' };
358 Arguments: CodeRef $returning_message, @args
360 All of the following six functions work the same as their L<log_$level>
361 brethren, except they return what is passed into them and put the stringified
362 (with L<Data::Dumper::Concise>) version of their args into C<$_>. This means
363 you can do cool things like the following:
365 my @nicks = Dlog_debug { "names: $_" } map $_->value, $frew->names->all;
367 and the output might look something like:
377 my ($foo, $bar) = Dlog_trace { "entered method foo with args: $_" } @_;
381 Dlog_debug { "random data structure: $_" } { foo => $bar };
385 return Dlog_info { "html from method returned: $_" } "<html>...</html>";
389 Dlog_warn { "probably invalid value: $_" } $foo;
393 Dlog_error { "non-numeric user input! ($_)" } $port;
397 Dlog_fatal { '1 is never equal to 0!' } 'ZOMG ZOMG' if 1 == 0;
403 Arguments: CodeRef $returning_message, Item $arg
405 All of the following six functions work the same as the related L<Dlog_$level>
406 functions, except they only take a single scalar after the
407 C<$returning_message> instead of slurping up (and also setting C<wantarray>)
410 my $pals_rs = DlogS_debug { "pals resultset: $_" }
411 $schema->resultset('Pals')->search({ perlers => 1 });
416 DlogS_trace { "entered method foo with first arg $_" } $_[0], $_[1];
420 DlogS_debug { "random data structure: $_" } { foo => $bar };
424 return DlogS_info { "html from method returned: $_" } "<html>...</html>";
428 DlogS_warn { "probably invalid value: $_" } $foo;
432 DlogS_error { "non-numeric user input! ($_)" } $port;
436 DlogS_fatal { '1 is never equal to 0!' } 'ZOMG ZOMG' if 1 == 0;
438 =head1 LOGGER INTERFACE
440 Because this module is ultimately pretty looking glue (glittery?) with the
441 awesome benefit of the Contextual part, users will often want to make their
442 favorite logger work with it. The following are the methods that should be
443 implemented in the logger:
458 The first six merely need to return true if that level is enabled. The latter
459 six take the results of whatever the user returned from their coderef and log
460 them. For a basic example see L<Log::Contextual::SimpleLogger>.
464 frew - Arthur Axel "fREW" Schmidt <frioux@gmail.com>
468 mst - Matt S. Trout <mst@shadowcat.co.uk>
472 Copyright (c) 2010 the Log::Contextual L</AUTHOR> and L</DESIGNER> as listed
477 This library is free software and may be distributed under the same terms as