ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-MP/MP/LogCatcher.pm
Revision: 1.5
Committed: Thu Mar 22 01:24:26 2012 UTC (12 years, 2 months ago) by root
Branch: MAIN
Changes since 1.4: +24 -18 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 =head1 NAME
2    
3     AnyEvent::MP::LogCatcher - catch all logs from all nodes
4    
5     =head1 SYNOPSIS
6    
7     use AnyEvent::MP::LogCatcher;
8    
9     =head1 DESCRIPTION
10    
11 root 1.5 This relatively simple module attaches itself to the
12     C<$AnyEvent::Log::COLLECT> context on every node and sends all log
13     messages to the node showing interest via the C<catch> function.
14 root 1.1
15 root 1.5 No attempt to buffer log messages on connection loss, or to retransmit
16     lost messages, is done.
17 root 1.1
18     =head1 GLOBALS AND FUNCTIONS
19    
20     =over 4
21    
22     =cut
23    
24     package AnyEvent::MP::LogCatcher;
25    
26     use common::sense;
27     use Carp ();
28     use POSIX ();
29    
30     use AnyEvent ();
31 root 1.5 use AnyEvent::Log ();
32 root 1.1 use AnyEvent::Util ();
33    
34     use AnyEvent::MP;
35     use AnyEvent::MP::Kernel;
36    
37     use base "Exporter";
38    
39 root 1.5 AE::log 7 => "starting log catcher service.";
40 root 1.1
41     our $LOGLEVEL;
42     our %lport; # local logging ports
43    
44     # other nodes connect via this
45     sub connect {
46     my ($version, $rport, $loglevel) = @_;
47    
48 root 1.5 my $ctx = new AnyEvent::Log::Ctx
49     title => "AnyEvent::MP::LogCatcher",
50     level => $loglevel,
51     log_cb => sub {
52     snd $rport, @{ $_[0] };
53     },
54     fmt_cb => sub {
55     [$_[0], $_[1]->title, $_[2], $_[3]]
56     },
57     ;
58 root 1.1
59 root 1.5 $AnyEvent::Log::COLLECT->attach ($ctx);
60 root 1.1
61     # monitor them, silently die
62     mon $rport, sub {
63 root 1.5 $AnyEvent::Log::COLLECT->detach ($ctx);
64 root 1.1 };
65     }
66    
67     sub mon_node {
68     my ($node, $is_up) = @_;
69    
70     return unless $is_up;
71    
72     my $lport = $lport{$node} = port {
73 root 1.5 my ($time, $ctx, $level, $msg) = @_;
74 root 1.1
75 root 1.5 $level = 2 if $level < 2; # do not exit because others do so
76 root 1.1
77 root 1.5 my $diff = $time - AE::now;
78     $diff = $diff < 1e-4 ? "" : sprintf ", %gs", $diff;
79     AE::log $level, "[$node$diff] $msg";
80 root 1.1 };
81    
82     # establish connection
83 root 1.4 AnyEvent::MP::Kernel::snd_to_func $node, "AnyEvent::MP::LogCatcher::connect", 0, $lport, $LOGLEVEL;
84 root 1.1
85 root 1.4 mon $node, $lport;
86 root 1.1 }
87    
88 root 1.3 =item AnyEvent::MP::LogCatcher::catch [$level]
89    
90     Starts catching all log messages from all nodes with level C<$level> or
91     lower. If the C<$level> is C<undef>, then stop catching all messages
92     again.
93    
94     Example: start a node that catches all messages (you might have to specify
95     a suitable profile name).
96    
97     aemp run profilename services '[["AnyEvent::MP::LogCatcher::catch",9]]'
98    
99     =cut
100    
101 root 1.1 sub catch {
102     $LOGLEVEL = $_[0];
103     kil $_, "restart" for values %lport;
104     %lport = ();
105    
106     return unless defined $LOGLEVEL;
107    
108     mon_node $_, 1
109     for up_nodes;
110    
111     mon_nodes \&mon_node;
112     ()
113     }
114    
115     =back
116    
117     =head1 SEE ALSO
118    
119     L<AnyEvent::MP>.
120    
121     =head1 AUTHOR
122    
123     Marc Lehmann <schmorp@schmorp.de>
124     http://home.schmorp.de/
125    
126     =cut
127    
128     1
129