AnyEvent

 view release on metacpan or  search on metacpan

lib/AnyEvent/Log.pm  view on Meta::CPAN

               "$msg->[1]",
               $msg->[2] + 0,
               "$msg->[3]";

      0
   });

=item $ctx->log_to_warn

Sets the C<log_cb> to simply use C<CORE::warn> to report any messages
(usually this logs to STDERR).

=item $ctx->log_to_file ($path)

Sets the C<log_cb> 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)

Same as C<< ->log_to_file >>, but opens the file for each message. This
is much slower, but allows you to change/move/rename/delete the file at
basically any time.

Needless(?) to say, if you do not want to be bitten by some evil person
calling C<chdir>, the path should be absolute. Doesn't help with
C<chroot>, but hey...

=item $ctx->log_to_syslog ([$facility])

Logs all messages via L<Sys::Syslog>, mapping C<trace> to C<debug> and
all the others in the obvious way. If specified, then the C<$facility> is
used as the facility (C<user>, C<auth>, C<local0> and so on). The default
facility is C<user>.

Note that this function also sets a C<fmt_cb> - the logging part requires
an array reference with [$level, $str] as input.

=cut

sub log_cb {
   my ($ctx, $cb) = @_;

   $ctx->[3] = $cb;
}

sub fmt_cb {
   my ($ctx, $cb) = @_;

   $ctx->[4] = $cb;
}

sub log_to_warn {
   my ($ctx, $path) = @_;

   $ctx->log_cb (sub {
      warn shift;
      0
   });
}

# 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::aio_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::aio_close ($fh, sub {
                        undef $fh;
                        $kick->($kick);
                     });
                  }
               };
            };

            if ($fh) {
               $write->();
            } else {
               AnyEvent::IO::aio_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;



( run in 3.265 seconds using v1.01-cache-2.11-cpan-2398b32b56e )