… | |
… | |
57 | The design goal behind this module was to keep it simple (and small), |
57 | 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 |
58 | 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 |
59 | extensive enough for the most common tasks, such as logging to multiple |
60 | targets, or being able to log into a database. |
60 | targets, or being able to log into a database. |
61 | |
61 | |
|
|
62 | The amount of documentation might indicate otherwise, but the module is |
|
|
63 | still just 240 lines or so. |
|
|
64 | |
62 | =head1 LOGGING FUNCTIONS |
65 | =head1 LOGGING FUNCTIONS |
63 | |
66 | |
64 | These functions allow you to log messages. They always use the caller's |
67 | 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 |
68 | 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 |
69 | callable as C<AnyEvent::log> or C<AE::log> when the C<AnyEvent> module is |
… | |
… | |
75 | use Carp (); |
78 | use Carp (); |
76 | use POSIX (); |
79 | use POSIX (); |
77 | |
80 | |
78 | use AnyEvent (); BEGIN { AnyEvent::common_sense } |
81 | use AnyEvent (); BEGIN { AnyEvent::common_sense } |
79 | use AnyEvent::Util (); |
82 | use AnyEvent::Util (); |
|
|
83 | |
|
|
84 | our $VERSION = $AnyEvent::VERSION; |
80 | |
85 | |
81 | our ($now_int, $now_str1, $now_str2); |
86 | our ($now_int, $now_str1, $now_str2); |
82 | |
87 | |
83 | # Format Time, not public - yet? |
88 | # Format Time, not public - yet? |
84 | sub ft($) { |
89 | sub ft($) { |
… | |
… | |
377 | They have exactly one parent - the context of the "parent" package. The |
382 | They have exactly one parent - the context of the "parent" package. The |
378 | parent package is simply defined to be the package name without the last |
383 | parent package is simply defined to be the package name without the last |
379 | component, i.e. C<AnyEvent::Debug::Wrapped> becomes C<AnyEvent::Debug>, |
384 | component, i.e. C<AnyEvent::Debug::Wrapped> becomes C<AnyEvent::Debug>, |
380 | and C<AnyEvent> becomes ... C<AnyEvent::Log::Top> which is the |
385 | and C<AnyEvent> becomes ... C<AnyEvent::Log::Top> which is the |
381 | exception of the rule - just like the parent of any package name in |
386 | exception of the rule - just like the parent of any package name in |
382 | Perl is C<main>, the default parent of any toplevel package context is |
387 | Perl is C<main>, the default parent of any top-level package context is |
383 | C<AnyEvent::Log::Top>. |
388 | C<AnyEvent::Log::Top>. |
384 | |
389 | |
385 | Since perl packages form only an approximate hierarchy, this parent |
390 | Since perl packages form only an approximate hierarchy, this parent |
386 | context can of course be removed. |
391 | context can of course be removed. |
387 | |
392 | |
388 | All other (anonymous) contexts have no parents and an empty title by |
393 | All other (anonymous) contexts have no parents and an empty title by |
389 | default. |
394 | default. |
390 | |
395 | |
391 | When the module is loaded it creates the default context called |
396 | When the module is loaded it creates the default context called |
392 | C<AnyEvent::Log::Default>, which simply logs everything to STDERR and |
397 | C<AnyEvent::Log::Default> (also stored in C<$AnyEvent::Log::Default>), |
393 | doesn't propagate anything anywhere by default. The purpose of the default |
398 | which simply logs everything to STDERR and doesn't propagate anything |
394 | context is to provide a convenient place to override the global logging |
399 | anywhere by default. The purpose of the default context is to provide |
|
|
400 | a convenient place to override the global logging target or to attach |
395 | target or to attach additional log targets. It's not meant for filtering. |
401 | additional log targets. It's not meant for filtering. |
396 | |
402 | |
397 | It then creates the root context called C<AnyEvent::Log::Root> and |
403 | It then creates the root context called C<AnyEvent::Log::Root> (also |
398 | sets its log level set to all levels up to the one specified by |
404 | stored in C<$AnyEvent::Log::Root>) and sets its log level set to all |
399 | C<$ENV{PERL_ANYEVENT_VERBOSE}>. It then attached the default logging |
405 | levels up to the one specified by C<$ENV{PERL_ANYEVENT_VERBOSE}>. It |
400 | context to it. The purpose of the root context is to simply provide |
406 | then attached the default logging context to it. The purpose of the root |
401 | filtering according to some global log level. |
407 | context is to simply provide filtering according to some global log level. |
402 | |
408 | |
403 | Finally it creates the toplevel package context called |
409 | Finally it creates the top-level package context called |
|
|
410 | C<AnyEvent::Log::Top> (also stored in, you might have guessed, |
404 | C<AnyEvent::Log::Top> and attached the root context but otherwise leaves |
411 | C<$AnyEvent::Log::Top>) and attached the root context but otherwise leaves |
405 | it at default config. It's purpose is simply to collect all log messages |
412 | it at default config. It's purpose is simply to collect all log messages |
406 | system-wide. |
413 | system-wide. |
407 | |
414 | |
408 | These three special contexts can also be referred to by the names |
415 | These three special contexts can also be referred to by the |
409 | C<AE::Log::Default>, C<AE::Log::Root> and C<AE::Log::Top>. |
416 | package/context names C<AE::Log::Default>, C<AE::Log::Root> and |
|
|
417 | C<AE::Log::Top>. |
410 | |
418 | |
411 | The effect of all this is that log messages, by default, wander up |
419 | The effect of all this is that log messages, by default, wander up |
412 | to the root context where log messages with lower priority then |
420 | to the root context where log messages with lower priority then |
413 | C<$ENV{PERL_ANYEVENT_VERBOSE}> will be filtered away and then to the |
421 | C<$ENV{PERL_ANYEVENT_VERBOSE}> will be filtered away and then to the |
414 | AnyEvent::Log::Default context to be logged to STDERR. |
422 | AnyEvent::Log::Default context to be logged to STDERR. |
… | |
… | |
468 | $default->title ("AnyEvent::Log::Default"); |
476 | $default->title ("AnyEvent::Log::Default"); |
469 | $default->log_cb (sub { |
477 | $default->log_cb (sub { |
470 | print STDERR shift; |
478 | print STDERR shift; |
471 | 0 |
479 | 0 |
472 | }); |
480 | }); |
473 | $CTX{"AnyEvent::Log::Default"} = $CTX{"AE::Log::Default"} = $default; |
481 | $AnyEvent::Log::Default = $CTX{"AnyEvent::Log::Default"} = $CTX{"AE::Log::Default"} = $default; |
474 | |
482 | |
475 | my $root = ctx undef; |
483 | my $root = ctx undef; |
476 | $root->title ("AnyEvent::Log::Root"); |
484 | $root->title ("AnyEvent::Log::Root"); |
477 | $root->level ($AnyEvent::VERBOSE); |
485 | $root->level ($AnyEvent::VERBOSE); |
478 | $root->attach ($default); |
486 | $root->attach ($default); |
479 | $CTX{"AnyEvent::Log::Root"} = $CTX{"AE::Log::Root"} = $root; |
487 | $AnyEvent::Log::Root = $CTX{"AnyEvent::Log::Root"} = $CTX{"AE::Log::Root"} = $root; |
480 | |
488 | |
481 | my $top = ctx undef; |
489 | my $top = ctx undef; |
482 | $top->title ("AnyEvent::Log::Top"); |
490 | $top->title ("AnyEvent::Log::Top"); |
483 | $top->attach ($root); |
491 | $top->attach ($root); |
484 | $CTX{"AnyEvent::Log::Top"} = $CTX{"AE::Log::Top"} = $top; |
492 | $AnyEvent::Log::Top = $CTX{"AnyEvent::Log::Top"} = $CTX{"AE::Log::Top"} = $top; |
485 | } |
493 | } |
486 | |
494 | |
487 | AnyEvent::Log::reset; |
495 | AnyEvent::Log::reset; |
488 | |
496 | |
|
|
497 | # hello, CPAN, please catch me |
489 | package AnyEvent::Log::Default; |
498 | package AnyEvent::Log::Default; |
490 | package AE::Log::Default; |
499 | package AE::Log::Default; |
491 | package AnyEvent::Log::Root; |
500 | package AnyEvent::Log::Root; |
492 | package AE::Log::Root; |
501 | package AE::Log::Root; |
493 | package AnyEvent::Log::Top; |
502 | package AnyEvent::Log::Top; |
494 | package AE::Log::Top; |
503 | package AE::Log::Top; |
495 | |
504 | |
496 | =back |
|
|
497 | |
|
|
498 | =cut |
|
|
499 | |
|
|
500 | package AnyEvent::Log::Ctx; |
505 | package AnyEvent::Log::Ctx; |
501 | |
506 | |
502 | # 0 1 2 3 4 |
507 | # 0 1 2 3 4 |
503 | # [$title, $level, %$parents, &$logcb, &$fmtcb] |
508 | # [$title, $level, %$parents, &$logcb, &$fmtcb] |
|
|
509 | |
|
|
510 | =item $ctx = new AnyEvent::Log::Ctx methodname => param... |
|
|
511 | |
|
|
512 | This is a convenience constructor that makes it simpler to construct |
|
|
513 | anonymous logging contexts. |
|
|
514 | |
|
|
515 | Each key-value pair results in an invocation of the method of the same |
|
|
516 | name as the key with the value as parameter, unless the value is an |
|
|
517 | arrayref, in which case it calls the method with the contents of the |
|
|
518 | array. The methods are called in the same order as specified. |
|
|
519 | |
|
|
520 | Example: create a new logging context and set both the default logging |
|
|
521 | level, some parent contexts and a logging callback. |
|
|
522 | |
|
|
523 | $ctx = new AnyEvent::Log::Ctx |
|
|
524 | title => "dubious messages", |
|
|
525 | level => "error", |
|
|
526 | log_cb => sub { print STDOUT shift; 0 }, |
|
|
527 | parents => [$ctx1, $ctx, $ctx2], |
|
|
528 | ; |
|
|
529 | |
|
|
530 | =back |
|
|
531 | |
|
|
532 | =cut |
|
|
533 | |
|
|
534 | sub new { |
|
|
535 | my $class = shift; |
|
|
536 | |
|
|
537 | my $ctx = AnyEvent::Log::ctx undef; |
|
|
538 | |
|
|
539 | while (@_) { |
|
|
540 | my ($k, $v) = splice @_, 0, 2; |
|
|
541 | $ctx->$k (ref $v eq "ARRAY" ? @$v : $v); |
|
|
542 | } |
|
|
543 | |
|
|
544 | bless $ctx, $class # do we really support subclassing, hmm? |
|
|
545 | } |
|
|
546 | |
504 | |
547 | |
505 | =head2 CONFIGURING A LOG CONTEXT |
548 | =head2 CONFIGURING A LOG CONTEXT |
506 | |
549 | |
507 | The following methods can be used to configure the logging context. |
550 | The following methods can be used to configure the logging context. |
508 | |
551 | |
… | |
… | |
758 | |
801 | |
759 | 1; |
802 | 1; |
760 | |
803 | |
761 | =back |
804 | =back |
762 | |
805 | |
|
|
806 | =head1 EXAMPLES |
|
|
807 | |
|
|
808 | This section shows some common configurations. |
|
|
809 | |
|
|
810 | =over 4 |
|
|
811 | |
|
|
812 | =item Setting the global logging level. |
|
|
813 | |
|
|
814 | Either put PERL_ANYEVENT_VERBOSE=<number> into your environment before |
|
|
815 | running your program, or modify the log level of the root context: |
|
|
816 | |
|
|
817 | PERL_ANYEVENT_VERBOSE=5 ./myprog |
|
|
818 | |
|
|
819 | $AnyEvent::Log::Root->level ("warn"); |
|
|
820 | |
|
|
821 | =item Append all messages to a file instead of sending them to STDERR. |
|
|
822 | |
|
|
823 | This is affected by the global logging level. |
|
|
824 | |
|
|
825 | open my $fh, ">>", $path |
|
|
826 | or die "$path: $!"; |
|
|
827 | |
|
|
828 | $AnyEvent::Log::Default->log_cb (sub { |
|
|
829 | syswrite $fh, shift; |
|
|
830 | 0 |
|
|
831 | }); |
|
|
832 | |
|
|
833 | =item Write all messages with priority C<error> and higher to a file. |
|
|
834 | |
|
|
835 | This writes them only when the global logging level allows it, because |
|
|
836 | it is attached to the default context which is invoked I<after> global |
|
|
837 | filtering. |
|
|
838 | |
|
|
839 | open my $fh, ">>", $path |
|
|
840 | or die "$path: $!"; |
|
|
841 | |
|
|
842 | $AnyEvent::Log::Default->attach (new AnyEvent::Log::Ctx |
|
|
843 | log_cb => sub { syswrite $fh, shift; 0 }); |
|
|
844 | |
|
|
845 | This writes them regardless of the global logging level, because it is |
|
|
846 | attached to the toplevel context, which receives all messages I<before> |
|
|
847 | the global filtering. |
|
|
848 | |
|
|
849 | $AnyEvent::Log::Top->attach (new AnyEvent::Log::Ctx |
|
|
850 | log_cb => sub { syswrite $fh, shift; 0 }); |
|
|
851 | |
|
|
852 | In both cases, messages are still written to STDOUT. |
|
|
853 | |
|
|
854 | =item Write trace messages (only) from L<AnyEvent::Debug> to the default logging target(s). |
|
|
855 | |
|
|
856 | Attach the CyAnyEvent::Log::Default> context to the C<AnyEvent::Debug> |
|
|
857 | context and increase the C<AnyEvent::Debug> logging level - this simply |
|
|
858 | circumvents the global filtering for trace messages. |
|
|
859 | |
|
|
860 | my $debug = AnyEvent::Debug->AnyEvent::Log::ctx; |
|
|
861 | $debug->attach ($AnyEvent::Log::Default); |
|
|
862 | $debug->levels ("trace"); # not "level"! |
|
|
863 | |
|
|
864 | This of course works for any package. |
|
|
865 | |
|
|
866 | =back |
|
|
867 | |
763 | =head1 AUTHOR |
868 | =head1 AUTHOR |
764 | |
869 | |
765 | Marc Lehmann <schmorp@schmorp.de> |
870 | Marc Lehmann <schmorp@schmorp.de> |
766 | http://home.schmorp.de/ |
871 | http://home.schmorp.de/ |
767 | |
872 | |