vnstat-metrics.cgi 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #!/usr/bin/perl -w
  2. # vnstat-metrics.cgi -- Prometheus compatible metrics endpoint output from vnStat data
  3. # copyright (c) 2022 Teemu Toivola <tst at iki dot fi>
  4. # released under the GNU General Public License
  5. use strict;
  6. use JSON::PP;
  7. # location of vnstat binary
  8. my $vnstat_cmd = '/usr/bin/vnstat';
  9. ################
  10. sub get_interface_alias
  11. {
  12. my ($interface) = @_;
  13. my $interface_alias = $interface->{'alias'};
  14. if (length($interface_alias) == 0) {
  15. $interface_alias = $interface->{'name'};
  16. }
  17. return $interface_alias;
  18. }
  19. sub print_totals
  20. {
  21. my ($data) = @_;
  22. print "\n# HELP vnstat_interface_total_received_bytes All time total received (rx) bytes\n";
  23. print "# TYPE vnstat_interface_total_received_bytes counter\n";
  24. foreach my $interface ( @{ $data->{'interfaces'} } ) {
  25. my $interface_alias = get_interface_alias($interface);
  26. print "vnstat_interface_total_received_bytes{interface=\"$interface->{'name'}\",alias=\"$interface_alias\"} $interface->{'traffic'}{'total'}{'rx'} $interface->{'updated'}{'timestamp'}000\n";
  27. }
  28. print "\n# HELP vnstat_interface_total_transmitted_bytes All time total transmitted (tx) bytes\n";
  29. print "# TYPE vnstat_interface_total_transmitted_bytes counter\n";
  30. foreach my $interface ( @{ $data->{'interfaces'} } ) {
  31. my $interface_alias = get_interface_alias($interface);
  32. print "vnstat_interface_total_transmitted_bytes{interface=\"$interface->{'name'}\",alias=\"$interface_alias\"} $interface->{'traffic'}{'total'}{'tx'} $interface->{'updated'}{'timestamp'}000\n";
  33. }
  34. }
  35. sub print_data_resolution
  36. {
  37. my ($resolution, $data) = @_;
  38. my $output_count = 0;
  39. print "\n# HELP vnstat_interface_".$resolution."_received_bytes Received (rx) bytes for current $resolution\n";
  40. print "# TYPE vnstat_interface_".$resolution."_received_bytes gauge\n";
  41. $output_count = 0;
  42. foreach my $interface ( @{ $data->{'interfaces'} } ) {
  43. my $interface_alias = get_interface_alias($interface);
  44. if (defined $interface->{'traffic'}{$resolution}) {
  45. print "vnstat_interface_".$resolution."_received_bytes{interface=\"$interface->{'name'}\",alias=\"$interface_alias\"} $interface->{'traffic'}{$resolution}[0]{'rx'} $interface->{'updated'}{'timestamp'}000\n";
  46. $output_count++;
  47. }
  48. }
  49. if ($output_count == 0) {
  50. print "# no data\n";
  51. }
  52. print "\n# HELP vnstat_interface_".$resolution."_transmitted_bytes Transmitted (tx) bytes for current $resolution\n";
  53. print "# TYPE vnstat_interface_".$resolution."_transmitted_bytes gauge\n";
  54. $output_count = 0;
  55. foreach my $interface ( @{ $data->{'interfaces'} } ) {
  56. my $interface_alias = get_interface_alias($interface);
  57. if (defined $interface->{'traffic'}{$resolution}) {
  58. print "vnstat_interface_".$resolution."_transmitted_bytes{interface=\"$interface->{'name'}\",alias=\"$interface_alias\"} $interface->{'traffic'}{$resolution}[0]{'tx'} $interface->{'updated'}{'timestamp'}000\n";
  59. $output_count++;
  60. }
  61. }
  62. if ($output_count == 0) {
  63. print "# no data\n";
  64. }
  65. }
  66. my @data_resolutions = ('fiveminute', 'hour', 'day', 'month', 'year');
  67. print "Content-Type: text/plain\n\n";
  68. my $json_data = `$vnstat_cmd --json s 1`;
  69. my $data = "";
  70. eval { $data = decode_json($json_data) };
  71. if ($@) {
  72. print "# Error: Invalid command output: $json_data\n";
  73. exit 1;
  74. }
  75. if (not defined $data->{'vnstatversion'}) {
  76. print "# Error: Expected content from command output missing\n";
  77. exit 1;
  78. }
  79. if (not defined $data->{'interfaces'}[0]) {
  80. print "# Error: No interfaces found in command output\n";
  81. exit 1;
  82. }
  83. if (not defined $data->{'interfaces'}[0]{'created'}{'timestamp'}) {
  84. print "# Error: Incompatible vnStat version used\n";
  85. exit 1;
  86. }
  87. print "# vnStat version: ".$data->{'vnstatversion'}."\n";
  88. print_totals($data);
  89. foreach my $data_resolution ( @data_resolutions ) {
  90. print_data_resolution($data_resolution, $data);
  91. }