]> git.proxmox.com Git - pmg-api.git/commitdiff
PMG/API2/Nodes.pm: add rrddata API
authorDietmar Maurer <dietmar@proxmox.com>
Fri, 24 Mar 2017 16:02:47 +0000 (17:02 +0100)
committerDietmar Maurer <dietmar@proxmox.com>
Fri, 24 Mar 2017 16:02:47 +0000 (17:02 +0100)
PMG/API2/Nodes.pm
PMG/Utils.pm

index 41d6f2dadf25e8a93c7eedf9ab40afd8f20416b6..b778eadb9e89862fa4bb40d2b2b2681681ef8949 100644 (file)
@@ -74,6 +74,45 @@ __PACKAGE__->register_method ({
        return $result;
     }});
 
+__PACKAGE__->register_method({
+    name => 'rrddata',
+    path => 'rrddata',
+    method => 'GET',
+    protected => 1, # fixme: can we avoid that?
+    proxyto => 'node',
+    description => "Read node RRD statistics",
+    parameters => {
+       additionalProperties => 0,
+       properties => {
+           node => get_standard_option('pve-node'),
+           timeframe => {
+               description => "Specify the time frame you are interested in.",
+               type => 'string',
+               enum => [ 'hour', 'day', 'week', 'month', 'year' ],
+           },
+           cf => {
+               description => "The RRD consolidation function",
+               type => 'string',
+               enum => [ 'AVERAGE', 'MAX' ],
+               optional => 1,
+           },
+       },
+    },
+    returns => {
+       type => "array",
+       items => {
+           type => "object",
+           properties => {},
+       },
+    },
+    code => sub {
+       my ($param) = @_;
+
+       return PMG::Utils::create_rrd_data(
+           "pmg-node-v1.rrd", $param->{timeframe}, $param->{cf});
+    }});
+
+
 __PACKAGE__->register_method({
     name => 'syslog',
     path => 'syslog',
index 7326979a1f2708317803f4cce909d1876f2c92f0..ca7cfa1fa5f79d701c4e955ad94cb7e469cfbb80 100644 (file)
@@ -670,4 +670,60 @@ sub update_node_status_rrd {
     die "RRD error: $err\n" if $err;
 }
 
+sub create_rrd_data {
+    my ($rrdname, $timeframe, $cf) = @_;
+
+    my $rrd = "${rrd_dir}/$rrdname";
+
+    my $setup = {
+       hour =>  [ 60, 70 ],
+       day  =>  [ 60*30, 70 ],
+       week =>  [ 60*180, 70 ],
+       month => [ 60*720, 70 ],
+       year =>  [ 60*10080, 70 ],
+    };
+
+    my ($reso, $count) = @{$setup->{$timeframe}};
+    my $ctime  = $reso*int(time()/$reso);
+    my $req_start = $ctime - $reso*$count;
+
+    $cf = "AVERAGE" if !$cf;
+
+    my @args = (
+       "-s" => $req_start,
+       "-e" => $ctime - 1,
+       "-r" => $reso,
+       );
+
+    push @args, "--daemon" => "unix:${rrdcached_socket}"
+       if -S $rrdcached_socket;
+
+    my ($start, $step, $names, $data) = RRDs::fetch($rrd, $cf, @args);
+
+    my $err = RRDs::error;
+    die "RRD error: $err\n" if $err;
+
+    die "got wrong time resolution ($step != $reso)\n"
+       if $step != $reso;
+
+    my $res = [];
+    my $fields = scalar(@$names);
+    for my $line (@$data) {
+       my $entry = { 'time' => $start };
+       $start += $step;
+       for (my $i = 0; $i < $fields; $i++) {
+           my $name = $names->[$i];
+           if (defined(my $val = $line->[$i])) {
+               $entry->{$name} = $val;
+           } else {
+               # leave empty fields undefined
+               # maybe make this configurable?
+           }
+       }
+       push @$res, $entry;
+    }
+
+    return $res;
+}
+
 1;