1 package Log::Contextual;
6 our $VERSION = '1.000';
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 - Super simple logging interface
230 use Log::Contextual qw{:log set_logger with_logger};
232 my $logger = Log::Contextual::SimpleLogger->new({ levels => [qw{debug}]});
234 set_logger { $logger };
236 log_debug { "program started" };
239 with_logger Log::Contextual::SimpleLogger->new({
240 levels => [qw{trace debug}]
242 log_trace { 'foo entered' };
244 log_trace { 'foo left' };
250 This module is a simple interface to extensible logging. It is bundled with a
251 really basic logger, L<Log::Contextual::SimpleLogger>, but in general you
252 should use a real logger instead of that. For something more serious but not
253 overly complicated, take a look at L<Log::Dispatchouli>.
257 When you import this module you may use C<-logger> as a shortcut for
258 L<set_logger>, for example:
260 use Log::Contextual::SimpleLogger;
261 use Log::Contextual qw{:dlog},
262 -logger => Log::Contextual::SimpleLogger->new({ levels => [qw{ debug }] });
264 sometimes you might want to have the logger handy for other stuff, in which
265 case you might try something like the following:
268 BEGIN { $var_log = VarLogger->new }
269 use Log::Contextual qw{:dlog}, -logger => $var_log;
271 =head1 A WORK IN PROGRESS
273 This module is certainly not complete, but we will not break the interface
274 lightly, so I would say it's safe to use in production code. The main result
275 from that at this point is that doing:
279 will die as we do not yet know what the defaults should be. If it turns out
280 that nearly everyone uses the C<:log> tag and C<:dlog> is really rare, we'll
281 probably make C<:log> the default. But only time, and usage, will tell.
287 my $logger = WarnLogger->new;
290 Arguments: Ref|CodeRef $returning_logger
292 C<set_logger> will just set the current logger to whatever you pass it. It
293 expects a C<CodeRef>, but if you pass it something else it will wrap it in a
298 my $logger = WarnLogger->new;
299 with_logger $logger => sub {
301 log_fatal { 'Non Logical Universe Detected' };
303 log_info { 'All is good' };
307 Arguments: Ref|CodeRef $returning_logger, CodeRef $to_execute
309 C<with_logger> sets the logger for the scope of the C<CodeRef> C<$to_execute>.
310 as with L<set_logger>, C<with_logger> will wrap C<$returning_logger> with a
311 C<CodeRef> if needed.
317 Arguments: CodeRef $returning_message
319 All of the following six functions work the same except that a different method
320 is called on the underlying C<$logger> object. The basic pattern is:
323 if ($logger->is_$level) {
324 $logger->$level(shift->());
330 log_trace { 'entered method foo with args ' join q{,}, @args };
334 log_debug { 'entered method foo' };
338 log_info { 'started process foo' };
342 log_warn { 'possible misconfiguration at line 10' };
346 log_error { 'non-numeric user input!' };
350 log_fatal { '1 is never equal to 0!' };
356 Arguments: CodeRef $returning_message, @args
358 All of the following six functions work the same as their L<log_$level> brethren,
359 except they return what is passed into them and as a bonus put the stringified
360 (with L<Data::Dumper::Concise>) version of their args into C<$_>. This means
361 you can do cool things like the following:
363 my @nicks = Dlog_debug { "names: $_" } map $_->value, $frew->names->all;
365 and the output might look something like:
375 my ($foo, $bar) = Dlog_trace { "entered method foo with args $_" } @_;
379 Dlog_debug { "random data structure: $_" } { foo => $bar };
383 return Dlog_info { "html from method returned: $_" } "<html>...</html>";
387 Dlog_warn { "probably invalid value: $_" } $foo;
391 Dlog_error { "non-numeric user input! ($_)" } $port;
395 Dlog_fatal { '1 is never equal to 0!' } 'ZOMG ZOMG' if 1 == 0;
401 Arguments: CodeRef $returning_message, Item $arg
403 All of the following six functions work the same as the related L<Dlog_$level>
404 functions, except they only take a single scalar after the
405 C<$returning_message> instead of slurping up (and also setting C<wantarray>)
408 my $pals_rs = DlogS_debug { "pals resultset: $_" }
409 $schema->resultset('Pals')->search({ perlers => 1 });
413 my ($foo, $bar) = DlogS_trace { "entered method foo with first arg $_" } $_[0], $_[1];
417 DlogS_debug { "random data structure: $_" } { foo => $bar };
421 return DlogS_info { "html from method returned: $_" } "<html>...</html>";
425 DlogS_warn { "probably invalid value: $_" } $foo;
429 DlogS_error { "non-numeric user input! ($_)" } $port;
433 DlogS_fatal { '1 is never equal to 0!' } 'ZOMG ZOMG' if 1 == 0;
435 =head1 LOGGER INTERFACE
437 Because this module is ultimately pretty looking glue (glittery?) with the
438 awesome benefit of the Contextual part, users will often want to make their
439 favorite logger work with it. The following are the methods that should be
440 implemented in the logger:
455 The first six merely need to return true if that level is enabled. The latter
456 six take the results of whatever the user returned from their coderef and log
457 them. For a basic example see L<Log::Contextual::SimpleLogger>.
461 frew - Arthur Axel "fREW" Schmidt <frioux@gmail.com>
465 mst - Matt S. Trout <mst@shadowcat.co.uk>
469 Copyright (c) 2010 the Log::Contextual L</AUTHOR> and L</DESIGNER> as listed
474 This library is free software and may be distributed under the same terms as