Skip to content

Commit

Permalink
add Prometheus compatible metrics endpoint cgi to examples
Browse files Browse the repository at this point in the history
  • Loading branch information
vergoh committed Aug 29, 2022
1 parent 0885c9a commit 1c9d718
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
- Add --style support to -tr / --traffic output
- Add summary option to --json and --xml outputs
- Add timestamps to --json and --xml outputs
- Add Prometheus compatible metrics endpoint cgi to examples
(examples/vnstat-metrics.cgi)


2.9 / 23-Jan-2022
Expand Down
118 changes: 118 additions & 0 deletions examples/vnstat-metrics.cgi
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#!/usr/bin/perl -w

# vnstat-metrics.cgi -- Prometheus compatible metrics endpoint output from vnStat data
# copyright (c) 2022 Teemu Toivola <tst at iki dot fi>
# released under the GNU General Public License

use strict;
use JSON::PP;

# location of vnstat binary
my $vnstat_cmd = '/usr/bin/vnstat';


################


sub get_interface_alias
{
my ($interface) = @_;
my $interface_alias = $interface->{'alias'};
if (length($interface_alias) == 0) {
$interface_alias = $interface->{'name'};
}
return $interface_alias;
}

sub print_totals
{
my ($data) = @_;

print "\n# HELP vnstat_interface_total_received_bytes All time total received (rx) bytes\n";
print "# TYPE vnstat_interface_total_received_bytes counter\n";

foreach my $interface ( @{ $data->{'interfaces'} } ) {
my $interface_alias = get_interface_alias($interface);
print "vnstat_interface_total_received_bytes{interface=\"$interface->{'name'}\",alias=\"$interface_alias\"} $interface->{'traffic'}{'total'}{'rx'} $interface->{'updated'}{'timestamp'}000\n";
}

print "\n# HELP vnstat_interface_total_transmitted_bytes All time total transmitted (tx) bytes\n";
print "# TYPE vnstat_interface_total_transmitted_bytes counter\n";

foreach my $interface ( @{ $data->{'interfaces'} } ) {
my $interface_alias = get_interface_alias($interface);
print "vnstat_interface_total_transmitted_bytes{interface=\"$interface->{'name'}\",alias=\"$interface_alias\"} $interface->{'traffic'}{'total'}{'tx'} $interface->{'updated'}{'timestamp'}000\n";
}
}

sub print_data_resolution
{
my ($resolution, $data) = @_;
my $output_count = 0;

print "\n# HELP vnstat_interface_".$resolution."_received_bytes Received (rx) bytes for current $resolution\n";
print "# TYPE vnstat_interface_".$resolution."_received_bytes gauge\n";

$output_count = 0;
foreach my $interface ( @{ $data->{'interfaces'} } ) {
my $interface_alias = get_interface_alias($interface);
if (defined $interface->{'traffic'}{$resolution}) {
print "vnstat_interface_".$resolution."_received_bytes{interface=\"$interface->{'name'}\",alias=\"$interface_alias\"} $interface->{'traffic'}{$resolution}[0]{'rx'} $interface->{'updated'}{'timestamp'}000\n";
$output_count++;
}
}
if ($output_count == 0) {
print "# no data\n";
}

print "\n# HELP vnstat_interface_".$resolution."_transmitted_bytes Transmitted (tx) bytes for current $resolution\n";
print "# TYPE vnstat_interface_".$resolution."_transmitted_bytes gauge\n";

$output_count = 0;
foreach my $interface ( @{ $data->{'interfaces'} } ) {
my $interface_alias = get_interface_alias($interface);
if (defined $interface->{'traffic'}{$resolution}) {
print "vnstat_interface_".$resolution."_transmitted_bytes{interface=\"$interface->{'name'}\",alias=\"$interface_alias\"} $interface->{'traffic'}{$resolution}[0]{'tx'} $interface->{'updated'}{'timestamp'}000\n";
$output_count++;
}
}
if ($output_count == 0) {
print "# no data\n";
}
}

my @data_resolutions = ('fiveminute', 'hour', 'day', 'month', 'year');

print "Content-Type: text/plain\n\n";

my $json_data = `$vnstat_cmd --json s 1`;

my $data = "";
eval { $data = decode_json($json_data) };
if ($@) {
print "# Error: Invalid command output: $json_data\n";
exit 1;
}

if (not defined $data->{'vnstatversion'}) {
print "# Error: Expected content from command output missing\n";
exit 1;
}

if (not defined $data->{'interfaces'}[0]) {
print "# Error: No interfaces found in command output\n";
exit 1;
}

if (not defined $data->{'interfaces'}[0]{'created'}{'timestamp'}) {
print "# Error: Incompatible vnStat version used\n";
exit 1;
}

print "# vnStat version: ".$data->{'vnstatversion'}."\n";

print_totals($data);

foreach my $data_resolution ( @data_resolutions ) {
print_data_resolution($data_resolution, $data);
}

0 comments on commit 1c9d718

Please sign in to comment.