File Coverage

blib/lib/Proc/LoadMonitor.pm
Criterion Covered Total %
statement 50 50 100.0
branch 6 10 60.0
condition 7 11 63.6
subroutine 9 9 100.0
pod 3 4 75.0
total 75 84 89.2


line stmt bran cond sub pod time code
1             package Proc::LoadMonitor;
2             $Proc::LoadMonitor::VERSION = '0.003';
3 1     1   45170 use Time::HiRes qw(tv_interval gettimeofday);
  1         8776  
  1         7  
4 1     1   3782 use Moo;
  1         27568  
  1         8  
5 1     1   1912 use strict;
  1         2  
  1         42  
6 1     1   6 use warnings;
  1         2  
  1         947  
7              
8             has '__load_log' => ( is => 'ro', default => sub { [] } );
9              
10             has '__start_busy' => ( is => 'rw' );
11              
12             has '__start_idle' => ( is => 'rw' );
13              
14             has '__start_time' => ( is => 'rw' );
15              
16             has 'state' => ( is => 'rw' );
17              
18             has 'jobs' => ( is => 'rw', default => 0 );
19              
20             has 'loops' => ( is => 'rw', default => 0 );
21              
22             sub BUILD {
23 1     1 0 15 my ($self) = @_;
24 1         14 my $timeofday = [gettimeofday];
25 1         10 $self->__start_idle($timeofday);
26 1         4 $self->__start_time($timeofday);
27 1         29 $self->state('idle');
28             }
29              
30             sub busy {
31 11     11 1 57 my ($self) = @_;
32 11 50       36 return if $self->state eq 'busy';
33 11         47 $self->__start_busy( [gettimeofday] );
34 11         31 $self->jobs( $self->jobs + 1 );
35 11         33 $self->state('busy');
36             }
37              
38             sub idle {
39 16     16 1 2000920 my ($self) = @_;
40 16         41 $self->loops( $self->loops + 1 );
41 16 100       47 return if $self->state eq 'idle';
42 11         45 $self->__start_idle( [gettimeofday] );
43 11         79 my $elapsed = tv_interval( $self->__start_busy );
44 11         160 my $time_slot = __time_slot();
45 11         31 my $load_log = $self->__load_log;
46 11         23 $load_log->[$time_slot] += $elapsed;
47 11         37 $load_log->[ __time_slot( $time_slot, $_ ) ] = undef for 1 .. 15;
48 11         48 $self->state('idle');
49             }
50              
51             sub report {
52 1     1 1 497 my ($self) = @_;
53 1         4 my $time_slot = __time_slot();
54 1         4 my $load_log = $self->__load_log;
55 1         8 my $seconds = (localtime)[0];
56 1         3 my $sum_05 = $load_log->[$time_slot];
57 1   50     6 $sum_05 += $load_log->[ __time_slot( $time_slot, -$_ ) ] // 0 for 1 .. 5;
58 1         3 my $load_05 = $sum_05 / ( 300 + $seconds );
59 1         1 my $sum_10 = $sum_05;
60 1   50     4 $sum_10 += $load_log->[ __time_slot( $time_slot, -$_ ) ] // 0 for 6 .. 10;
61 1         4 my $load_10 = $sum_10 / ( 600 + $seconds );
62 1         1 my $sum_15 = $sum_10;
63 1   50     4 $sum_15 += $load_log->[ __time_slot( $time_slot, -$_ ) ] // 0 for 11 .. 15;
64 1         2 my $load_15 = $sum_15 / ( 900 + $seconds );
65             return {
66 1 50       27 load_05 => sprintf( '%.3f', $load_05 > 1 ? 1 : $load_05 ),
    50          
    50          
67             load_10 => sprintf( '%.3f', $load_10 > 1 ? 1 : $load_10 ),
68             load_15 => sprintf( '%.3f', $load_15 > 1 ? 1 : $load_15 ),
69             total => tv_interval( $self->__start_time ),
70             loops => $self->loops,
71             jobs => $self->jobs,
72             state => $self->state,
73             };
74             }
75              
76             sub __time_slot {
77 192     192   197 my ( $base, $offset ) = @_;
78 192   66     722 $base //= (localtime)[1]; # minutes
79 192   100     410 $offset //= 0;
80 192         542 return ( $base + $offset + 60 ) % 60;
81             }
82              
83             1; # track-id: 3a59124cfcc7ce26274174c962094a20
84              
85             __END__