2 # vim: shiftwidth=4 tabstop=4
4 # This CGI program is a Prometheus exporter for pppd's lcp-rtt-file feature.
6 # Copyright (C) Marco d'Itri <md@linux.it>
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version.
17 use List::Util qw(sum max min);
20 my $data = read_data('/run/ppp-rtt.data');
21 my $stats = compute_statistics($data, 60);
23 my $s = metrics($stats);
24 my $length = length($s);
26 print "Content-type: text/plain\n";
27 print "Content-length: $length\n\n$s";
35 # TYPE lcp_rtt_status gauge
37 lcp_rtt_status $stats->{status}
39 foreach (qw(average min max loss)) {
40 next if not exists $stats->{$_};
42 # TYPE lcp_rtt_$_ gauge
44 lcp_rtt_$_ $stats->{$_}
51 sub compute_statistics {
52 my ($data, $length) = @_;
54 my $cutoff = time() - $length;
55 my @e = grep { $_->[0] >= $cutoff } @{ $data->{data} };
56 return { status => -1 } if not @e; # no data
58 my $average = (sum map { $_->[1] } @e) / scalar(@e);
59 my $min = min map { $_->[1] } @e;
60 my $max = max map { $_->[1] } @e;
61 my $loss = sum map { $_->[2] } @e;
64 status => $data->{status},
76 open(my $fh, '<', $file);
80 $bytes_read = sysread($fh, $data, 8192, length($data));
81 } while ($bytes_read == 8192);
84 my ($magic, $status, $position, $echo_interval, $rest)
85 = unpack('NNNN a*', $data);
86 return undef if $magic != 0x19450425;
88 # the position is relative to the C array, not to the logical entries
91 my @rawdata = unpack('(N C a3)*', $rest);
93 while (my ($time, $loss, $rtt) = splice(@rawdata, 0, 3)) {
94 push(@data, [ $time, unpack('N', "\000$rtt"), $loss ]);
98 # skip any "empty" (null) entries
100 # rearrange the list in chronological order
101 (@data[$position+1 .. $#data], @data[0 .. $position]);
105 echo_interval => $echo_interval,
106 position => $position,