my %FOLLOWS = ( ACCESS => "/var/log/messages", ); my $IRC_ALIAS = $nick; my $SKIPPING = 0; # if skipping, how many we've done my $SEND_QUEUE; # cache my $CHANNEL = $channel; POE::Session->create( package_states => [ main => [ qw( _default _start irc_public irc_join my_add my_tailed my_heartbeat ) ], ], ); $poe_kernel->run(); sub _start { my $irc = POE::Component::IRC::State->spawn( nick => $nick, Username => $username, ircname => $desc, server => $server_address, ); $_[HEAP]{dns} = POE::Component::Client::DNS->spawn; $_[HEAP]{irc} = $irc; $irc->plugin_add( 'NickServID', POE::Component::IRC::Plugin::NickServID->new( Password => 'iamrobot' ), ); $irc->plugin_add( 'AutoJoin', POE::Component::IRC::Plugin::AutoJoin->new( Channels => $channel, ), ); $irc->yield( register => 'all' ); $irc->yield( 'connect' ); $irc->yield("my_heartbeat"); # start heartbeat $irc->yield("my_add", $_) for keys %FOLLOWS; # start following return; } sub my_add { my $trailing = $_[ARG0]; my $session = $_[SESSION]; POE::Session->create( inline_states => { _start => sub { $_[HEAP]->{wheel} = POE::Wheel::FollowTail->new( Filename => $FOLLOWS{$trailing}, InputEvent => 'got_line', ); }, got_line => sub { $_[KERNEL]->post( $session => my_tailed => time, $trailing, $_[ARG0] ); }, }, ); } sub my_tailed { my ($time, $file, $line) = @_[ARG0..ARG2]; ## $time will be undef on a probe, or a time value if a real line ## PoCo::IRC has throttling built in, but no external visibility ## so this is reaching "under the hood" $SEND_QUEUE ||= $_[KERNEL]->alias_resolve($IRC_ALIAS)->get_heap->{send_queue}; ## handle "no need to keep skipping" transition if ($SKIPPING and @$SEND_QUEUE < 1) { $_[KERNEL]->post($IRC_ALIAS => privmsg => $CHANNEL => "[discarded $SKIPPING messages]"); $SKIPPING = 0; } ## handle potential message display if ($time) { if ($SKIPPING or @$SEND_QUEUE > 3) { # 3 msgs per 10 seconds $SKIPPING++; } else { my @time = localtime $time; $_[KERNEL]->post( $IRC_ALIAS => privmsg => $CHANNEL => sprintf "%02d:%02d:%02d: %s: %s", ($time[2] + 11) % 12 + 1, $time[1], $time[0], $file, $line); } } ## handle re-probe/flush if skipping if ($SKIPPING) { $_[KERNEL]->delay($_[STATE] => 0.5); # $time will be undef } } sub my_heartbeat { $_[KERNEL]->yield(my_tailed => time, "heartbeat", "beep"); $_[KERNEL]->delay($_[STATE] => 10); } # Default event handler, for some reason, stops output after logged in sub _default { my ($event, $args) = @_[ARG0 .. $#_]; my @output = ( "$event: " ); for my $arg (@$args) { if (ref $arg eq 'ARRAY') { push @output, '[' . join ', ', @$arg . ']'; } else { push @output, "'$arg'"; } } print join ' ', @output, "\n"; return; } # Event when a public message is broadcast to a channel sub irc_public { my ($sender, $where, $what) = @_[SENDER, ARG1, ARG2]; my $nick = parse_nick $_[ARG0]; my $irc = $_[SENDER]->get_heap; } # Event when someone joins a channel sub irc_join { my $nick = parse_nick $_[ARG0]; my $channel = $_[ARG1]; my $irc = $_[SENDER]->get_heap; if ($nick eq $irc->nick_name) { $irc->yield(privmsg => $channel, "I am online and responding to commands"); } }