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.9 by root, Fri Aug 19 19:59:53 2011 UTC vs.
Revision 1.17 by root, Sat Aug 20 02:21:53 2011 UTC

10 AE::log debug => "hit my knee"; 10 AE::log debug => "hit my knee";
11 AE::log warn => "it's a bit too hot"; 11 AE::log warn => "it's a bit too hot";
12 AE::log error => "the flag was false!"; 12 AE::log error => "the flag was false!";
13 AE::log fatal => "the bit toggled! run!"; 13 AE::log fatal => "the bit toggled! run!";
14 14
15 # complex use 15 # "complex" use
16 use AnyEvent::Log; 16 use AnyEvent::Log;
17 17
18 my $tracer = AnyEvent::Log::logger trace => \$my $trace; 18 my $tracer = AnyEvent::Log::logger trace => \$my $trace;
19 19
20 $tracer->("i am here") if $trace; 20 $tracer->("i am here") if $trace;
21 $tracer->(sub { "lots of data: " . Dumper $self }) if $trace; 21 $tracer->(sub { "lots of data: " . Dumper $self }) if $trace;
22 22
23 #TODO: config 23 # configuration
24 #TODO: ctx () becomes caller[0]... 24
25 # set logging for this package to errors and higher only
26 AnyEvent::Log::ctx->level ("error");
27
28 # set logging globally to anything below debug
29 $AnyEvent::Log::Root->level ("notice");
30
31 # see also EXAMPLES, below
25 32
26=head1 DESCRIPTION 33=head1 DESCRIPTION
27 34
28This module implements a relatively simple "logging framework". It doesn't 35This module implements a relatively simple "logging framework". It doesn't
29attempt to be "the" logging solution or even "a" logging solution for 36attempt to be "the" logging solution or even "a" logging solution for
30AnyEvent - AnyEvent simply creates logging messages internally, and this 37AnyEvent - AnyEvent simply creates logging messages internally, and this
31module more or less exposes the mechanism, with some extra spiff to allow 38module more or less exposes the mechanism, with some extra spiff to allow
32using it from other modules as well. 39using it from other modules as well.
33 40
34Remember that the default verbosity level is C<0>, so nothing will be 41Remember that the default verbosity level is C<0>, so nothing will be
35logged, ever, unless you set C<PERL_ANYEVENT_VERBOSE> to a higher number 42logged, unless you set C<PERL_ANYEVENT_VERBOSE> to a higher number before
36before starting your program, or change the logging level at runtime wiht 43starting your program, or change the logging level at runtime with
37something like: 44something like:
38 45
39 use AnyEvent; 46 use AnyEvent;
40 (AnyEvent::Log::ctx "")->level ("info"); 47 (AnyEvent::Log::ctx "")->level ("info");
48
49The design goal behind this module was to keep it simple (and small),
50but make it powerful enough to be potentially useful for any module, and
51extensive enough for the most common tasks, such as logging to multiple
52targets, or being able to log into a database.
53
54The amount of documentation might indicate otherwise, but the module is
55still just 240 lines or so.
41 56
42=head1 LOGGING FUNCTIONS 57=head1 LOGGING FUNCTIONS
43 58
44These functions allow you to log messages. They always use the caller's 59These functions allow you to log messages. They always use the caller's
45package as a "logging module/source". Also, the main logging function is 60package as a "logging module/source". Also, the main logging function is
56use POSIX (); 71use POSIX ();
57 72
58use AnyEvent (); BEGIN { AnyEvent::common_sense } 73use AnyEvent (); BEGIN { AnyEvent::common_sense }
59use AnyEvent::Util (); 74use AnyEvent::Util ();
60 75
76our $VERSION = $AnyEvent::VERSION;
77
61our ($now_int, $now_str1, $now_str2); 78our ($now_int, $now_str1, $now_str2);
62 79
63# Format Time, not public - yet? 80# Format Time, not public - yet?
64sub ft($) { 81sub ft($) {
65 my $i = int $_[0]; 82 my $i = int $_[0];
71 "$now_str1$f$now_str2" 88 "$now_str1$f$now_str2"
72} 89}
73 90
74our %CTX; # all logging contexts 91our %CTX; # all logging contexts
75 92
76my $default_log_cb = sub { 0 };
77
78# creates a default package context object for the given package 93# creates a default package context object for the given package
79sub _pkg_ctx($) { 94sub _pkg_ctx($) {
80 my $ctx = bless [$_[0], 0, {}, $default_log_cb], "AnyEvent::Log::Ctx"; 95 my $ctx = bless [$_[0], (1 << 10) - 1 - 1, {}], "AnyEvent::Log::Ctx";
81 96
82 # link "parent" package 97 # link "parent" package
83 my $pkg = $_[0] =~ /^(.+)::/ ? $1 : ""; 98 my $pkg = $_[0] =~ /^(.+)::/ ? $1 : "AE::Log::Top";
84 99
85 $pkg = $CTX{$pkg} ||= &_pkg_ctx ($pkg); 100 $pkg = $CTX{$pkg} ||= &_pkg_ctx ($pkg);
86 $ctx->[2]{$pkg+0} = $pkg; 101 $ctx->[2]{$pkg+0} = $pkg;
87 102
88 $ctx 103 $ctx
114Note that you can (and should) call this function as C<AnyEvent::log> or 129Note that you can (and should) call this function as C<AnyEvent::log> or
115C<AE::log>, without C<use>-ing this module if possible (i.e. you don't 130C<AE::log>, without C<use>-ing this module if possible (i.e. you don't
116need any additional functionality), as those functions will load the 131need any additional functionality), as those functions will load the
117logging module on demand only. They are also much shorter to write. 132logging module on demand only. They are also much shorter to write.
118 133
119Also, if you otpionally generate a lot of debug messages (such as when 134Also, if you optionally generate a lot of debug messages (such as when
120tracing some code), you should look into using a logger callback and a 135tracing some code), you should look into using a logger callback and a
121boolean enabler (see C<logger>, below). 136boolean enabler (see C<logger>, below).
122 137
123Example: log something at error level. 138Example: log something at error level.
124 139
146 debug => 8, 161 debug => 8,
147 trace => 9, 162 trace => 9,
148); 163);
149 164
150sub now () { time } 165sub now () { time }
166
151AnyEvent::post_detect { 167AnyEvent::post_detect {
152 *now = \&AE::now; 168 *now = \&AE::now;
153}; 169};
154 170
155our @LEVEL2STR = qw(0 fatal alert crit error warn note info debug trace); 171our @LEVEL2STR = qw(0 fatal alert crit error warn note info debug trace);
156 172
157# time, ctx, level, msg 173# time, ctx, level, msg
158sub _format($$$$) { 174sub _format($$$$) {
159 my $pfx = ft $_[0]; 175 my $ts = ft $_[0];
176 my $ct = " ";
160 177
161 join "", 178 my @res;
162 map "$pfx $_\n", 179
163 split /\n/,
164 sprintf "%-5s %s: %s", $LEVEL2STR[$_[2]], $_[1][0], $_[3] 180 for (split /\n/, sprintf "%-5s %s: %s", $LEVEL2STR[$_[2]], $_[1][0], $_[3]) {
181 push @res, "$ts$ct$_\n";
182 $ct = " + ";
183 }
184
185 join "", @res
165} 186}
166 187
167sub _log { 188sub _log {
168 my ($ctx, $level, $format, @args) = @_; 189 my ($ctx, $level, $format, @args) = @_;
169 190
191 $level = $level > 0 && $level <= 9
192 ? $level+0
170 $level = $level > 0 && $level <= 9 ? $level+0 : $STR2LEVEL{$level} || Carp::croak "$level: not a valid logging level, caught"; 193 : $STR2LEVEL{$level} || Carp::croak "$level: not a valid logging level, caught";
171 194
172 my $mask = 1 << $level; 195 my $mask = 1 << $level;
173 my $now = AE::now;
174 196
175 my (@ctx, $did_format, $fmt); 197 my (%seen, @ctx, $now, $fmt);
176 198
177 do { 199 do
178 if ($ctx->[1] & $mask) { 200 {
201 # skip if masked
202 if ($ctx->[1] & $mask && !$seen{$ctx+0}++) {
203 if ($ctx->[3]) {
179 # logging target found 204 # logging target found
180 205
181 # get raw message 206 # now get raw message, unless we have it already
182 unless ($did_format) { 207 unless ($now) {
183 $format = $format->() if ref $format; 208 $format = $format->() if ref $format;
184 $format = sprintf $format, @args if @args; 209 $format = sprintf $format, @args if @args;
185 $format =~ s/\n$//; 210 $format =~ s/\n$//;
186 $did_format = 1; 211 $now = AE::now;
187 }; 212 };
188 213
189 # format msg 214 # format msg
190 my $str = $ctx->[4] 215 my $str = $ctx->[4]
191 ? $ctx->[4]($now, $_[0], $level, $format) 216 ? $ctx->[4]($now, $_[0], $level, $format)
192 : $fmt ||= _format $now, $_[0], $level, $format; 217 : $fmt ||= _format $now, $_[0], $level, $format;
193 218
194 $ctx->[3]($str) 219 $ctx->[3]($str);
195 and next; 220 }
221
222 # not masked, not consumed - propagate to parent contexts
223 push @ctx, values %{ $ctx->[2] };
224 }
196 } 225 }
197
198 # not consume - push parent contexts
199 push @ctx, values %{ $ctx->[2] };
200 } while $ctx = pop @ctx; 226 while $ctx = pop @ctx;
201 227
202 exit 1 if $level <= 1; 228 exit 1 if $level <= 1;
203} 229}
204 230
205sub log($$;@) { 231sub log($$;@) {
246 # and later in your program 272 # and later in your program
247 $debug_log->("yo, stuff here") if $debug; 273 $debug_log->("yo, stuff here") if $debug;
248 274
249 $debug and $debug_log->("123"); 275 $debug and $debug_log->("123");
250 276
251Note: currently the enabled var is always true - that will be fixed in a
252future version :)
253
254=cut 277=cut
255 278
256our %LOGGER; 279our %LOGGER;
257 280
258# re-assess logging status for all loggers 281# re-assess logging status for all loggers
259sub _reassess { 282sub _reassess {
283 local $SIG{__DIE__};
284 my $die = sub { die };
285
260 for (@_ ? $LOGGER{$_[0]} : values %LOGGER) { 286 for (@_ ? $LOGGER{$_[0]} : values %LOGGER) {
261 my ($ctx, $level, $renabled) = @$_; 287 my ($ctx, $level, $renabled) = @$_;
262 288
263 # to detetc whether a message would be logged, we # actually 289 # to detect whether a message would be logged, we actually
264 # try to log one and die. this isn't # fast, but we can be 290 # try to log one and die. this isn't fast, but we can be
265 # sure that the logging decision is correct :) 291 # sure that the logging decision is correct :)
266 292
267 $$renabled = !eval { 293 $$renabled = !eval {
268 local $SIG{__DIE__};
269
270 _log $ctx, $level, sub { die }; 294 _log $ctx, $level, $die;
271 295
272 1 296 1
273 }; 297 };
274
275 $$renabled = 1; # TODO
276 } 298 }
277} 299}
278 300
279sub _logger($;$) { 301sub _logger {
280 my ($ctx, $level, $renabled) = @_; 302 my ($ctx, $level, $renabled) = @_;
281
282 $renabled ||= \my $enabled;
283 303
284 $$renabled = 1; 304 $$renabled = 1;
285 305
286 my $logger = [$ctx, $level, $renabled]; 306 my $logger = [$ctx, $level, $renabled];
287 307
306 _logger 326 _logger
307 $CTX{ (caller)[0] } ||= _pkg_ctx +(caller)[0], 327 $CTX{ (caller)[0] } ||= _pkg_ctx +(caller)[0],
308 @_ 328 @_
309} 329}
310 330
311#TODO
312
313=back 331=back
314 332
315=head1 LOGGING CONTEXTS 333=head1 LOGGING CONTEXTS
316 334
317This module associates every log message with a so-called I<logging 335This module associates every log message with a so-called I<logging
318context>, based on the package of the caller. Every perl package has its 336context>, based on the package of the caller. Every perl package has its
319own logging context. 337own logging context.
320 338
321A logging context has two major responsibilities: logging the message and 339A logging context has three major responsibilities: filtering, logging and
322propagating the message to other contexts. 340propagating the message.
323 341
324For logging, the context stores a set of logging levels that it 342For the first purpose, filtering, each context has a set of logging
325potentially wishes to log, a formatting callback that takes the timestamp, 343levels, called the log level mask. Messages not in the set will be ignored
344by this context (masked).
345
346For logging, the context stores a formatting callback (which takes the
326context, level and string emssage and formats it in the way it should be 347timestamp, context, level and string message and formats it in the way
327logged, and a logging callback, which is responsible for actually logging 348it should be logged) and a logging callback (which is responsible for
328the formatted message and telling C<AnyEvent::Log> whether it has consumed 349actually logging the formatted message and telling C<AnyEvent::Log>
329the message, or whether it should be propagated. 350whether it has consumed the message, or whether it should be propagated).
330 351
331For propagation, a context can have any number of attached I<parent 352For propagation, a context can have any number of attached I<parent
332contexts>. They will be ignored if the logging callback consumes the 353contexts>. Any message that is neither masked by the logging mask nor
333message, but in all other cases, the log message will be passed to all 354masked by the logging callback returning true will be passed to all parent
334parent contexts attached to a context. 355contexts.
356
357Each call to a logging function will log the message at most once per
358context, so it does not matter (much) if there are cycles or if the
359message can arrive at the same context via multiple paths.
335 360
336=head2 DEFAULTS 361=head2 DEFAULTS
337 362
338By default, all logging contexts have an empty set of log levels, a 363By default, all logging contexts have an full set of log levels ("all"), a
339disabled logging callback and the default formatting callback. 364disabled logging callback and the default formatting callback.
340 365
341Package contexts have the package name as logging title by default. 366Package contexts have the package name as logging title by default.
342 367
343They have exactly one parent - the context of the "parent" package. The 368They have exactly one parent - the context of the "parent" package. The
344parent package is simply defined to be the package name without the last 369parent package is simply defined to be the package name without the last
345component, i.e. C<AnyEvent::Debug::Wrapped> becomes C<AnyEvent::Debug>, 370component, i.e. C<AnyEvent::Debug::Wrapped> becomes C<AnyEvent::Debug>,
346and C<AnyEvent> becomes the empty string. 371and C<AnyEvent> becomes ... C<AnyEvent::Log::Top> which is the
372exception of the rule - just like the parent of any package name in
373Perl is C<main>, the default parent of any top-level package context is
374C<AnyEvent::Log::Top>.
347 375
348Since perl packages form only an approximate hierarchy, this parent 376Since perl packages form only an approximate hierarchy, this parent
349context can of course be removed. 377context can of course be removed.
350 378
351All other (anonymous) contexts have no parents and an empty title by 379All other (anonymous) contexts have no parents and an empty title by
352default. 380default.
353 381
354When the module is first loaded, it configures the root context (the one 382When the module is loaded it creates the default context called
355with the empty string) to simply dump all log messages to C<STDERR>, 383C<AnyEvent::Log::Default> (also stored in C<$AnyEvent::Log::Default>),
356and sets it's log level set to all levels up to the one specified by 384which simply logs everything via C<warn> and doesn't propagate anything
357C<$ENV{PERL_ANYEVENT_VERBOSE}>. 385anywhere by default. The purpose of the default context is to provide
386a convenient place to override the global logging target or to attach
387additional log targets. It's not meant for filtering.
358 388
389It then creates the root context called C<AnyEvent::Log::Root> (also
390stored in C<$AnyEvent::Log::Root>) and sets its log level set to all
391levels up to the one specified by C<$ENV{PERL_ANYEVENT_VERBOSE}>. It
392then attached the default logging context to it. The purpose of the root
393context is to simply provide filtering according to some global log level.
394
395Finally it creates the top-level package context called
396C<AnyEvent::Log::Top> (also stored in, you might have guessed,
397C<$AnyEvent::Log::Top>) and attached the root context but otherwise leaves
398it at default config. It's purpose is simply to collect all log messages
399system-wide.
400
401These three special contexts can also be referred to by the
402package/context names C<AE::Log::Default>, C<AE::Log::Root> and
403C<AE::Log::Top>.
404
359The effetc of all this is that log messages, by default, wander up to the 405The effect of all this is that log messages, by default, wander up
360root context and will be logged to STDERR if their log level is less than 406to the root context where log messages with lower priority then
361or equal to C<$ENV{PERL_ANYEVENT_VERBOSE}>. 407C<$ENV{PERL_ANYEVENT_VERBOSE}> will be filtered away and then to the
408AnyEvent::Log::Default context to be passed to C<warn>.
362 409
410Splitting the top level context into three contexts makes it easy to set
411a global logging level (by modifying the root context), but still allow
412other contexts to log, for example, their debug and trace messages to the
413default target despite the global logging level, or to attach additional
414log targets that log messages, regardless of the global logging level.
415
416It also makes it easy to replace the default warn-logger by something that
417logs to a file, or to attach additional logging targets.
418
363=head2 CREATING/FINDING A CONTEXT 419=head2 CREATING/FINDING/DESTROYING CONTEXTS
364 420
365=over 4 421=over 4
366 422
367=item $ctx = AnyEvent::Log::ctx [$pkg] 423=item $ctx = AnyEvent::Log::ctx [$pkg]
368 424
383 439
384 ref $pkg 440 ref $pkg
385 ? $pkg 441 ? $pkg
386 : defined $pkg 442 : defined $pkg
387 ? $CTX{$pkg} ||= AnyEvent::Log::_pkg_ctx $pkg 443 ? $CTX{$pkg} ||= AnyEvent::Log::_pkg_ctx $pkg
388 : bless [undef, 0, undef, $default_log_cb], "AnyEvent::Log::Ctx" 444 : bless [undef, (1 << 10) - 1 - 1], "AnyEvent::Log::Ctx"
389} 445}
390 446
391# create default root context 447=item AnyEvent::Log::reset
392{ 448
393 my $root = ctx undef; 449Resets all package contexts and recreates the default hierarchy if
394 $root->[0] = ""; 450necessary, i.e. resets the logging subsystem to defaults, as much as
395 $root->title ("default"); 451possible. This process keeps references to contexts held by other parts of
396 $root->level ($AnyEvent::VERBOSE); undef $AnyEvent::VERBOSE; 452the program intact.
397 $root->log_cb (sub { 453
398 print STDERR shift; 454This can be used to implement config-file (re-)loading: before loading a
455configuration, reset all contexts.
456
457=cut
458
459sub reset {
460 # hard to kill complex data structures
461 # we recreate all package loggers and reset the hierarchy
462 while (my ($k, $v) = each %CTX) {
463 @$v = ($k, (1 << 10) - 1 - 1, { });
464
465 my $pkg = $k =~ /^(.+)::/ ? $1 : "AE::Log::Top";
466 $v->attach ($CTX{$pkg});
467 }
468
469 $AnyEvent::Log::Default->parents;
470 $AnyEvent::Log::Default->title ("AnyEvent::Log::Default");
471 $AnyEvent::Log::Default->log_cb (sub {
472 warn shift;
399 0 473 0
400 }); 474 });
401 $CTX{""} = $root; 475 $CTX{"AnyEvent::Log::Default"} = $CTX{"AE::Log::Default"} = $AnyEvent::Log::Default;
402}
403 476
404=back 477 $AnyEvent::Log::Root->parents ($AnyEvent::Log::Default);
478 $AnyEvent::Log::Root->title ("AnyEvent::Log::Root");
479 $AnyEvent::Log::Root->level ($AnyEvent::VERBOSE);
480 $CTX{"AnyEvent::Log::Root"} = $CTX{"AE::Log::Root"} = $AnyEvent::Log::Root;
405 481
406=cut 482 $AnyEvent::Log::Top->parents ($AnyEvent::Log::Root);
483 $AnyEvent::Log::Top->title ("AnyEvent::Log::Top");
484 $CTX{"AnyEvent::Log::Top"} = $CTX{"AE::Log::Top"} = $AnyEvent::Log::Top;
485
486 _reassess;
487}
488
489# create the default logger contexts
490$AnyEvent::Log::Default = ctx undef;
491$AnyEvent::Log::Root = ctx undef;
492$AnyEvent::Log::Top = ctx undef;
493
494AnyEvent::Log::reset;
495
496# hello, CPAN, please catch me
497package AnyEvent::Log::Default;
498package AE::Log::Default;
499package AnyEvent::Log::Root;
500package AE::Log::Root;
501package AnyEvent::Log::Top;
502package AE::Log::Top;
407 503
408package AnyEvent::Log::Ctx; 504package AnyEvent::Log::Ctx;
409 505
410# 0 1 2 3 4 506# 0 1 2 3 4
411# [$title, $level, %$parents, &$logcb, &$fmtcb] 507# [$title, $level, %$parents, &$logcb, &$fmtcb]
508
509=item $ctx = new AnyEvent::Log::Ctx methodname => param...
510
511This is a convenience constructor that makes it simpler to construct
512anonymous logging contexts.
513
514Each key-value pair results in an invocation of the method of the same
515name as the key with the value as parameter, unless the value is an
516arrayref, in which case it calls the method with the contents of the
517array. The methods are called in the same order as specified.
518
519Example: create a new logging context and set both the default logging
520level, some parent contexts and a logging callback.
521
522 $ctx = new AnyEvent::Log::Ctx
523 title => "dubious messages",
524 level => "error",
525 log_cb => sub { print STDOUT shift; 0 },
526 parents => [$ctx1, $ctx, $ctx2],
527 ;
528
529=back
530
531=cut
532
533sub new {
534 my $class = shift;
535
536 my $ctx = AnyEvent::Log::ctx undef;
537
538 while (@_) {
539 my ($k, $v) = splice @_, 0, 2;
540 $ctx->$k (ref $v eq "ARRAY" ? @$v : $v);
541 }
542
543 bless $ctx, $class # do we really support subclassing, hmm?
544}
545
412 546
413=head2 CONFIGURING A LOG CONTEXT 547=head2 CONFIGURING A LOG CONTEXT
414 548
415The following methods can be used to configure the logging context. 549The following methods can be used to configure the logging context.
416 550
432 566
433=back 567=back
434 568
435=head3 LOGGING LEVELS 569=head3 LOGGING LEVELS
436 570
437The following methods deal with the logging level set associated wiht the log context. 571The following methods deal with the logging level set associated with the
572log context.
438 573
439The most common method to use is probably C<< $ctx->level ($level) >>, 574The most common method to use is probably C<< $ctx->level ($level) >>,
440which configures the specified and any higher priority levels. 575which configures the specified and any higher priority levels.
441 576
577All functions which accept a list of levels also accept the special string
578C<all> which expands to all logging levels.
579
442=over 4 580=over 4
443 581
444=item $ctx->levels ($level[, $level...) 582=item $ctx->levels ($level[, $level...)
445 583
446Enables logging fot the given levels and disables it for all others. 584Enables logging for the given levels and disables it for all others.
447 585
448=item $ctx->level ($level) 586=item $ctx->level ($level)
449 587
450Enables logging for the given level and all lower level (higher priority) 588Enables logging for the given level and all lower level (higher priority)
451ones. Specifying a level of C<0> or C<off> disables all logging for this 589ones. In addition to normal logging levels, specifying a level of C<0> or
452level. 590C<off> disables all logging for this level.
453 591
454Example: log warnings, errors and higher priority messages. 592Example: log warnings, errors and higher priority messages.
455 593
456 $ctx->level ("warn"); 594 $ctx->level ("warn");
457 $ctx->level (5); # same thing, just numeric 595 $ctx->level (5); # same thing, just numeric
465Disables logging for the given levels, leaving all others unchanged. 603Disables logging for the given levels, leaving all others unchanged.
466 604
467=cut 605=cut
468 606
469sub _lvl_lst { 607sub _lvl_lst {
608 map {
609 $_ > 0 && $_ <= 9 ? $_+0
610 : $_ eq "all" ? (1 .. 9)
470 map { $_ > 0 && $_ <= 9 ? $_+0 : $STR2LEVEL{$_} || Carp::croak "$_: not a valid logging level, caught" } 611 : $STR2LEVEL{$_} || Carp::croak "$_: not a valid logging level, caught"
471 @_ 612 } @_
472} 613}
473 614
474our $NOP_CB = sub { 0 }; 615our $NOP_CB = sub { 0 };
475 616
476sub levels { 617sub levels {
481 AnyEvent::Log::_reassess; 622 AnyEvent::Log::_reassess;
482} 623}
483 624
484sub level { 625sub level {
485 my $ctx = shift; 626 my $ctx = shift;
486 my $lvl = $_[0] =~ /^(?:0|off|none)$/ ? 0 : (_lvl_lst $_[0])[0]; 627 my $lvl = $_[0] =~ /^(?:0|off|none)$/ ? 0 : (_lvl_lst $_[0])[-1];
628
487 $ctx->[1] = ((1 << $lvl) - 1) << 1; 629 $ctx->[1] = ((1 << $lvl) - 1) << 1;
488 AnyEvent::Log::_reassess; 630 AnyEvent::Log::_reassess;
489} 631}
490 632
491sub enable { 633sub enable {
526Removes the given parents from this context - it's not an error to attempt 668Removes the given parents from this context - it's not an error to attempt
527to remove a context that hasn't been added. 669to remove a context that hasn't been added.
528 670
529A context can be specified either as package name or as a context object. 671A context can be specified either as package name or as a context object.
530 672
673=item $ctx->parents ($ctx2[, $ctx3...])
674
675Replaces all parents attached to this context by the ones given.
676
531=cut 677=cut
532 678
533sub attach { 679sub attach {
534 my $ctx = shift; 680 my $ctx = shift;
535 681
542 688
543 delete $ctx->[2]{$_+0} 689 delete $ctx->[2]{$_+0}
544 for map { AnyEvent::Log::ctx $_ } @_; 690 for map { AnyEvent::Log::ctx $_ } @_;
545} 691}
546 692
693sub parents {
694 undef $_[0][2];
695 &attach;
696}
697
547=back 698=back
548 699
549=head3 MESSAGE LOGGING 700=head3 MESSAGE LOGGING
550 701
551The following methods configure how the logging context actually does 702The following methods configure how the logging context actually does
552the logging (which consists of foratting the message and printing it or 703the logging (which consists of formatting the message and printing it or
553whatever it wants to do with it) and also allows you to log messages 704whatever it wants to do with it) and also allows you to log messages
554directly to a context, without going via your package context. 705directly to a context, without going via your package context.
555 706
556=over 4 707=over 4
557 708
571Example: a very simple logging callback, simply dump the message to STDOUT 722Example: a very simple logging callback, simply dump the message to STDOUT
572and do not consume it. 723and do not consume it.
573 724
574 $ctx->log_cb (sub { print STDERR shift; 0 }); 725 $ctx->log_cb (sub { print STDERR shift; 0 });
575 726
727You can filter messages by having a log callback that simply returns C<1>
728and does not do anything with the message, but this counts as "message
729being logged" and might not be very efficient.
730
731Example: propagate all messages except for log levels "debug" and
732"trace". The messages will still be generated, though, which can slow down
733your program.
734
735 $ctx->levels ("debug", "trace");
736 $ctx->log_cb (sub { 1 }); # do not log, but eat debug and trace messages
737
576=item $ctx->fmt_cb ($fmt_cb->($timestamp, $ctx, $level, $message)) 738=item $ctx->fmt_cb ($fmt_cb->($timestamp, $ctx, $level, $message))
577 739
578Replaces the fornatting callback on the cobntext (C<undef> restores the 740Replaces the formatting callback on the context (C<undef> restores the
579default formatter). 741default formatter).
580 742
581The callback is passed the (possibly fractional) timestamp, the original 743The callback is passed the (possibly fractional) timestamp, the original
582logging context, the (numeric) logging level and the raw message string and needs to 744logging context, the (numeric) logging level and the raw message string and needs to
583return a formatted log message. In most cases this will be a string, but 745return a formatted log message. In most cases this will be a string, but
611=cut 773=cut
612 774
613sub log_cb { 775sub log_cb {
614 my ($ctx, $cb) = @_; 776 my ($ctx, $cb) = @_;
615 777
616 $ctx->[3] = $cb || $default_log_cb; 778 $ctx->[3] = $cb;
617} 779}
618 780
619sub fmt_cb { 781sub fmt_cb {
620 my ($ctx, $cb) = @_; 782 my ($ctx, $cb) = @_;
621 783
638 800
6391; 8011;
640 802
641=back 803=back
642 804
805=head1 EXAMPLES
806
807This section shows some common configurations.
808
809=over 4
810
811=item Setting the global logging level.
812
813Either put PERL_ANYEVENT_VERBOSE=<number> into your environment before
814running your program, or modify the log level of the root context:
815
816 PERL_ANYEVENT_VERBOSE=5 ./myprog
817
818 $AnyEvent::Log::Root->level ("warn");
819
820=item Append all messages to a file instead of sending them to STDERR.
821
822This is affected by the global logging level.
823
824 open my $fh, ">>", $path
825 or die "$path: $!";
826
827 $AnyEvent::Log::Default->log_cb (sub {
828 syswrite $fh, shift;
829 0
830 });
831
832=item Write all messages with priority C<error> and higher to a file.
833
834This writes them only when the global logging level allows it, because
835it is attached to the default context which is invoked I<after> global
836filtering.
837
838 open my $fh, ">>", $path
839 or die "$path: $!";
840
841 $AnyEvent::Log::Default->attach (new AnyEvent::Log::Ctx
842 log_cb => sub { syswrite $fh, shift; 0 });
843
844This writes them regardless of the global logging level, because it is
845attached to the toplevel context, which receives all messages I<before>
846the global filtering.
847
848 $AnyEvent::Log::Top->attach (new AnyEvent::Log::Ctx
849 log_cb => sub { syswrite $fh, shift; 0 });
850
851In both cases, messages are still written to STDOUT.
852
853=item Write trace messages (only) from L<AnyEvent::Debug> to the default logging target(s).
854
855Attach the CyAnyEvent::Log::Default> context to the C<AnyEvent::Debug>
856context and increase the C<AnyEvent::Debug> logging level - this simply
857circumvents the global filtering for trace messages.
858
859 my $debug = AnyEvent::Debug->AnyEvent::Log::ctx;
860 $debug->attach ($AnyEvent::Log::Default);
861 $debug->levels ("trace"); # not "level"!
862
863This of course works for any package.
864
865=back
866
643=head1 AUTHOR 867=head1 AUTHOR
644 868
645 Marc Lehmann <schmorp@schmorp.de> 869 Marc Lehmann <schmorp@schmorp.de>
646 http://home.schmorp.de/ 870 http://home.schmorp.de/
647 871

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines