AnyEvent-Monitor-CPU
view release on metacpan or search on metacpan
lib/AnyEvent/Monitor/CPU.pm view on Meta::CPAN
package AnyEvent::Monitor::CPU;
our $VERSION = '0.3';
use common::sense;
use AnyEvent;
use Proc::CPUUsage;
use Carp qw( croak );
use parent qw( Exporter );
@AnyEvent::Monitor::CPU::EXPORT_OK = ('monitor_cpu');
## Shortcut, optional import
sub monitor_cpu { return __PACKAGE__->new(@_) }
sub new {
my $class = shift;
my %args = @_ == 1 ? %{$_[0]} : @_;
my $self = bless {
cb => delete $args{cb},
interval => delete $args{interval} || .25,
high => delete $args{high} || .95,
low => delete $args{low} || .80,
high_samples => delete $args{high_samples} || 2,
low_samples => delete $args{low_samples} || 2,
cur_high_samples => 0,
cur_low_samples => 0,
cpu => Proc::CPUUsage->new,
usage => undef,
state => 1,
}, $class;
croak("Required parameter 'cb' not found, ") unless $self->{cb};
croak("Parameter 'cb' must be a coderef, ") unless ref $self->{cb} eq 'CODE';
$self->start;
return $self;
}
sub start {
my $self = shift;
$self->{timer} = AnyEvent->timer(
after => $self->{interval},
interval => $self->{interval},
cb => sub { $self->_check_cpu },
);
$self->{usage} = $self->{cpu}->usage;
$self->reset_stats;
return;
}
sub stop { delete $_[0]->{timer} }
sub is_running { $_[0]->{timer} }
sub usage { return $_[0]->{usage} }
sub is_low { return $_[0]->{state} == 1 }
sub is_high { return $_[0]->{state} == 0 }
sub reset_stats {
my ($self) = @_;
$self->{usage_sum} = 0;
$self->{usage_count} = 0;
}
sub stats {
my ($self) = @_;
my %stats;
my ($count, $sum);
if ($count = $self->{usage_count}) {
$sum = $self->{usage_sum};
$stats{usage_avg} = $sum/$count;
}
$stats{usage_count} = $count;
$stats{usage_sum} = $sum;
$stats{usage} = $self->{usage};
return \%stats;
}
sub _check_cpu {
my $self = $_[0];
my $chs = $self->{current_high_samples};
my $cls = $self->{current_low_samples};
my $usage = $self->{usage} = $self->{cpu}->usage;
if ($usage > $self->{high}) { $chs++; $cls = 0 }
elsif ($usage < $self->{low}) { $cls++; $chs = 0 }
else {
$chs-- if $chs;
$cls-- if $cls;
}
$self->{usage_sum} += $usage;
$self->{usage_count}++;
my $hs = $self->{high_samples};
my $ls = $self->{low_samples};
my $state = $self->{state};
my $trigger = 0;
if ($chs >= $hs) {
$chs = $hs;
if ($state) {
$state = 0;
$trigger = 1;
}
}
elsif ($cls >= $ls) {
$cls = $ls;
if (!$state) {
$state = 1;
$trigger = 1;
}
( run in 1.392 second using v1.01-cache-2.11-cpan-13bb782fe5a )