#!/usr/bin/perl -w use strict; $|++; ## CONFIG my $NICK = 'weblogger'; my $CONNECT = {Server => 'irc.some.borg', Nick => $NICK, Ircname => 'weblogger: see merlyn@stonehenge.com', }; my $CHANNEL = '#weblogger'; my $IRC_ALIAS = "irk"; my %FOLLOWS = ( ACCESS => "/var/log/access_log", ERROR => "/var/log/error_log", ); ## END CONFIG my $SKIPPING = 0; # if skipping, how many we've done my $SEND_QUEUE; # cache use POE qw(Component::IRC Wheel::FollowTail); POE::Component::IRC->new($IRC_ALIAS); POE::Session->create (inline_states => {_start => sub { $_[KERNEL]->post($IRC_ALIAS => register => 'all'); $_[KERNEL]->post($IRC_ALIAS => connect => $CONNECT); }, irc_255 => sub { # server is done blabbing $_[KERNEL]->post($IRC_ALIAS => join => $CHANNEL); $_[KERNEL]->yield("heartbeat"); # start heartbeat $_[KERNEL]->yield("my_add", $_) for keys %FOLLOWS; }, (map { ;"irc_$_" => sub { }} qw(join public connected snotice ctcp_action ping notice mode part quit 001 002 003 004 005 250 251 252 253 254 265 266 332 333 353 366 372 375 376)), _child => sub {}, _default => sub { printf "%s: session %s caught an unhandled %s event.\n", scalar localtime(), $_[SESSION]->ID, $_[ARG0]; print "The $_[ARG0] event was given these parameters: ", join(" ", map({"ARRAY" eq ref $_ ? "[@$_]" : "$_"} @{$_[ARG1]})), "\n"; 0; # false for signals }, my_add => sub { 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]); }, }, ); }, my_tailed => sub { 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 } }, my_heartbeat => sub { $_[KERNEL]->yield(my_tailed => time, "heartbeat", "beep"); $_[KERNEL]->delay($_[STATE] => 10); } }, ); POE::Kernel->run;