ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent/lib/AnyEvent/Log.pm
(Generate patch)

Comparing AnyEvent/lib/AnyEvent/Log.pm (file contents):
Revision 1.2 by root, Tue Aug 16 14:47:27 2011 UTC vs.
Revision 1.12 by root, Sat Aug 20 01:33:10 2011 UTC

2 2
3AnyEvent::Log - simple logging "framework" 3AnyEvent::Log - simple logging "framework"
4 4
5=head1 SYNOPSIS 5=head1 SYNOPSIS
6 6
7 # simple use
8 use AnyEvent;
9
10 AE::log debug => "hit my knee";
11 AE::log warn => "it's a bit too hot";
12 AE::log error => "the flag was false!";
13 AE::log fatal => "the bit toggled! run!";
14
15 # "complex" use
7 use AnyEvent::Log; 16 use AnyEvent::Log;
17
18 my $tracer = AnyEvent::Log::logger trace => \$my $trace;
19
20 $tracer->("i am here") if $trace;
21 $tracer->(sub { "lots of data: " . Dumper $self }) if $trace;
22
23 # configuration
24
25 # set logging for this package to maximum
26 AnyEvent::Log::ctx->level ("all");
27
28 # set logging globally to anything below debug
29 (AnyEvent::Log::ctx "")->level ("notice");
30
31 # see also EXAMPLES, below
32
33 # disable logging for package "AnyEvent" and all packages below it
34 AnyEvent->AnyEvent::Log::ctx->level (0);
35
36 # log everything below debug to a file, for the whole program
37 my $ctx = AnyEvent::Log::ctx;
38 $ctx->log_cb (sub { print FILE shift; 0 });
39 (AnyEvent::Log::ctx "")->add ($ctx);
8 40
9=head1 DESCRIPTION 41=head1 DESCRIPTION
10 42
11This module implements a relatively simple "logging framework". It doesn't 43This module implements a relatively simple "logging framework". It doesn't
12attempt to be "the" logging solution or even "a" logging solution for 44attempt to be "the" logging solution or even "a" logging solution for
13AnyEvent - AnyEvent simply creates logging messages internally, and this 45AnyEvent - AnyEvent simply creates logging messages internally, and this
14module more or less exposes the mechanism, with some extra spiff to allow 46module more or less exposes the mechanism, with some extra spiff to allow
15using it from other modules as well. 47using it from other modules as well.
16 48
17Remember that the default verbosity level is C<0>, so nothing 49Remember that the default verbosity level is C<0>, so nothing will be
18will be logged, ever, unless you set C<$Anyvent::VERBOSE> or 50logged, unless you set C<PERL_ANYEVENT_VERBOSE> to a higher number before
19C<PERL_ANYEVENT_VERBOSE> to a higher number. 51starting your program, or change the logging level at runtime with
52something like:
20 53
21Possible future extensions are to allow custom log targets (where the 54 use AnyEvent;
22level is an object), log filtering based on package, formatting, aliasing 55 (AnyEvent::Log::ctx "")->level ("info");
23or package groups.
24 56
57The design goal behind this module was to keep it simple (and small),
58but make it powerful enough to be potentially useful for any module, and
59extensive enough for the most common tasks, such as logging to multiple
60targets, or being able to log into a database.
61
25=head1 LOG FUNCTIONS 62=head1 LOGGING FUNCTIONS
26 63
27These functions allow you to log messages. They always use the caller's 64These functions allow you to log messages. They always use the caller's
28package as a "logging module/source". Also, The main logging function is 65package as a "logging module/source". Also, the main logging function is
29easily available as C<AnyEvent::log> or C<AE::log> when the C<AnyEvent> 66callable as C<AnyEvent::log> or C<AE::log> when the C<AnyEvent> module is
30module is loaded. 67loaded.
31 68
32=over 4 69=over 4
33 70
34=cut 71=cut
35 72
37 74
38use Carp (); 75use Carp ();
39use POSIX (); 76use POSIX ();
40 77
41use AnyEvent (); BEGIN { AnyEvent::common_sense } 78use AnyEvent (); BEGIN { AnyEvent::common_sense }
79use AnyEvent::Util ();
42 80
43our ($now_int, $now_str1, $now_str2); 81our ($now_int, $now_str1, $now_str2);
44 82
45# Format Time, not public - yet? 83# Format Time, not public - yet?
46sub ft($) { 84sub ft($) {
51 if $now_int != $i; 89 if $now_int != $i;
52 90
53 "$now_str1$f$now_str2" 91 "$now_str1$f$now_str2"
54} 92}
55 93
94our %CTX; # all logging contexts
95
96# creates a default package context object for the given package
97sub _pkg_ctx($) {
98 my $ctx = bless [$_[0], (1 << 10) - 1 - 1, {}], "AnyEvent::Log::Ctx";
99
100 # link "parent" package
101 my $pkg = $_[0] =~ /^(.+)::/ ? $1 : "AE::Log::Top";
102
103 $pkg = $CTX{$pkg} ||= &_pkg_ctx ($pkg);
104 $ctx->[2]{$pkg+0} = $pkg;
105
106 $ctx
107}
108
56=item AnyEvent::Log::log $level, $msg[, @args] 109=item AnyEvent::Log::log $level, $msg[, @args]
57 110
58Requests logging of the given C<$msg> with the given log level (1..9). 111Requests logging of the given C<$msg> with the given log level (1..9).
59You can also use the following strings as log level: C<fatal> (1), 112You can also use the following strings as log level: C<fatal> (1),
60C<alert> (2), C<critical> (3), C<error> (4), C<warn> (5), C<note> (6), 113C<alert> (2), C<critical> (3), C<error> (4), C<warn> (5), C<note> (6),
66C<$msg> is interpreted as an sprintf format string. 119C<$msg> is interpreted as an sprintf format string.
67 120
68The C<$msg> should not end with C<\n>, but may if that is convenient for 121The C<$msg> should not end with C<\n>, but may if that is convenient for
69you. Also, multiline messages are handled properly. 122you. Also, multiline messages are handled properly.
70 123
71In addition, for possible future expansion, C<$msg> must not start with an 124Last not least, C<$msg> might be a code reference, in which case it is
72angle bracket (C<< < >>). 125supposed to return the message. It will be called only then the message
126actually gets logged, which is useful if it is costly to create the
127message in the first place.
73 128
74Whether the given message will be logged depends on the maximum log level 129Whether the given message will be logged depends on the maximum log level
75and the caller's package. 130and the caller's package.
76 131
77Note that you can (and should) call this function as C<AnyEvent::log> or 132Note that you can (and should) call this function as C<AnyEvent::log> or
78C<AE::log>, without C<use>-ing this module if possible, as those functions 133C<AE::log>, without C<use>-ing this module if possible (i.e. you don't
79will laod the logging module on demand only. 134need any additional functionality), as those functions will load the
135logging module on demand only. They are also much shorter to write.
136
137Also, if you optionally generate a lot of debug messages (such as when
138tracing some code), you should look into using a logger callback and a
139boolean enabler (see C<logger>, below).
140
141Example: log something at error level.
142
143 AE::log error => "something";
144
145Example: use printf-formatting.
146
147 AE::log info => "%5d %-10.10s %s", $index, $category, $msg;
148
149Example: only generate a costly dump when the message is actually being logged.
150
151 AE::log debug => sub { require Data::Dump; Data::Dump::dump \%cache };
80 152
81=cut 153=cut
82 154
83# also allow syslog equivalent names 155# also allow syslog equivalent names
84our %STR2LEVEL = ( 156our %STR2LEVEL = (
91 info => 7, 163 info => 7,
92 debug => 8, 164 debug => 8,
93 trace => 9, 165 trace => 9,
94); 166);
95 167
168sub now () { time }
169
170AnyEvent::post_detect {
171 *now = \&AE::now;
172};
173
96our @LEVEL2STR = qw(0 fatal alert crit error warn note info debug trace); 174our @LEVEL2STR = qw(0 fatal alert crit error warn note info debug trace);
97 175
176# time, ctx, level, msg
177sub _format($$$$) {
178 my $ts = ft $_[0];
179 my $ct = " ";
180
181 my @res;
182
183 for (split /\n/, sprintf "%-5s %s: %s", $LEVEL2STR[$_[2]], $_[1][0], $_[3]) {
184 push @res, "$ts$ct$_\n";
185 $ct = " + ";
186 }
187
188 join "", @res
189}
190
191sub _log {
192 my ($ctx, $level, $format, @args) = @_;
193
194 $level = $level > 0 && $level <= 9
195 ? $level+0
196 : $STR2LEVEL{$level} || Carp::croak "$level: not a valid logging level, caught";
197
198 my $mask = 1 << $level;
199
200 my (%seen, @ctx, $now, $fmt);
201
202 do
203 {
204 # skip if masked
205 if ($ctx->[1] & $mask && !$seen{$ctx+0}++) {
206 if ($ctx->[3]) {
207 # logging target found
208
209 # now get raw message, unless we have it already
210 unless ($now) {
211 $format = $format->() if ref $format;
212 $format = sprintf $format, @args if @args;
213 $format =~ s/\n$//;
214 $now = AE::now;
215 };
216
217 # format msg
218 my $str = $ctx->[4]
219 ? $ctx->[4]($now, $_[0], $level, $format)
220 : $fmt ||= _format $now, $_[0], $level, $format;
221
222 $ctx->[3]($str);
223 }
224
225 # not masked, not consumed - propagate to parent contexts
226 push @ctx, values %{ $ctx->[2] };
227 }
228 }
229 while $ctx = pop @ctx;
230
231 exit 1 if $level <= 1;
232}
233
98sub log($$;@) { 234sub log($$;@) {
99 my ($targ, $msg, @args) = @_; 235 _log
236 $CTX{ (caller)[0] } ||= _pkg_ctx +(caller)[0],
237 @_;
238}
100 239
101 my $level = ref $targ ? die "Can't use reference as logging level (yet)" 240*AnyEvent::log = *AE::log = \&log;
102 : $targ > 0 && $targ <= 9 ? $targ+0
103 : $STR2LEVEL{$targ} || Carp::croak "$targ: not a valid logging level, caught";
104 241
105 return if $level > $AnyEvent::VERBOSE; 242=item $logger = AnyEvent::Log::logger $level[, \$enabled]
106 243
107 my $pkg = (caller)[0]; 244Creates a code reference that, when called, acts as if the
245C<AnyEvent::Log::log> function was called at this point with the givne
246level. C<$logger> is passed a C<$msg> and optional C<@args>, just as with
247the C<AnyEvent::Log::log> function:
108 248
109 $msg = sprintf $msg, @args if @args; 249 my $debug_log = AnyEvent::Log::logger "debug";
110 $msg =~ s/\n$//;
111 250
112 # now we have a message, log it 251 $debug_log->("debug here");
113 #TODO: could do LOTS of stuff here, and should, at least in some later version 252 $debug_log->("%06d emails processed", 12345);
253 $debug_log->(sub { $obj->as_string });
114 254
115 $msg = sprintf "%5s (%s) %s", $LEVEL2STR[$level], $pkg, $msg; 255The idea behind this function is to decide whether to log before actually
116 my $pfx = ft AE::now; 256logging - when the C<logger> function is called once, but the returned
257logger callback often, then this can be a tremendous speed win.
117 258
118 for (split /\n/, $msg) { 259Despite this speed advantage, changes in logging configuration will
119 printf STDERR "$pfx $_\n"; 260still be reflected by the logger callback, even if configuration changes
120 $pfx = "\t"; 261I<after> it was created.
262
263To further speed up logging, you can bind a scalar variable to the logger,
264which contains true if the logger should be called or not - if it is
265false, calling the logger can be safely skipped. This variable will be
266updated as long as C<$logger> is alive.
267
268Full example:
269
270 # near the init section
271 use AnyEvent::Log;
272
273 my $debug_log = AnyEvent:Log::logger debug => \my $debug;
274
275 # and later in your program
276 $debug_log->("yo, stuff here") if $debug;
277
278 $debug and $debug_log->("123");
279
280Note: currently the enabled var is always true - that will be fixed in a
281future version :)
282
283=cut
284
285our %LOGGER;
286
287# re-assess logging status for all loggers
288sub _reassess {
289 for (@_ ? $LOGGER{$_[0]} : values %LOGGER) {
290 my ($ctx, $level, $renabled) = @$_;
291
292 # to detect whether a message would be logged, we # actually
293 # try to log one and die. this isn't fast, but we can be
294 # sure that the logging decision is correct :)
295
296 $$renabled = !eval {
297 local $SIG{__DIE__};
298
299 _log $ctx, $level, sub { die };
300
301 1
302 };
303
304 $$renabled = 1; # TODO
121 } 305 }
122
123 exit 1 if $level <= 1;
124} 306}
125 307
126*AnyEvent::log = *AE::log = \&log; 308sub _logger($;$) {
309 my ($ctx, $level, $renabled) = @_;
127 310
128#TODO 311 $renabled ||= \my $enabled;
312
313 $$renabled = 1;
314
315 my $logger = [$ctx, $level, $renabled];
316
317 $LOGGER{$logger+0} = $logger;
318
319 _reassess $logger+0;
320
321 my $guard = AnyEvent::Util::guard {
322 # "clean up"
323 delete $LOGGER{$logger+0};
324 };
325
326 sub {
327 $guard if 0; # keep guard alive, but don't cause runtime overhead
328
329 _log $ctx, $level, @_
330 if $$renabled;
331 }
332}
333
334sub logger($;$) {
335 _logger
336 $CTX{ (caller)[0] } ||= _pkg_ctx +(caller)[0],
337 @_
338}
129 339
130=back 340=back
131 341
132=head1 CONFIGURATION FUNCTIONALITY 342=head1 LOGGING CONTEXTS
133 343
134None, yet, except for C<PERL_ANYEVENT_VERBOSE>, described in the L<AnyEvent> manpage. 344This module associates every log message with a so-called I<logging
345context>, based on the package of the caller. Every perl package has its
346own logging context.
347
348A logging context has three major responsibilities: filtering, logging and
349propagating the message.
350
351For the first purpose, filtering, each context has a set of logging
352levels, called the log level mask. Messages not in the set will be ignored
353by this context (masked).
354
355For logging, the context stores a formatting callback (which takes the
356timestamp, context, level and string message and formats it in the way
357it should be logged) and a logging callback (which is responsible for
358actually logging the formatted message and telling C<AnyEvent::Log>
359whether it has consumed the message, or whether it should be propagated).
360
361For propagation, a context can have any number of attached I<parent
362contexts>. Any message that is neither masked by the logging mask nor
363masked by the logging callback returning true will be passed to all parent
364contexts.
365
366Each call to a logging function will log the message at most once per
367context, so it does not matter (much) if there are cycles or if the
368message can arrive at the same context via multiple paths.
369
370=head2 DEFAULTS
371
372By default, all logging contexts have an full set of log levels ("all"), a
373disabled logging callback and the default formatting callback.
374
375Package contexts have the package name as logging title by default.
376
377They have exactly one parent - the context of the "parent" package. The
378parent package is simply defined to be the package name without the last
379component, i.e. C<AnyEvent::Debug::Wrapped> becomes C<AnyEvent::Debug>,
380and C<AnyEvent> becomes ... C<AnyEvent::Log::Top> which is the
381exception of the rule - just like the parent of any package name in
382Perl is C<main>, the default parent of any top-level package context is
383C<AnyEvent::Log::Top>.
384
385Since perl packages form only an approximate hierarchy, this parent
386context can of course be removed.
387
388All other (anonymous) contexts have no parents and an empty title by
389default.
390
391When the module is loaded it creates the default context called
392C<AnyEvent::Log::Default> (also stored in C<$AnyEvent::Log::Default>),
393which simply logs everything to STDERR and doesn't propagate anything
394anywhere by default. The purpose of the default context is to provide
395a convenient place to override the global logging target or to attach
396additional log targets. It's not meant for filtering.
397
398It then creates the root context called C<AnyEvent::Log::Root> (also
399stored in C<$AnyEvent::Log::Root>) and sets its log level set to all
400levels up to the one specified by C<$ENV{PERL_ANYEVENT_VERBOSE}>. It
401then attached the default logging context to it. The purpose of the root
402context is to simply provide filtering according to some global log level.
403
404Finally it creates the top-level package context called
405C<AnyEvent::Log::Top> (also stored in, you might have guessed,
406C<$AnyEvent::Log::Top>) and attached the root context but otherwise leaves
407it at default config. It's purpose is simply to collect all log messages
408system-wide.
409
410These three special contexts can also be referred to by the
411package/context names C<AE::Log::Default>, C<AE::Log::Root> and
412C<AE::Log::Top>.
413
414The effect of all this is that log messages, by default, wander up
415to the root context where log messages with lower priority then
416C<$ENV{PERL_ANYEVENT_VERBOSE}> will be filtered away and then to the
417AnyEvent::Log::Default context to be logged to STDERR.
418
419Splitting the top level context into three contexts makes it easy to set
420a global logging level (by modifying the root context), but still allow
421other contexts to log, for example, their debug and trace messages to the
422default target despite the global logging level, or to attach additional
423log targets that log messages, regardless of the global logging level.
424
425It also makes it easy to replace the default STDERR-logger by something
426that logs to a file, or to attach additional logging targets.
427
428=head2 CREATING/FINDING/DESTROYING CONTEXTS
135 429
136=over 4 430=over 4
137 431
432=item $ctx = AnyEvent::Log::ctx [$pkg]
433
434This function creates or returns a logging context (which is an object).
435
436If a package name is given, then the context for that packlage is
437returned. If it is called without any arguments, then the context for the
438callers package is returned (i.e. the same context as a C<AE::log> call
439would use).
440
441If C<undef> is given, then it creates a new anonymous context that is not
442tied to any package and is destroyed when no longer referenced.
443
138=cut 444=cut
445
446sub ctx(;$) {
447 my $pkg = @_ ? shift : (caller)[0];
448
449 ref $pkg
450 ? $pkg
451 : defined $pkg
452 ? $CTX{$pkg} ||= AnyEvent::Log::_pkg_ctx $pkg
453 : bless [undef, (1 << 10) - 1 - 1], "AnyEvent::Log::Ctx"
454}
455
456=item AnyEvent::Log::reset
457
458Deletes all contexts and recreates the default hierarchy, i.e. resets the
459logging subsystem to defaults.
460
461This can be used to implement config-file (re-)loading: before loading a
462configuration, reset all contexts.
463
464=cut
465
466sub reset {
467 @$_ = () for values %CTX; # just to be sure - to kill circular logging dependencies
468 %CTX = ();
469
470 my $default = ctx undef;
471 $default->title ("AnyEvent::Log::Default");
472 $default->log_cb (sub {
473 print STDERR shift;
474 0
475 });
476 $AnyEvent::Log::Default = $CTX{"AnyEvent::Log::Default"} = $CTX{"AE::Log::Default"} = $default;
477
478 my $root = ctx undef;
479 $root->title ("AnyEvent::Log::Root");
480 $root->level ($AnyEvent::VERBOSE);
481 $root->attach ($default);
482 $AnyEvent::Log::Root = $CTX{"AnyEvent::Log::Root"} = $CTX{"AE::Log::Root"} = $root;
483
484 my $top = ctx undef;
485 $top->title ("AnyEvent::Log::Top");
486 $top->attach ($root);
487 $AnyEvent::Log::Top = $CTX{"AnyEvent::Log::Top"} = $CTX{"AE::Log::Top"} = $top;
488}
489
490AnyEvent::Log::reset;
491
492# hello, CPAN, please catch me
493package AnyEvent::Log::Default;
494package AE::Log::Default;
495package AnyEvent::Log::Root;
496package AE::Log::Root;
497package AnyEvent::Log::Top;
498package AE::Log::Top;
499
500package AnyEvent::Log::Ctx;
501
502# 0 1 2 3 4
503# [$title, $level, %$parents, &$logcb, &$fmtcb]
504
505=item $ctx = new AnyEvent::Log::Ctx methodname => param...
506
507This is a convenience constructor that makes it simpler to construct
508anonymous logging contexts.
509
510Each key-value pair results in an invocation of the method of the same
511name as the key with the value as parameter, unless the value is an
512arrayref, in which case it calls the method with the contents of the
513array. The methods are called in the same order as specified.
514
515Example: create a new logging context and set both the default logging
516level, some parent contexts and a logging callback.
517
518 $ctx = new AnyEvent::Log::Ctx
519 title => "dubious messages",
520 level => "error",
521 log_cb => sub { print STDOUT shift; 0 },
522 parents => [$ctx1, $ctx, $ctx2],
523 ;
524
525=back
526
527=cut
528
529sub new {
530 my $class = shift;
531
532 my $ctx = AnyEvent::Log::ctx undef;
533
534 while (@_) {
535 my ($k, $v) = splice @_, 0, 2;
536 $ctx->$k (ref $v eq "ARRAY" ? @$v : $v);
537 }
538
539 bless $ctx, $class # do we really support subclassing, hmm?
540}
541
542
543=head2 CONFIGURING A LOG CONTEXT
544
545The following methods can be used to configure the logging context.
546
547=over 4
548
549=item $ctx->title ([$new_title])
550
551Returns the title of the logging context - this is the package name, for
552package contexts, and a user defined string for all others.
553
554If C<$new_title> is given, then it replaces the package name or title.
555
556=cut
557
558sub title {
559 $_[0][0] = $_[1] if @_ > 1;
560 $_[0][0]
561}
562
563=back
564
565=head3 LOGGING LEVELS
566
567The following methods deal with the logging level set associated with the
568log context.
569
570The most common method to use is probably C<< $ctx->level ($level) >>,
571which configures the specified and any higher priority levels.
572
573All functions which accept a list of levels also accept the special string
574C<all> which expands to all logging levels.
575
576=over 4
577
578=item $ctx->levels ($level[, $level...)
579
580Enables logging for the given levels and disables it for all others.
581
582=item $ctx->level ($level)
583
584Enables logging for the given level and all lower level (higher priority)
585ones. In addition to normal logging levels, specifying a level of C<0> or
586C<off> disables all logging for this level.
587
588Example: log warnings, errors and higher priority messages.
589
590 $ctx->level ("warn");
591 $ctx->level (5); # same thing, just numeric
592
593=item $ctx->enable ($level[, $level...])
594
595Enables logging for the given levels, leaving all others unchanged.
596
597=item $ctx->disable ($level[, $level...])
598
599Disables logging for the given levels, leaving all others unchanged.
600
601=cut
602
603sub _lvl_lst {
604 map {
605 $_ > 0 && $_ <= 9 ? $_+0
606 : $_ eq "all" ? (1 .. 9)
607 : $STR2LEVEL{$_} || Carp::croak "$_: not a valid logging level, caught"
608 } @_
609}
610
611our $NOP_CB = sub { 0 };
612
613sub levels {
614 my $ctx = shift;
615 $ctx->[1] = 0;
616 $ctx->[1] |= 1 << $_
617 for &_lvl_lst;
618 AnyEvent::Log::_reassess;
619}
620
621sub level {
622 my $ctx = shift;
623 my $lvl = $_[0] =~ /^(?:0|off|none)$/ ? 0 : (_lvl_lst $_[0])[-1];
624
625 $ctx->[1] = ((1 << $lvl) - 1) << 1;
626 AnyEvent::Log::_reassess;
627}
628
629sub enable {
630 my $ctx = shift;
631 $ctx->[1] |= 1 << $_
632 for &_lvl_lst;
633 AnyEvent::Log::_reassess;
634}
635
636sub disable {
637 my $ctx = shift;
638 $ctx->[1] &= ~(1 << $_)
639 for &_lvl_lst;
640 AnyEvent::Log::_reassess;
641}
642
643=back
644
645=head3 PARENT CONTEXTS
646
647The following methods attach and detach another logging context to a
648logging context.
649
650Log messages are propagated to all parent contexts, unless the logging
651callback consumes the message.
652
653=over 4
654
655=item $ctx->attach ($ctx2[, $ctx3...])
656
657Attaches the given contexts as parents to this context. It is not an error
658to add a context twice (the second add will be ignored).
659
660A context can be specified either as package name or as a context object.
661
662=item $ctx->detach ($ctx2[, $ctx3...])
663
664Removes the given parents from this context - it's not an error to attempt
665to remove a context that hasn't been added.
666
667A context can be specified either as package name or as a context object.
668
669=item $ctx->parents ($ctx2[, $ctx3...])
670
671Replaces all parents attached to this context by the ones given.
672
673=cut
674
675sub attach {
676 my $ctx = shift;
677
678 $ctx->[2]{$_+0} = $_
679 for map { AnyEvent::Log::ctx $_ } @_;
680}
681
682sub detach {
683 my $ctx = shift;
684
685 delete $ctx->[2]{$_+0}
686 for map { AnyEvent::Log::ctx $_ } @_;
687}
688
689sub parents {
690 undef $_[0][2];
691 &attach;
692}
693
694=back
695
696=head3 MESSAGE LOGGING
697
698The following methods configure how the logging context actually does
699the logging (which consists of formatting the message and printing it or
700whatever it wants to do with it) and also allows you to log messages
701directly to a context, without going via your package context.
702
703=over 4
704
705=item $ctx->log_cb ($cb->($str))
706
707Replaces the logging callback on the context (C<undef> disables the
708logging callback).
709
710The logging callback is responsible for handling formatted log messages
711(see C<fmt_cb> below) - normally simple text strings that end with a
712newline (and are possibly multiline themselves).
713
714It also has to return true iff it has consumed the log message, and false
715if it hasn't. Consuming a message means that it will not be sent to any
716parent context. When in doubt, return C<0> from your logging callback.
717
718Example: a very simple logging callback, simply dump the message to STDOUT
719and do not consume it.
720
721 $ctx->log_cb (sub { print STDERR shift; 0 });
722
723You can filter messages by having a log callback that simply returns C<1>
724and does not do anything with the message, but this counts as "message
725being logged" and might not be very efficient.
726
727Example: propagate all messages except for log levels "debug" and
728"trace". The messages will still be generated, though, which can slow down
729your program.
730
731 $ctx->levels ("debug", "trace");
732 $ctx->log_cb (sub { 1 }); # do not log, but eat debug and trace messages
733
734=item $ctx->fmt_cb ($fmt_cb->($timestamp, $ctx, $level, $message))
735
736Replaces the formatting callback on the context (C<undef> restores the
737default formatter).
738
739The callback is passed the (possibly fractional) timestamp, the original
740logging context, the (numeric) logging level and the raw message string and needs to
741return a formatted log message. In most cases this will be a string, but
742it could just as well be an array reference that just stores the values.
743
744Example: format just the raw message, with numeric log level in angle
745brackets.
746
747 $ctx->fmt_cb (sub {
748 my ($time, $ctx, $lvl, $msg) = @_;
749
750 "<$lvl>$msg\n"
751 });
752
753Example: return an array reference with just the log values, and use
754C<PApp::SQL::sql_exec> to store the emssage in a database.
755
756 $ctx->fmt_cb (sub { \@_ });
757 $ctx->log_cb (sub {
758 my ($msg) = @_;
759
760 sql_exec "insert into log (when, subsys, prio, msg) values (?, ?, ?, ?)",
761 $msg->[0] + 0,
762 "$msg->[1]",
763 $msg->[2] + 0,
764 "$msg->[3]";
765
766 0
767 });
768
769=cut
770
771sub log_cb {
772 my ($ctx, $cb) = @_;
773
774 $ctx->[3] = $cb;
775}
776
777sub fmt_cb {
778 my ($ctx, $cb) = @_;
779
780 $ctx->[4] = $cb;
781}
782
783=item $ctx->log ($level, $msg[, @params])
784
785Same as C<AnyEvent::Log::log>, but uses the given context as log context.
786
787=item $logger = $ctx->logger ($level[, \$enabled])
788
789Same as C<AnyEvent::Log::logger>, but uses the given context as log
790context.
791
792=cut
793
794*log = \&AnyEvent::Log::_log;
795*logger = \&AnyEvent::Log::_logger;
139 796
1401; 7971;
798
799=back
800
801=head1 EXAMPLES
802
803This section shows some common configurations.
804
805=over 4
806
807=item Setting the global logging level.
808
809Either put PERL_ANYEVENT_VERBOSE=<number> into your environment before
810running your program, or modify the log level of the root context:
811
812 PERL_ANYEVENT_VERBOSE=5 ./myprog
813
814 $AnyEvent::Log::Root->level ("warn");
815
816=item Append all messages to a file instead of sending them to STDERR.
817
818This is affected by the global logging level.
819
820 open my $fh, ">>", $path
821 or die "$path: $!";
822
823 $AnyEvent::Log::Default->log_cb (sub {
824 syswrite $fh, shift;
825 0
826 });
827
828=item Write all messages with priority C<error> and higher to a file.
829
830This writes them only when the global logging level allows it, because
831it is attached to the default context which is invoked I<after> global
832filtering.
833
834 open my $fh, ">>", $path
835 or die "$path: $!";
836
837 $AnyEvent::Log::Default->attach (new AnyEvent::Log::Ctx
838 log_cb => sub { syswrite $fh, shift; 0 });
839
840This writes them regardless of the global logging level, because it is
841attached to the toplevel context, which receives all messages I<before>
842the global filtering.
843
844 $AnyEvent::Log::Top->attach (new AnyEvent::Log::Ctx
845 log_cb => sub { syswrite $fh, shift; 0 });
846
847In both cases, messages are still written to STDOUT.
848
849=item Write trace messages (only) from L<AnyEvent::Debug> to the default logging target(s).
850
851Attach the CyAnyEvent::Log::Default> context to the C<AnyEvent::Debug>
852context and increase the C<AnyEvent::Debug> logging level - this simply
853circumvents the global filtering for trace messages.
854
855 my $debug = AnyEvent::Debug->AnyEvent::Log::ctx;
856 $debug->attach ($AnyEvent::Log::Default);
857 $debug->levels ("trace"); # not "level"!
141 858
142=back 859=back
143 860
144=head1 AUTHOR 861=head1 AUTHOR
145 862

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines