--- AnyEvent/lib/AnyEvent/Log.pm 2012/03/22 00:19:39 1.48 +++ AnyEvent/lib/AnyEvent/Log.pm 2012/03/30 21:31:52 1.55 @@ -8,15 +8,15 @@ use AnyEvent; - AE::log trace => "going to call function abc"; + AE::log fatal => "No config found, cannot continue!"; # never returns + AE::log alert => "The battery died!"; + AE::log crit => "The battery temperature is too hot!"; + AE::log error => "Division by zero attempted."; + AE::log warn => "Couldn't delete the file."; + AE::log note => "Wanted to create config, but config already exists."; + AE::log info => "File soandso successfully deleted."; AE::log debug => "the function returned 3"; - AE::log info => "file soandso successfully deleted"; - AE::log note => "wanted to create config, but config was already created"; - AE::log warn => "couldn't delete the file"; - AE::log error => "failed to retrieve data"; - AE::log crit => "the battery temperature is too hot"; - AE::log alert => "the battery died"; - AE::log fatal => "no config found, cannot continue"; # never returns + AE::log trace => "going to call function abc"; Log level overview: @@ -63,10 +63,11 @@ module more or less exposes the mechanism, with some extra spiff to allow using it from other modules as well. -Remember that the default verbosity level is C<3> (C), so little -will be logged, unless you set C to a higher number -before starting your program, or change the logging level at runtime with -something like: +Remember that the default verbosity level is C<4> (C), so only +errors and more important messages will be logged, unless you set +C to a higher number before starting your program +(C is recommended during development), or change the logging +level at runtime with something like: use AnyEvent::Log; $AnyEvent::Log::FILTER->level ("info"); @@ -117,6 +118,10 @@ C), because logging a fatal message will also quit the program - so use it sparingly :) +For example, a program that finds an unknown switch on the commandline +might well use a fatal logging level to tell users about it - the "system" +in this case would be the program, or module. + Some methods also offer some extra levels, such as C<0>, C, C or C - these are only valid for the methods that documented them. @@ -861,7 +866,7 @@ =over 4 -=item $ctx->log_cb ($cb->($str) +=item $ctx->log_cb ($cb->($str)) Replaces the logging callback on the context (C disables the logging callback). @@ -896,12 +901,12 @@ default formatter). The callback is passed the (possibly fractional) timestamp, the original -logging context, the (numeric) logging level and the raw message string -and needs to return a formatted log message. In most cases this will be a -string, but it could just as well be an array reference that just stores -the values. +logging context (object, not title), the (numeric) logging level and +the raw message string and needs to return a formatted log message. In +most cases this will be a string, but it could just as well be an array +reference that just stores the values. -If, for some reason, you want to use C to find out more baout the +If, for some reason, you want to use C to find out more about the logger then you should walk up the call stack until you are no longer inside the C package. @@ -915,7 +920,7 @@ }); Example: return an array reference with just the log values, and use -C to store the emssage in a database. +C to store the message in a database. $ctx->fmt_cb (sub { \@_ }); $ctx->log_cb (sub { @@ -937,7 +942,8 @@ =item $ctx->log_to_file ($path) -Sets the C to log to a file (by appending), unbuffered. +Sets the C to log to a file (by appending), unbuffered. The +function might return before the log file has been opened or created. =item $ctx->log_to_path ($path) @@ -982,28 +988,100 @@ }); } +# this function is a good example of why threads are a must, +# simply for priority inversion. +sub _log_to_disk { + # eval'uating this at runtime saves 220kb rss - perl has become + # an insane memory waster. + eval q{ # poor man's autoloading {} + sub _log_to_disk { + my ($ctx, $path, $keepopen) = @_; + + my $fh; + my @queue; + my $delay; + my $disable; + + use AnyEvent::IO (); + + my $kick = sub { + undef $delay; + return unless @queue; + $delay = 1; + + # we pass $kick to $kick, so $kick itself doesn't keep a reference to $kick. + my $kick = shift; + + # write one or more messages + my $write = sub { + # we write as many messages as have been queued + my $data = join "", @queue; + @queue = (); + + AnyEvent::IO::ae_write $fh, $data, sub { + $disable = 1; + @_ + ? ($_[0] == length $data or AE::log 4 => "unable to write to logfile '$path': short write") + : AE::log 4 => "unable to write to logfile '$path': $!"; + undef $disable; + + if ($keepopen) { + $kick->($kick); + } else { + AnyEvent::IO::ae_close ($fh, sub { + undef $fh; + $kick->($kick); + }); + } + }; + }; + + if ($fh) { + $write->(); + } else { + AnyEvent::IO::ae_open + $path, + AnyEvent::IO::O_CREAT | AnyEvent::IO::O_WRONLY | AnyEvent::IO::O_APPEND, + 0666, + sub { + $fh = shift + or do { + $disable = 1; + AE::log 4 => "unable to open logfile '$path': $!"; + undef $disable; + return; + }; + + $write->(); + } + ; + } + }; + + $ctx->log_cb (sub { + return if $disable; + push @queue, shift; + $kick->($kick) unless $delay; + 0 + }); + + $kick->($kick) if $keepopen; # initial open + }; + }; + die if $@; + &_log_to_disk +} + sub log_to_file { my ($ctx, $path) = @_; - open my $fh, ">>", $path - or die "$path: $!"; - - $ctx->log_cb (sub { - syswrite $fh, shift; - 0 - }); + _log_to_disk $ctx, $path, 1; } sub log_to_path { my ($ctx, $path) = @_; - $ctx->log_cb (sub { - open my $fh, ">>", $path - or die "$path: $!"; - - syswrite $fh, shift; - 0 - }); + _log_to_disk $ctx, $path, 0; } sub log_to_syslog { @@ -1043,6 +1121,10 @@ Same as C, but uses the given context as log context. +Example: log a message in the context of another package. + + (AnyEvent::Log::ctx "Other::Package")->log (warn => "heely bo"); + =item $logger = $ctx->logger ($level[, \$enabled]) Same as C, but uses the given context as log @@ -1285,8 +1367,6 @@ } } -1; - =head1 EXAMPLES This section shows some common configurations, both as code, and as @@ -1376,3 +1456,5 @@ =cut +1 +