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';
25 Getopt
::Long
::Configure
("pass_through");
31 'verbose' => \
$verbose_opt,
34 'r|root=s' => \
$rootdir,
35 'pidfile=s' => \
$pidfile,
38 pod2usage
(-exitval
=> -1, -verbose
=> 0) if $help_opt;
39 pod2usage
(-exitval
=> -2, -verbose
=> 2) if $man_opt;
41 my $listener = shift @ARGV;
43 # default listener to one which just prints
44 unless (defined($listener))
46 $listener = "LWES::Listeners::EventPrintingListener";
49 # determine the callback which will process each event
50 my $processEventFunc = getProcessEventFunc
($listener, \
@ARGV);
52 unless (defined $rootdir)
54 # default rootdir to current working directory
58 # pidfile means to daemonize
59 if (defined ($pidfile))
61 # place pidfile in cwd as well
62 unless ($pidfile =~ m
#^/#)
64 $pidfile = "$rootdir/$pidfile";
67 chdir '/' or die "Can't chdir to /: $!";
68 open STDIN
, '/dev/null' or die "Can't read /dev/null: $!";
69 open STDOUT
, '>>/dev/null' or die "Can't write to /dev/null: $!";
70 open STDERR
, '>>/dev/null' or die "Can't write to /dev/null: $!";
71 defined (my $pid = fork) or die "Can't fork: $!";
74 # parent writes pidfile
75 open PID
, ">$pidfile";
82 # child continues daemonizing
83 POSIX
::setsid
() or die "Can't start a new session: $!";
85 open STDOUT
, "> $rootdir/listener.out";
86 open STDERR
, "> $rootdir/listener.err";
90 # set up socket either UDP or Multicast
92 if ($addr eq "0.0.0.0")
94 $sock = IO
::Socket
::INET
->new(LocalPort
=>$port, Proto
=>'udp', Reuse
=>1);
98 $sock = IO
::Socket
::Multicast
->new(LocalPort
=>$port, Reuse
=>1)
99 or die "Can't create socket: $!";
100 # add multicast address
101 $sock->mcast_add($addr) or die "mcast_add: $!";
104 $sock->sockopt(SO_RCVBUF
,(16*1024*1024));
108 my ($message, $peer);
109 die "recv error: $!" unless $peer = recv ($sock, $message, 65535, 0);
110 my ($port, $peeraddr) = sockaddr_in
($peer);
112 my $event = bytesToEvent
($message);
114 # set up a header similiar to the lwes header
115 my ($seconds, $microseconds) = gettimeofday
;
116 my $millis = int($microseconds/1000);
118 $event->{'ReceiptTime'} = $seconds*1000+$millis;
119 $event->{'ReceiptTimeSecs'} = $seconds;
120 $event->{'ReceiptTimeMillis'} = $millis;
121 $event->{'SenderIP'} = inet_ntoa
($peeraddr);
122 $event->{'SenderPort'} = $port;
124 # let the listener process the event
125 $processEventFunc->($event);
134 lwes-perl-event-listener - listens for events on the network
138 lwes-perl-event-listener [options] [<listener> [<args>] | <code>]
141 -m|--addr <ip> Address to listen on
142 (default: 224.0.0.69)
143 -p|--port <port> Port numer to listen on
145 -r|--root <dir> Directory to write logs/pid files
147 --pidfile <filepath> If a pidfile is specified this
148 will daemonize itself.
149 -help Brief help message
150 -man Full Documentation
152 <listener> is the name of a perl module which extends the base
153 listener LWES::Listener and provides an initialize and processEvent
154 method. The <args> are passed directly to the listener constructor.
156 code is perl code which is embedded in a function which takes one
157 argument, a reference to a perl hash which contains the contents
158 of the event called $event
166 The address to listen on, if you are using UDP this should be 0.0.0.0,
167 otherwise it should be a valid multicast address.
171 The port to listen on.
175 The directory to write log and pidfiles when daemonizing
179 The path to a pidfile, it will default to being in the B<root> directory,
180 specifying this option causes the listener to daemonize itself.
184 Print help information
188 Print more verbose help information
194 The lwes-perl-event-listener is a tool for inspecting LWES events that are
195 flowing to a particular machine. It can listen for either multicast or
196 udp events on an ip and port, then process the events as it receives them.
197 It processes events as they appear, so on a heavy LWES stream may not be
198 able to clear the system network buffer before it overflows.
200 There are several ways to use the tool. To just print out events as they
201 are seen it can be invoked as
203 % lwes-perl-event-listener -m <ip> -p <port>
205 If you wish to create a module for handling events a skeleton is as
206 follows (saved as Foo.pm)
214 @Foo::ISA = qw(LWES::Listener);
223 # parse additional options
233 print "Foo : Got event!\n";
238 Which can then be invoked as
240 % lwes-perl-event-listener -m <ip> -p <port> Foo foo_arg
242 This assumes the Foo.pm file is in the directory you invoke the listener
245 Alternatively, you can install a listener into the LWES/Listeners/ directory
246 in the perl LWES distribution (you'll have to find it). In that case the
247 file should look like
249 package LWES::Listeners::Bar;
255 @LWES::Listeners::Bar::ISA = qw(LWES::Listener);
264 # parse additional options
274 print "Bar : Got event!\n";
279 And be saved as Bar.pm in the system LWES/Listeners directory. It can then
282 % lwes-perl-event-listener -m <ip> -p <port> Bar bar_arg
284 Finally, the listener can be passed code which will be wrapped in a function
285 called for each event. An example of this is
287 % lwes-perl-event-listener -m <ip> -p <port> \
288 'print $event->{"EventType"}."\n";'
290 Internally this is wrapped by a function like
294 <code from command line>
297 The $event is a reference to a perl hash. 64-bit values are Math::BigInt