… | |
… | |
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 | # configuration |
23 | # configuration |
24 | |
24 | |
25 | # set logging for this package to maximum |
25 | # set logging for this package to errors and higher only |
26 | AnyEvent::Log::ctx->level ("all"); |
26 | AnyEvent::Log::ctx->level ("error"); |
27 | |
27 | |
28 | # set logging globally to anything below debug |
28 | # set logging globally to anything below debug |
29 | (AnyEvent::Log::ctx "")->level ("notice"); |
29 | $AnyEvent::Log::Root->level ("notice"); |
30 | |
30 | |
31 | # see also EXAMPLES, below |
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); |
|
|
40 | |
32 | |
41 | =head1 DESCRIPTION |
33 | =head1 DESCRIPTION |
42 | |
34 | |
43 | This module implements a relatively simple "logging framework". It doesn't |
35 | This module implements a relatively simple "logging framework". It doesn't |
44 | attempt to be "the" logging solution or even "a" logging solution for |
36 | attempt to be "the" logging solution or even "a" logging solution for |
… | |
… | |
57 | The design goal behind this module was to keep it simple (and small), |
49 | The design goal behind this module was to keep it simple (and small), |
58 | but make it powerful enough to be potentially useful for any module, and |
50 | but make it powerful enough to be potentially useful for any module, and |
59 | extensive enough for the most common tasks, such as logging to multiple |
51 | extensive enough for the most common tasks, such as logging to multiple |
60 | targets, or being able to log into a database. |
52 | targets, or being able to log into a database. |
61 | |
53 | |
|
|
54 | The amount of documentation might indicate otherwise, but the module is |
|
|
55 | still just 240 lines or so. |
|
|
56 | |
62 | =head1 LOGGING FUNCTIONS |
57 | =head1 LOGGING FUNCTIONS |
63 | |
58 | |
64 | These functions allow you to log messages. They always use the caller's |
59 | These functions allow you to log messages. They always use the caller's |
65 | package as a "logging module/source". Also, the main logging function is |
60 | package as a "logging module/source". Also, the main logging function is |
66 | callable as C<AnyEvent::log> or C<AE::log> when the C<AnyEvent> module is |
61 | callable as C<AnyEvent::log> or C<AE::log> when the C<AnyEvent> module is |
… | |
… | |
75 | use Carp (); |
70 | use Carp (); |
76 | use POSIX (); |
71 | use POSIX (); |
77 | |
72 | |
78 | use AnyEvent (); BEGIN { AnyEvent::common_sense } |
73 | use AnyEvent (); BEGIN { AnyEvent::common_sense } |
79 | use AnyEvent::Util (); |
74 | use AnyEvent::Util (); |
|
|
75 | |
|
|
76 | our $VERSION = $AnyEvent::VERSION; |
80 | |
77 | |
81 | our ($now_int, $now_str1, $now_str2); |
78 | our ($now_int, $now_str1, $now_str2); |
82 | |
79 | |
83 | # Format Time, not public - yet? |
80 | # Format Time, not public - yet? |
84 | sub ft($) { |
81 | sub ft($) { |
… | |
… | |
275 | # and later in your program |
272 | # and later in your program |
276 | $debug_log->("yo, stuff here") if $debug; |
273 | $debug_log->("yo, stuff here") if $debug; |
277 | |
274 | |
278 | $debug and $debug_log->("123"); |
275 | $debug and $debug_log->("123"); |
279 | |
276 | |
280 | Note: currently the enabled var is always true - that will be fixed in a |
|
|
281 | future version :) |
|
|
282 | |
|
|
283 | =cut |
277 | =cut |
284 | |
278 | |
285 | our %LOGGER; |
279 | our %LOGGER; |
286 | |
280 | |
287 | # re-assess logging status for all loggers |
281 | # re-assess logging status for all loggers |
… | |
… | |
303 | |
297 | |
304 | $$renabled = 1; # TODO |
298 | $$renabled = 1; # TODO |
305 | } |
299 | } |
306 | } |
300 | } |
307 | |
301 | |
308 | sub _logger($;$) { |
302 | sub _logger { |
309 | my ($ctx, $level, $renabled) = @_; |
303 | my ($ctx, $level, $renabled) = @_; |
310 | |
|
|
311 | $renabled ||= \my $enabled; |
|
|
312 | |
304 | |
313 | $$renabled = 1; |
305 | $$renabled = 1; |
314 | |
306 | |
315 | my $logger = [$ctx, $level, $renabled]; |
307 | my $logger = [$ctx, $level, $renabled]; |
316 | |
308 | |
… | |
… | |
388 | All other (anonymous) contexts have no parents and an empty title by |
380 | All other (anonymous) contexts have no parents and an empty title by |
389 | default. |
381 | default. |
390 | |
382 | |
391 | When the module is loaded it creates the default context called |
383 | When the module is loaded it creates the default context called |
392 | C<AnyEvent::Log::Default> (also stored in C<$AnyEvent::Log::Default>), |
384 | C<AnyEvent::Log::Default> (also stored in C<$AnyEvent::Log::Default>), |
393 | which simply logs everything to STDERR and doesn't propagate anything |
385 | which simply logs everything via C<warn> and doesn't propagate anything |
394 | anywhere by default. The purpose of the default context is to provide |
386 | anywhere by default. The purpose of the default context is to provide |
395 | a convenient place to override the global logging target or to attach |
387 | a convenient place to override the global logging target or to attach |
396 | additional log targets. It's not meant for filtering. |
388 | additional log targets. It's not meant for filtering. |
397 | |
389 | |
398 | It then creates the root context called C<AnyEvent::Log::Root> (also |
390 | It then creates the root context called C<AnyEvent::Log::Root> (also |
… | |
… | |
412 | C<AE::Log::Top>. |
404 | C<AE::Log::Top>. |
413 | |
405 | |
414 | The effect of all this is that log messages, by default, wander up |
406 | The effect of all this is that log messages, by default, wander up |
415 | to the root context where log messages with lower priority then |
407 | to the root context where log messages with lower priority then |
416 | C<$ENV{PERL_ANYEVENT_VERBOSE}> will be filtered away and then to the |
408 | C<$ENV{PERL_ANYEVENT_VERBOSE}> will be filtered away and then to the |
417 | AnyEvent::Log::Default context to be logged to STDERR. |
409 | AnyEvent::Log::Default context to be passed to C<warn>. |
418 | |
410 | |
419 | Splitting the top level context into three contexts makes it easy to set |
411 | Splitting the top level context into three contexts makes it easy to set |
420 | a global logging level (by modifying the root context), but still allow |
412 | a global logging level (by modifying the root context), but still allow |
421 | other contexts to log, for example, their debug and trace messages to the |
413 | other contexts to log, for example, their debug and trace messages to the |
422 | default target despite the global logging level, or to attach additional |
414 | default target despite the global logging level, or to attach additional |
423 | log targets that log messages, regardless of the global logging level. |
415 | log targets that log messages, regardless of the global logging level. |
424 | |
416 | |
425 | It also makes it easy to replace the default STDERR-logger by something |
417 | It also makes it easy to replace the default warn-logger by something that |
426 | that logs to a file, or to attach additional logging targets. |
418 | logs to a file, or to attach additional logging targets. |
427 | |
419 | |
428 | =head2 CREATING/FINDING/DESTROYING CONTEXTS |
420 | =head2 CREATING/FINDING/DESTROYING CONTEXTS |
429 | |
421 | |
430 | =over 4 |
422 | =over 4 |
431 | |
423 | |
… | |
… | |
453 | : bless [undef, (1 << 10) - 1 - 1], "AnyEvent::Log::Ctx" |
445 | : bless [undef, (1 << 10) - 1 - 1], "AnyEvent::Log::Ctx" |
454 | } |
446 | } |
455 | |
447 | |
456 | =item AnyEvent::Log::reset |
448 | =item AnyEvent::Log::reset |
457 | |
449 | |
458 | Deletes all contexts and recreates the default hierarchy, i.e. resets the |
450 | Resets all package contexts and recreates the default hierarchy if |
459 | logging subsystem to defaults. |
451 | necessary, i.e. resets the logging subsystem to defaults, as much as |
|
|
452 | possible. This process keeps references to contexts held by other parts of |
|
|
453 | the program intact. |
460 | |
454 | |
461 | This can be used to implement config-file (re-)loading: before loading a |
455 | This can be used to implement config-file (re-)loading: before loading a |
462 | configuration, reset all contexts. |
456 | configuration, reset all contexts. |
463 | |
457 | |
464 | =cut |
458 | =cut |
465 | |
459 | |
466 | sub reset { |
460 | sub reset { |
467 | @$_ = () for values %CTX; # just to be sure - to kill circular logging dependencies |
461 | # hard to kill complex data structures |
468 | %CTX = (); |
462 | # we recreate all package loggers and reset the hierarchy |
|
|
463 | while (my ($k, $v) = each %CTX) { |
|
|
464 | @$v = ($k, (1 << 10) - 1 - 1, { }); |
469 | |
465 | |
470 | my $default = ctx undef; |
466 | my $pkg = $k =~ /^(.+)::/ ? $1 : "AE::Log::Top"; |
|
|
467 | $v->attach ($CTX{$pkg}); |
|
|
468 | } |
|
|
469 | |
|
|
470 | $AnyEvent::Log::Default->parents; |
471 | $default->title ("AnyEvent::Log::Default"); |
471 | $AnyEvent::Log::Default->title ("AnyEvent::Log::Default"); |
472 | $default->log_cb (sub { |
472 | $AnyEvent::Log::Default->log_cb (sub { |
473 | print STDERR shift; |
473 | warn shift; |
474 | 0 |
474 | 0 |
475 | }); |
475 | }); |
476 | $AnyEvent::Log::Default = $CTX{"AnyEvent::Log::Default"} = $CTX{"AE::Log::Default"} = $default; |
476 | $CTX{"AnyEvent::Log::Default"} = $CTX{"AE::Log::Default"} = $AnyEvent::Log::Default; |
477 | |
477 | |
478 | my $root = ctx undef; |
478 | $AnyEvent::Log::Root->parents ($AnyEvent::Log::Default); |
479 | $root->title ("AnyEvent::Log::Root"); |
479 | $AnyEvent::Log::Root->title ("AnyEvent::Log::Root"); |
480 | $root->level ($AnyEvent::VERBOSE); |
480 | $AnyEvent::Log::Root->level ($AnyEvent::VERBOSE); |
481 | $root->attach ($default); |
|
|
482 | $AnyEvent::Log::Root = $CTX{"AnyEvent::Log::Root"} = $CTX{"AE::Log::Root"} = $root; |
481 | $CTX{"AnyEvent::Log::Root"} = $CTX{"AE::Log::Root"} = $AnyEvent::Log::Root; |
483 | |
482 | |
484 | my $top = ctx undef; |
483 | $AnyEvent::Log::Top->parents ($AnyEvent::Log::Root); |
485 | $top->title ("AnyEvent::Log::Top"); |
484 | $AnyEvent::Log::Top->title ("AnyEvent::Log::Top"); |
486 | $top->attach ($root); |
|
|
487 | $AnyEvent::Log::Top = $CTX{"AnyEvent::Log::Top"} = $CTX{"AE::Log::Top"} = $top; |
485 | $CTX{"AnyEvent::Log::Top"} = $CTX{"AE::Log::Top"} = $AnyEvent::Log::Top; |
|
|
486 | |
|
|
487 | _reassess; |
488 | } |
488 | } |
|
|
489 | |
|
|
490 | # create the default logger contexts |
|
|
491 | $AnyEvent::Log::Default = ctx undef; |
|
|
492 | $AnyEvent::Log::Root = ctx undef; |
|
|
493 | $AnyEvent::Log::Top = ctx undef; |
489 | |
494 | |
490 | AnyEvent::Log::reset; |
495 | AnyEvent::Log::reset; |
491 | |
496 | |
492 | # hello, CPAN, please catch me |
497 | # hello, CPAN, please catch me |
493 | package AnyEvent::Log::Default; |
498 | package AnyEvent::Log::Default; |