--- AnyEvent-MP/MP/LogCatcher.pm 2009/09/06 00:13:21 1.1 +++ AnyEvent-MP/MP/LogCatcher.pm 2012/03/22 01:24:26 1.5 @@ -8,11 +8,12 @@ =head1 DESCRIPTION -This relatively simple module overrides C<$AnyEvent::MP::Kernel::WARN> on -every node and sends all log messages to the node running this service. +This relatively simple module attaches itself to the +C<$AnyEvent::Log::COLLECT> context on every node and sends all log +messages to the node showing interest via the C function. -No attempt to buffer log messages on connection loss, or retransmit lost -messages, is done. +No attempt to buffer log messages on connection loss, or to retransmit +lost messages, is done. =head1 GLOBALS AND FUNCTIONS @@ -27,6 +28,7 @@ use POSIX (); use AnyEvent (); +use AnyEvent::Log (); use AnyEvent::Util (); use AnyEvent::MP; @@ -34,7 +36,7 @@ use base "Exporter"; -$AnyEvent::MP::Kernel::WARN->(7, "starting log catcher service."); +AE::log 7 => "starting log catcher service."; our $LOGLEVEL; our %lport; # local logging ports @@ -43,18 +45,22 @@ sub connect { my ($version, $rport, $loglevel) = @_; - my $cb = sub { - snd $rport, @_ - if $_[0] <= $loglevel; - }; - - rcv $SELF, sub { };#d# + my $ctx = new AnyEvent::Log::Ctx + title => "AnyEvent::MP::LogCatcher", + level => $loglevel, + log_cb => sub { + snd $rport, @{ $_[0] }; + }, + fmt_cb => sub { + [$_[0], $_[1]->title, $_[2], $_[3]] + }, + ; - push @AnyEvent::MP::Kernel::WARN, $cb; + $AnyEvent::Log::COLLECT->attach ($ctx); # monitor them, silently die mon $rport, sub { - @AnyEvent::MP::Kernel::WARN = grep $_ != $cb, @AnyEvent::MP::Kernel::WARN; + $AnyEvent::Log::COLLECT->detach ($ctx); }; } @@ -64,26 +70,34 @@ return unless $is_up; my $lport = $lport{$node} = port { - my ($level, $msg) = @_; + my ($time, $ctx, $level, $msg) = @_; - $msg =~ s/\n$//; + $level = 2 if $level < 2; # do not exit because others do so - printf STDERR "%s [%s] <%d> %s\n", - (POSIX::strftime "%Y-%m-%d %H:%M:%S", localtime time), - $node, - $level, - $msg; + my $diff = $time - AE::now; + $diff = $diff < 1e-4 ? "" : sprintf ", %gs", $diff; + AE::log $level, "[$node$diff] $msg"; }; # establish connection - my $rport = spawn $node, "AnyEvent::MP::LogCatcher::connect", 0, $lport, $LOGLEVEL; + AnyEvent::MP::Kernel::snd_to_func $node, "AnyEvent::MP::LogCatcher::connect", 0, $lport, $LOGLEVEL; - mon $rport, $lport; - mon $lport, sub { - warn "$lport $rport <@_>\n";#d# - }; + mon $node, $lport; } +=item AnyEvent::MP::LogCatcher::catch [$level] + +Starts catching all log messages from all nodes with level C<$level> or +lower. If the C<$level> is C, then stop catching all messages +again. + +Example: start a node that catches all messages (you might have to specify +a suitable profile name). + + aemp run profilename services '[["AnyEvent::MP::LogCatcher::catch",9]]' + +=cut + sub catch { $LOGLEVEL = $_[0]; kil $_, "restart" for values %lport;