This program is from a Perl Journal article, archived at
http://www.stonehenge.com/merlyn/PerlJournal/col09.html.
#!/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("my_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;