NAME

AnyEvent::Monitor::CPU - monitors your process CPU usage, with high/low watermark triggers

VERSION

version 0.3

SYNOPSIS

use AnyEvent::Monitor::CPU qw( monitor_cpu );

my $monitor = monitor_cpu cb => sub {
    my ($self, $on_off_flag) = @_;

    # look at $on_off_flag
    #   * 1: below the low watermak - you can increase your CPU usage
    #   * 0: above the high watermark - reduce your CPU usage;
  }
;

## Or...

use AnyEvent::Monitor::CPU;

my $monitor = AnyEvent::Monitor::CPU->new(
  cb => sub { ... }
);

## other goodies
my $last_measured_usage = $monitor->usage;
my $have_spare_cpu = $monitor->is_low;
my $we_are_overloaded = $monitor->is_high;

## stats
use Data::Dump qw(pp);
my $stats = $monitor->stats;
print pp($stats);
# {
#   usage_count => 5,
#   usage_sum   => 3.344552,
#   usage_avg   => 0.668910,
#   usage       => 0.540231,
# }

$monitor->reset_stats;
print pp($monitor->stats);
# {
#   usage_count => 0,
#   usage_sum   => 0,
#   usage       => 0.481203,
# }

## monitor stop/start control
$monitor->stop;
$monitor->start;
$monitor->is_running;

DESCRIPTION

This module gives you a CPU monitor with high/low threseholds and triggers.

On a regular basis, it will check the CPU usage of the current process. If the usage is above your designated upper limit for more than a number of samples, it will trigger the provided callback.

If the CPU usage lowers below the provided lower limit for more than a number of samples, it will trigger the callback again.

See the constructor "new()" documentation for all the parameters that you can set, and their default values.

For each transition (above upper limit, below lower limit), the callback will be called only once.

All load values are between 0 and 1, between a idle processor (0) and a full blown fried eggs machine (1).

You can inspect the current state of the monitor. You can check the last usage that was sampled, and the average usage over the last samples.

An API is also provided to stop and restart the monitor.

PERFORMANCE

With the default parameters, the overhead of the CPU monitor is less than 0.05%, as measured on both of my development machines (a MacBook laptop with a 2.16Ghz Intel Core Duo, and a PC with a 2.66Ghz Intel Quad Core).

Please note that if you run your code under Devel::Cover the average loads will most likelly be outside the limits.

METHODS

new()

$cpu = AnyEvent::Monitor::CPU->new( cb => sub {}, ... );
$cpu = AnyEvent::Monitor::CPU->new({ cb => sub {}, ... });

Creates a new AnyEvent::Monitor::CPU object and start the polling process.

The following parameters are accepted:

cb
cb => sub {
  my ($monitor, $high_low_flag) = @_;
  
  say $high_low_flag? "I'm bored..." : "I'm high as a kite!";
},

The callback to be used when the CPU usage rises above or lowers below the defined thresholds.

This parameter is required and it should be a coderef.

The callback will be called with two parameters:

$monitor

The monitor object.

$high_low_flag

Flag with the current state of the CPU usage. The possible values are:

0

The CPU is over the defined high limit.

1

The CPU is under the defined low limit.

Your callback should tune the application to increase or decrease the CPU usage based on the $high_low_flag value.

interval
interval => .1, ## sample 10 times per second

The sample interval. Use fractional values for sub-second intervals.

The default value is .25, so it will sample the CPU usage 4 times per second.

high
high => .40,  ## set the upper limit to 40%

Defines the upper limit for the CPU usage.

The default value is .95.

low
low => .20,  ## set the lower limit to 20%

Defines the lower limit for the CPU usage.

The default value is .80.

high_samples
## Only trigger the cb after 4 consecutive samples above the
## high limit
high_samples => 4,

Set the number of samples above the high limit that we require to trigger the callback.

The default value is 2.

low_samples
## Only trigger the cb after 2 consecutive samples under the
## low limit
low_samples => 4,

Set the number of samples under the low limit that we require to trigger the callback.

The default value is 2.

monitor_cpu()

my $monitor = monitor_cpu cb => sub {}, interval => .1;

A shortcut to AnyEvent::Monitor::CPU->new(@args). All parameters are passed along to the "new()" constructor.

The monitor_cpu() function is not imported by default. You must ask for it.

usage()

$usage = $monitor->usage()

Returns the last sampled CPU usage.

The value returned is between 0 and 1.

is_high()

if ($monitor->is_high()) {
  say "Your eggs will be ready in a minute";
}

Returns true if the CPU usage is over the defined limits.

is_low()

if ($monitor->is_low()) {
  say "Its chilly in here, wanna generate some heat?";
}

Returns true if the CPU usage is below the defined limits.

stats()

my $stats = $monitor->stats;
my $count = $stats->{usage_count};
say "Average usage was $stats->{usage_avg} over the last $count samples"
  if $count;

Returns a hashref with statistics. The following keys are available:

usage

The last usage sample taken. Its the same as $monitor->usage.

usage_count

The number of samples taken since the last \"reset_stats()".

usage_sum

The sum of the samples taken since the last \"reset_stats()".

usage_avg

The average usage since the last \"reset_stats()".

This value is only available if usage_count is non-zero.

reset_stats()

$monitor->reset_stats();

Clears the stats.

stop()

$monitor->stop();

Stops the polling process for the CPU monitor.

start()

$monitor->start();

Starts the polling process for the CPU monitor.

is_running()

if ($monitor->is_running()) {
  say "Big brother is watching, play it cool";
}
else {
  say "Bring on the bacon and eggs, lets make breakfast!";
}

Returns true if the monitor is polling the CPU usage.

SEE ALSO

Proc::CPUUsage.

AUTHOR

Pedro Melo, <melo at cpan.org>

COPYRIGHT & LICENSE

Copyright 2009 Pedro Melo.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

1 POD Error

The following errors were encountered while parsing the POD:

Around line 283:

Expected text after =item, not a number