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.13 by root, Sat Aug 20 01:34:12 2011 UTC vs.
Revision 1.16 by root, Sat Aug 20 02:19:18 2011 UTC

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
43This module implements a relatively simple "logging framework". It doesn't 35This module implements a relatively simple "logging framework". It doesn't
44attempt to be "the" logging solution or even "a" logging solution for 36attempt to be "the" logging solution or even "a" logging solution for
57The design goal behind this module was to keep it simple (and small), 49The 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 50but make it powerful enough to be potentially useful for any module, and
59extensive enough for the most common tasks, such as logging to multiple 51extensive enough for the most common tasks, such as logging to multiple
60targets, or being able to log into a database. 52targets, or being able to log into a database.
61 53
54The amount of documentation might indicate otherwise, but the module is
55still just 240 lines or so.
56
62=head1 LOGGING FUNCTIONS 57=head1 LOGGING FUNCTIONS
63 58
64These 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
65package as a "logging module/source". Also, the main logging function is 60package as a "logging module/source". Also, the main logging function is
66callable as C<AnyEvent::log> or C<AE::log> when the C<AnyEvent> module is 61callable as C<AnyEvent::log> or C<AE::log> when the C<AnyEvent> module is
75use Carp (); 70use Carp ();
76use POSIX (); 71use POSIX ();
77 72
78use AnyEvent (); BEGIN { AnyEvent::common_sense } 73use AnyEvent (); BEGIN { AnyEvent::common_sense }
79use AnyEvent::Util (); 74use AnyEvent::Util ();
75
76our $VERSION = $AnyEvent::VERSION;
80 77
81our ($now_int, $now_str1, $now_str2); 78our ($now_int, $now_str1, $now_str2);
82 79
83# Format Time, not public - yet? 80# Format Time, not public - yet?
84sub ft($) { 81sub 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
280Note: currently the enabled var is always true - that will be fixed in a
281future version :)
282
283=cut 277=cut
284 278
285our %LOGGER; 279our %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
308sub _logger($;$) { 302sub _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
388All other (anonymous) contexts have no parents and an empty title by 380All other (anonymous) contexts have no parents and an empty title by
389default. 381default.
390 382
391When the module is loaded it creates the default context called 383When the module is loaded it creates the default context called
392C<AnyEvent::Log::Default> (also stored in C<$AnyEvent::Log::Default>), 384C<AnyEvent::Log::Default> (also stored in C<$AnyEvent::Log::Default>),
393which simply logs everything to STDERR and doesn't propagate anything 385which simply logs everything via C<warn> and doesn't propagate anything
394anywhere by default. The purpose of the default context is to provide 386anywhere by default. The purpose of the default context is to provide
395a convenient place to override the global logging target or to attach 387a convenient place to override the global logging target or to attach
396additional log targets. It's not meant for filtering. 388additional log targets. It's not meant for filtering.
397 389
398It then creates the root context called C<AnyEvent::Log::Root> (also 390It then creates the root context called C<AnyEvent::Log::Root> (also
412C<AE::Log::Top>. 404C<AE::Log::Top>.
413 405
414The effect of all this is that log messages, by default, wander up 406The effect of all this is that log messages, by default, wander up
415to the root context where log messages with lower priority then 407to the root context where log messages with lower priority then
416C<$ENV{PERL_ANYEVENT_VERBOSE}> will be filtered away and then to the 408C<$ENV{PERL_ANYEVENT_VERBOSE}> will be filtered away and then to the
417AnyEvent::Log::Default context to be logged to STDERR. 409AnyEvent::Log::Default context to be passed to C<warn>.
418 410
419Splitting the top level context into three contexts makes it easy to set 411Splitting the top level context into three contexts makes it easy to set
420a global logging level (by modifying the root context), but still allow 412a global logging level (by modifying the root context), but still allow
421other contexts to log, for example, their debug and trace messages to the 413other contexts to log, for example, their debug and trace messages to the
422default target despite the global logging level, or to attach additional 414default target despite the global logging level, or to attach additional
423log targets that log messages, regardless of the global logging level. 415log targets that log messages, regardless of the global logging level.
424 416
425It also makes it easy to replace the default STDERR-logger by something 417It also makes it easy to replace the default warn-logger by something that
426that logs to a file, or to attach additional logging targets. 418logs 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
458Deletes all contexts and recreates the default hierarchy, i.e. resets the 450Resets all package contexts and recreates the default hierarchy if
459logging subsystem to defaults. 451necessary, i.e. resets the logging subsystem to defaults, as much as
452possible. This process keeps references to contexts held by other parts of
453the program intact.
460 454
461This can be used to implement config-file (re-)loading: before loading a 455This can be used to implement config-file (re-)loading: before loading a
462configuration, reset all contexts. 456configuration, reset all contexts.
463 457
464=cut 458=cut
465 459
466sub reset { 460sub 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
490AnyEvent::Log::reset; 495AnyEvent::Log::reset;
491 496
492# hello, CPAN, please catch me 497# hello, CPAN, please catch me
493package AnyEvent::Log::Default; 498package AnyEvent::Log::Default;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines