10 use IO
::Socket
::Multicast
;
11 use Time
::HiRes
qw( gettimeofday );
17 my $port = $ENV{'LWES_PORT'} || 9191;
18 my $addr = $ENV{'LWES_ADDRESS'} || '224.0.0.69';
29 'verbose' => \
$verbose_opt,
32 'r|root=s' => \
$rootdir,
33 'pidfile=s' => \
$pidfile,
36 pod2usage
(-exitval
=> -1, -verbose
=> 0) if $help_opt;
37 pod2usage
(-exitval
=> -2, -verbose
=> 2) if $man_opt;
39 my $listener = shift @ARGV;
41 # default listener to one which just prints
42 unless (defined($listener))
44 $listener = "LWES::Listeners::EventPrintingListener";
47 # determine the callback which will process each event
48 my $processEventFunc = getProcessEventFunc
($listener, @ARGV);
50 unless (defined $rootdir)
52 # default rootdir to current working directory
56 # pidfile means to daemonize
57 if (defined ($pidfile))
59 # place pidfile in cwd as well
60 unless ($pidfile =~ m
#^/#)
62 $pidfile = "$rootdir/$pidfile";
65 chdir '/' or die "Can't chdir to /: $!";
66 open STDIN
, '/dev/null' or die "Can't read /dev/null: $!";
67 open STDOUT
, '>>/dev/null' or die "Can't write to /dev/null: $!";
68 open STDERR
, '>>/dev/null' or die "Can't write to /dev/null: $!";
69 defined (my $pid = fork) or die "Can't fork: $!";
72 # parent writes pidfile
73 open PID
, ">$pidfile";
80 # child continues daemonizing
81 POSIX
::setsid
() or die "Can't start a new session: $!";
83 open STDOUT
, "> $rootdir/listener.out";
84 open STDERR
, "> $rootdir/listener.err";
88 # set up socket either UDP or Multicast
90 if ($addr eq "0.0.0.0")
92 $sock = IO
::Socket
::INET
->new(LocalPort
=>$port, Proto
=>'udp', Reuse
=>1);
96 $sock = IO
::Socket
::Multicast
->new(LocalPort
=>$port, Reuse
=>1)
97 or die "Can't create socket: $!";
98 # add multicast address
99 $sock->mcast_add($addr) or die "mcast_add: $!";
102 $sock->sockopt(SO_RCVBUF
,(16*1024*1024));
106 my ($message, $peer);
107 die "recv error: $!" unless $peer = recv ($sock, $message, 65535, 0);
108 my ($port, $peeraddr) = sockaddr_in
($peer);
110 my $event = bytesToEvent
($message);
112 # set up a header similiar to the lwes header
113 my ($seconds, $microseconds) = gettimeofday
;
114 my $millis = int($microseconds/1000);
116 $event->{'ReceiptTime'} = $seconds*1000+$millis;
117 $event->{'ReceiptTimeSecs'} = $seconds;
118 $event->{'ReceiptTimeMillis'} = $millis;
119 $event->{'SenderIP'} = inet_ntoa
($peeraddr);
120 $event->{'SenderPort'} = $port;
122 # let the listener process the event
123 $processEventFunc->($event);
132 lwes-perl-event-listener - listens for events on the network
136 lwes-perl-event-listener [options] [<listener> [<args>] | <code>]
139 -m|--addr <ip> Address to listen on
140 (default: 224.0.0.69)
141 -p|--port <port> Port numer to listen on
143 -r|--root <dir> Directory to write logs/pid files
145 --pidfile <filepath> If a pidfile is specified this
146 will daemonize itself.
147 -help Brief help message
148 -man Full Documentation
150 <listener> is the name of a perl module which extends the base
151 listener LWES::Listener and provides an initialize and processEvent
152 method. The <args> are passed directly to the listener constructor.
154 code is perl code which is embedded in a function which takes one
155 argument, a reference to a perl hash which contains the contents
156 of the event called $event
164 The address to listen on, if you are using UDP this should be 0.0.0.0,
165 otherwise it should be a valid multicast address.
169 The port to listen on.
173 The directory to write log and pidfiles when daemonizing
177 The path to a pidfile, it will default to being in the B<root> directory,
178 specifying this option causes the listener to daemonize itself.
182 Print help information
186 Print more verbose help information
192 The lwes-perl-event-listener is a tool for inspecting LWES events that are
193 flowing to a particular machine. It can listen for either multicast or
194 udp events on an ip and port, then process the events as it receives them.
195 It processes events as they appear, so on a heavy LWES stream may not be
196 able to clear the system network buffer before it overflows.
198 There are several ways to use the tool. To just print out events as they
199 are seen it can be invoked as
201 % lwes-perl-event-listener -m <ip> -p <port>
203 If you wish to create a module for handling events a skeleton is as
204 follows (saved as Foo.pm)
210 @Foo::ISA = qw(LWES::Listener);
216 print "Bar : initialize with @_\n";
224 print "Foo : Got event!\n";
229 Which can then be invoked as
231 % lwes-perl-event-listener -m <ip> -p <port> Foo foo_arg
233 This assumes the Foo.pm file is in the directory you invoke the listener
236 Alternatively, you can install a listener into the LWES/Listeners/ directory
237 in the perl LWES distribution (you'll have to find it). In that case the
238 file should look like
240 package LWES::Listeners::Bar;
244 @LWES::Listeners::Bar::ISA = qw(LWES::Listener);
250 print "Bar : initialize with @_\n";
258 print "Bar : Got event!\n";
263 And be saved as Bar.pm in the system LWES/Listeners directory. It can then
266 % lwes-perl-event-listener -m <ip> -p <port> Bar bar_arg
268 Finally, the listener can be passed code which will be wrapped in a function
269 called for each event. An example of this is
271 % lwes-perl-event-listener -m <ip> -p <port> \
272 'print $event->{"EventType"}."\n";'
274 Internally this is wrapped by a function like
278 <code from command line>
281 The $event is a reference to a perl hash. 64-bit values are Math::BigInt