PVE-mods/PveSensorsV2/PVEMod_Store.pm

167 lines
5.3 KiB
Perl

package PVE::PVEMod::Store;
use strict;
use warnings;
use Exporter 'import';
use File::Path qw(make_path);
use PVE::INotify;
use RRDs;
use PVE::PVEMod::Config qw($RRD_SOCKET $RRD_BASE);
use PVE::PVEMod::Utils qw(debug);
our @EXPORT_OK = qw(
get_nodename
gpu_rrd_path
update_intel_gpu_rrd
update_nvidia_gpu_rrd
);
# ============================================================================
# Node name
# ============================================================================
sub get_nodename {
return PVE::INotify::nodename();
}
# ============================================================================
# RRD path helper
# ============================================================================
sub gpu_rrd_path {
my ($card) = @_;
return "$RRD_BASE/" . get_nodename() . "/$card";
}
# ============================================================================
# Intel GPU RRD
# ============================================================================
sub _ensure_intel_gpu_rrd {
my ($card) = @_;
my $path = gpu_rrd_path($card);
return if -f $path;
my $dir = "$RRD_BASE/" . get_nodename();
make_path($dir, { mode => 0755 }) unless -d $dir;
RRDs::create(
$path,
'--step', '1',
'DS:freq_req:GAUGE:120:0:U',
'DS:freq_act:GAUGE:120:0:U',
'DS:rc6:GAUGE:120:0:100',
'DS:power_gpu:GAUGE:120:0:U',
'DS:power_pkg:GAUGE:120:0:U',
'DS:render_busy:GAUGE:120:0:100',
'DS:blitter_busy:GAUGE:120:0:100',
'DS:video_busy:GAUGE:120:0:100',
'DS:videnh_busy:GAUGE:120:0:100',
'RRA:AVERAGE:0.5:1:1440',
'RRA:AVERAGE:0.5:60:1440',
'RRA:AVERAGE:0.5:1800:1344',
'RRA:AVERAGE:0.5:21600:1464',
'RRA:AVERAGE:0.5:604800:520',
'RRA:MAX:0.5:1:1440',
'RRA:MAX:0.5:60:1440',
'RRA:MAX:0.5:1800:1344',
'RRA:MAX:0.5:21600:1464',
'RRA:MAX:0.5:604800:520',
);
my $err = RRDs::error();
debug(__LINE__, "Created Intel GPU RRD $path: " . ($err // 'OK'));
}
sub update_intel_gpu_rrd {
my ($card, $stats) = @_;
_ensure_intel_gpu_rrd($card);
my $path = gpu_rrd_path($card);
my $freq_req = $stats->{frequency}{requested} // 'U';
my $freq_act = $stats->{frequency}{actual} // 'U';
my $rc6 = $stats->{rc6}{value} // 'U';
my $power_gpu = $stats->{power}{GPU} // 'U';
my $power_pkg = $stats->{power}{Package} // 'U';
my $render_busy = $stats->{engines}{'Render/3D'}{busy} // 'U';
my $blitter = $stats->{engines}{Blitter}{busy} // 'U';
my $video = $stats->{engines}{Video}{busy} // 'U';
my $videnh = $stats->{engines}{VideoEnhance}{busy} // 'U';
my @daemon_args = (-S $RRD_SOCKET) ? ('--daemon', "unix:$RRD_SOCKET") : ();
RRDs::update(
$path,
@daemon_args,
"N:$freq_req:$freq_act:$rc6:$power_gpu:$power_pkg:$render_busy:$blitter:$video:$videnh",
);
my $err = RRDs::error();
debug(__LINE__, "RRD update intel $card: $err") if $err;
}
# ============================================================================
# NVIDIA GPU RRD
# ============================================================================
sub _ensure_nvidia_gpu_rrd {
my ($index) = @_;
my $card = "nvidia$index";
my $path = gpu_rrd_path($card);
return if -f $path;
my $dir = "$RRD_BASE/" . get_nodename();
make_path($dir, { mode => 0755 }) unless -d $dir;
RRDs::create(
$path,
'--step', '1',
'DS:gpu_util:GAUGE:120:0:100',
'DS:mem_util:GAUGE:120:0:100',
'DS:mem_used:GAUGE:120:0:U',
'DS:mem_total:GAUGE:120:0:U',
'DS:power_draw:GAUGE:120:0:U',
'DS:power_limit:GAUGE:120:0:U',
'DS:temp_gpu:GAUGE:120:0:U',
'DS:fan_speed:GAUGE:120:0:100',
'RRA:AVERAGE:0.5:1:1440',
'RRA:AVERAGE:0.5:60:1440',
'RRA:AVERAGE:0.5:1800:1344',
'RRA:AVERAGE:0.5:21600:1464',
'RRA:AVERAGE:0.5:604800:520',
'RRA:MAX:0.5:1:1440',
'RRA:MAX:0.5:60:1440',
'RRA:MAX:0.5:1800:1344',
'RRA:MAX:0.5:21600:1464',
'RRA:MAX:0.5:604800:520',
);
my $err = RRDs::error();
debug(__LINE__, "Created NVIDIA GPU RRD $path: " . ($err // 'OK'));
}
sub update_nvidia_gpu_rrd {
my ($index, $stats) = @_;
_ensure_nvidia_gpu_rrd($index);
my $card = "nvidia$index";
my $path = gpu_rrd_path($card);
my $gpu_util = $stats->{utilization}{gpu} // 'U';
my $mem_util = $stats->{utilization}{memory} // 'U';
my $mem_used = $stats->{memory}{used} // 'U';
my $mem_total = $stats->{memory}{total} // 'U';
my $power_draw = $stats->{power}{draw} // 'U';
my $power_limit = $stats->{power}{limit} // 'U';
my $temp_gpu = $stats->{temperature}{gpu} // 'U';
my $fan_speed = $stats->{fan}{speed} // 'U';
my @daemon_args = (-S $RRD_SOCKET) ? ('--daemon', "unix:$RRD_SOCKET") : ();
RRDs::update(
$path,
@daemon_args,
"N:$gpu_util:$mem_util:$mem_used:$mem_total:$power_draw:$power_limit:$temp_gpu:$fan_speed",
);
my $err = RRDs::error();
debug(__LINE__, "RRD update nvidia$index: $err") if $err;
}
1;