Apache-Traffic
view release on metacpan or search on metacpan
$STATS{$TODAY} = { $uid => { hits => 0, bytes => 0 }};
}
# MOVE DATA FROM SHARED MEMORY INTO DBM FILE IF > 1 DAY INFO
if ((keys %STATS > 1) and (USE_DBM)) {
unless (_move_shm_to_dbm($r)) {
unless (semop($SEMID, pack "s*", 0, -1, SEM_UNDO)) {
error("unable to release lock: $!");
}
return DECLINED;
}
}
}
$ref = $STATS{$TODAY};
$$ref{$uid}{hits} += 1;
$$ref{$uid}{bytes} += $bytes;
$STATS{$TODAY} = $ref;
unless (semop($SEMID, pack "s*", 0, -1, SEM_UNDO)) {
error("unable to release lock: $!");
return DECLINED;
}
OK;
}
sub handler { shift->post_connection(\&logger) }
1;
__END__
sub error {
my($error, $package, $line, $r);
if (@_) {
($package, $line) = (caller)[0,2];
$ERRMSG = join('', "$package [$line]: ", @_);
eval { $r = Apache->request };
unless ($@) {
$r->log_error($ERRMSG);
}
return undef;
} else {
return $ERRMSG;
}
}
sub fetch {
my($start, $end, $wantuid, $all, @users) = @_;
my(%hash, %uids, $uid, $db_obj, %db, $ref);
$start = timegm(0, 0, 0, (localtime($start))[3..5]); # START OF DAY
$end = timegm(0, 0, 0, (localtime($end))[3..5]);
tie(%STATS, 'IPC::Shareable', SHMKEY, { create => 'no' })
or return error("unable to tie to shared memory: $!");
if (-e DBPATH) { # DBM FILE WON'T EXIST UNTIL HANDLER HAS RUN FOR > 1 DAY
$db_obj = tie %db, 'DB_File', DBPATH, O_RDONLY, MODE
or return error("unable to open dbm file: $!");
}
@users = () if ($all);
foreach(@users) {
# LOOKUP THE USERNAME IF WE WERE PASSED A UID
$_ = (getpwuid $_)[0] || $_ if ($_ =~ /^\d+$/);
# LOOKUP THE UID
(defined($uid = (getpwnam $_)[2])) || ($uid = $_);
# STORE THE USERNAME INDEXED BY UID (unless $wantuid is true)
$uids{$uid} = ($wantuid ? $uid : $_);
}
while($start <= $end) {
unless ($all) {
foreach(keys %uids) { # MAKE SURE WE RETURN VALUES FOR EVERY USER
$hash{$start}{ $uids{$_} } = { bytes => 0, hits => 0 };
}
}
if (exists $STATS{$start}) {
$ref = $STATS{$start};
} elsif ((defined $db_obj) and (exists $db{$start})) {
$ref = thaw($db{$start});
} else {
$start += ONEDAY;
next;
}
if ($all) {
foreach(keys %$ref) {
unless (defined $uids{$_}) {
$uids{$_} = $_;
if ((/^\d+$/) and (! $wantuid)) {
$uids{$_} = (getpwuid $_)[0] || $_;
}
}
}
}
foreach(keys %uids) {
next unless (exists $ref->{$_});
$hash{$start}{ $uids{$_} }{bytes} = $ref->{$_}{bytes};
$hash{$start}{ $uids{$_} }{hits} = $ref->{$_}{hits};
}
$start += ONEDAY;
}
return \%hash;
}
sub remove {
my($start, $end) = @_;
my(%db, $db_obj);
$start = timegm(0, 0, 0, (localtime($start))[3..5]); # START OF DAY
$end = timegm(0, 0, 0, (localtime($end))[3..5]);
tie(%STATS, 'IPC::Shareable', SHMKEY, { create => 'no' })
or return error("unable to tie to shared memory");
if (-e DBPATH) {
$db_obj = tie %db, 'DB_File', DBPATH, O_RDWR, MODE
or return error("unable to tie dbm file: $!");
}
(defined($SEMID = semget(SEMKEY, 1, MODE)))
or return error("unable to obtain semaphore for locking: $!");
semop($SEMID, pack "s*", 0, 0, 0, 0, 1, SEM_UNDO)
or return error("unable to obtain lock: $!");
while($start <= $end) {
delete $STATS{$start};
delete $db{$start} if (defined $db_obj);
$start += ONEDAY;
}
$db_obj->sync if (defined $db_obj);
semop($SEMID, pack "s*", 0, -1, SEM_UNDO)
or return error("unable to release lock: $!");
1;
}
# MOVE ALL DATA IN SHARED MEMORY INTO DBM FILE, _EXCEPT_ FOR CURRENT DAY
sub _move_shm_to_dbm {
my $r = shift;
my(%db);
tie %db, 'DB_File', DBPATH, O_CREAT | O_RDWR, MODE
or return error("unable to tie dbm file: $!");
foreach (keys %STATS) {
next if ($_ == $TODAY);
$db{$_} = freeze($STATS{$_})
or return error("error writing dbm: $!");
delete $STATS{$_};
}
untie %db;
1;
}
=head1 NAME
( run in 0.781 second using v1.01-cache-2.11-cpan-6aa56a78535 )