use strict;
use autodie;
use POSIX;
+use Time::HiRes qw(time sleep);
my $DEBUG = $ENV{DEBUG} || 0;
my $INFLUX = $ENV{INFLUX} || 'http://10.80.3.89:8086/write?db=gnt';
my $node = `hostname -s`;
chomp $node;
-warn $0 = "gnt-monitor\@$node $DC $RACK $INFLUX $INTERVAL $DEBUG";
+my $location = '';
+$location .= qq{,dc=$DC} if $DC;
+$location .= qq{,rack=$RACK} if $RACK;
+
+warn $0 = "gnt-monitor\@$node$location $INFLUX $INTERVAL $DEBUG";
use Data::Dump;
sub XXX { $DEBUG ? warn "XXX ",Data::Dump::dump( @_ ) : {} };
my $skip;
+my $begin_t = time();
+my $t = int( time() * 1000_000_000 );
+
foreach my $instance ( glob '/var/run/ganeti/kvm-hypervisor/pid/*' ) {
open(my $fh, '<', $instance);
if ( my $last_gtime = $last->{$instance}->{gtime} ) {
my $clock_ticks = POSIX::sysconf( &POSIX::_SC_CLK_TCK ); # clock ticks per second
- my $cpu = ( ( $gtime - $last_gtime ) * 100 ) / ( $clock_ticks * $vcpu );
+ my $cpu = ( ( $gtime - $last_gtime ) * 100 ) / ( $clock_ticks * $vcpu ) / $INTERVAL;
$stat->{$instance}->{cpu} = $cpu;
+ $stat->{$instance}->{ticks} = ($gtime - $last_gtime) / $INTERVAL;
}
$last->{$instance}->{gtime} = $gtime;
my @s = split(/\s+/, $v );
# https://www.kernel.org/doc/Documentation/block/stat.txt
my $d = {
- read_io => $s[0],
- read_bytes => $s[2] * 512,
- read_wait => $s[3],
- write_io => $s[4],
- write_bytes => $s[6] * 512,
- write_wait => $s[7],
+ read_io => $s[0] / $INTERVAL,
+ read_bytes => $s[2] * 512 / $INTERVAL,
+ read_wait => $s[3] / $INTERVAL,
+ write_io => $s[4] / $INTERVAL,
+ write_bytes => $s[6] * 512 / $INTERVAL,
+ write_wait => $s[7] / $INTERVAL,
};
if ( my $l = $last->{$instance}->{disk}->[$disk] ) {
my $delta;
foreach my $f (qw( rx_bytes tx_bytes rx_packets tx_packets )) {
open( my $fh, '<', "/sys/class/net/$dev/statistics/$f" );
my $v = <$fh>; chomp $v;
- $d->{$f} = $v;
+ $d->{$f} = $v / $INTERVAL;
}
if ( my $l = $last->{$instance}->{nic}->[$nic] ) {
$stat->{$instance}->{nic}->[$nic]->{$_} = $d->{$_} - $l->{$_} foreach keys %$d;
#XXX $stat;
#XXX $last;
-open(my $fh, '>', '/dev/shm/gnt-monitor.influx');
-
sub dump4influx {
my $hash = shift;
my @v;
foreach my $k ( keys %$hash ) {
my $v = $hash->{$k};
- my ( $d, $s ) = $v =~ m/^\d+$/ ? ( '', 'i' ) :
- $v =~ m/\w+/ ? ( '"', '' ) :
- ( '' , '' ) ; # float
+ my ( $d, $s ) = $v =~ m/^\d+(\.\d+)?$/i ? ( '', '' ) : # float
+ ( '"' ,'' ) ; # string
push @v, "$k=$d$v$d$s";
}
return $i;
}
+open(my $fh, '>', '/dev/shm/gnt-monitor.influx');
+
foreach my $instance ( keys %$stat ) {
next if $skip->{$instance};
- my $location = '';
- $location .= qq{,dc="$DC"} if $DC;
- $location .= qq{,rack="$RACK"} if $RACK;
-
- print $fh qq{cpu,node="$node",instance="$instance"$location cpu=}, $stat->{$instance}->{cpu}, "\n";
+ print $fh qq{ganeti_cpu,node=$node,instance=$instance$location cpu=$stat->{$instance}->{cpu},ticks=$stat->{$instance}->{ticks} $t\n};
foreach my $disk ( @{ $stat->{$instance}->{disk} } ) {
- print $fh qq{disk,node="$node",instance="$instance"$location },dump4influx( $disk ), "\n";
+ print $fh qq{ganeti_disk,node=$node,instance=$instance$location },dump4influx( $disk ), " $t\n";
}
foreach my $nic ( @{ $stat->{$instance}->{nic} } ) {
my $vlan = delete $nic->{vlan};
- print $fh qq{nic,node="$node",instance="$instance",vlan=${vlan}i$location },dump4influx( $nic ), "\n";
+ $vlan = 0 unless defined $vlan;
+ print $fh qq{ganeti_nic,node=$node,instance=$instance,vlan=${vlan}$location },dump4influx( $nic ), " $t\n";
}
}
close($fh);
-system 'curl', '-XPOST', $INFLUX, '--data-binary', '@/dev/shm/gnt-monitor.influx';
+if ( system( 'curl', '-s', '-XPOST', $INFLUX, '--data-binary', '@/dev/shm/gnt-monitor.influx' ) == 0 ) {
+} else {
+ rename '/dev/shm/gnt-monitor.influx', '/dev/shm/gnt-monitor.influx.bug.' . scalar glob '/dev/shm/gnt-monitor.influx.bug.*';
+ warn "curl failed: $? $!";
+}
-sleep $INTERVAL;
+my $dt = time() - $begin_t;
+sleep $INTERVAL - $dt if $dt > 0 && $dt < $INTERVAL;
} #/while