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

# Content
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 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
15 No attempt to buffer log messages on connection loss, or to retransmit
16 lost messages, is done.
17
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 use AnyEvent::Log ();
32 use AnyEvent::Util ();
33
34 use AnyEvent::MP;
35 use AnyEvent::MP::Kernel;
36
37 use base "Exporter";
38
39 AE::log 7 => "starting log catcher service.";
40
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 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
59 $AnyEvent::Log::COLLECT->attach ($ctx);
60
61 # monitor them, silently die
62 mon $rport, sub {
63 $AnyEvent::Log::COLLECT->detach ($ctx);
64 };
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 my ($time, $ctx, $level, $msg) = @_;
74
75 $level = 2 if $level < 2; # do not exit because others do so
76
77 my $diff = $time - AE::now;
78 $diff = $diff < 1e-4 ? "" : sprintf ", %gs", $diff;
79 AE::log $level, "[$node$diff] $msg";
80 };
81
82 # establish connection
83 AnyEvent::MP::Kernel::snd_to_func $node, "AnyEvent::MP::LogCatcher::connect", 0, $lport, $LOGLEVEL;
84
85 mon $node, $lport;
86 }
87
88 =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 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