ignore unparsable lines from ifstat, two totals
[influxdb-pipes] / ifstat.pl
1 #!/usr/bin/perl
2 use warnings;
3 use strict;
4 use autodie;
5
6 my $host = shift @ARGV || die "usage: INFLUX=http://127.0.0.1:8086/write?db=snmp COMMUNITY=snmp-community $0 host";
7 my $community = $ENV{COMMUNITY} || 'public';
8 my $influx    = $ENV{INFLUX} || 'http://127.0.0.1:8086/write?db=snmp';
9
10 use Data::Dump qw(dump);
11 sub XXX { warn "XXX ", scalar(@_), Data::Dump::dump(@_), join(' ',caller), "\n"; };
12
13 my ($sec,$min,$hour,$dd,$mm,$yyyy) = localtime(time); $mm++;
14 my $time;
15 use Time::Local;
16 sub update_time {
17         #warn "# time $yyyy-$mm-$dd $hour:$min:$sec $time\n";
18         $time = timelocal($sec,$min,$hour,$dd,$mm-1,$yyyy) * 1000_000_000;
19         return $time;
20 }
21
22 # FIXME add -A to pull interfaces if they go up and down
23 # -l loopback
24 # -a all
25 my $cmd = qq{$ENV{SSH}ifstat -s '$community@#$host' -a -l -b -n -t 1};
26 warn "# $cmd\n";
27 open(my $ifstat, '-|', $cmd);
28
29 my $first_skipped = 0;
30
31 my $curl;
32 sub reopen_curl {
33         if ( $ENV{INFLUX} ) {
34                 open($curl, '|-', qq( curl -XPOST $influx --data-binary \@- ));
35         } else {
36                 open($curl, '|-', 'tee /dev/shm/curl.debug');
37         }
38 }
39
40 my $stat;
41
42 my @if;
43 my @direction;
44
45 my $lines;
46 my $host_tags = $host;
47 $host_tags =~ s/\./,domain=/;
48
49 my $last_hour = $hour;
50
51 while(<$ifstat>) {
52         chomp;
53         #warn "# [$_]\n";
54         s/^\s+//;
55         s/(\w) (in|out)/$1_$2/g;
56         my @v = split(/\s+/);
57         #warn "## [",join(' ',@v), "]\n";
58         if ( $v[0] eq 'Time' ) {
59                 shift @v;
60                 @if = @v;
61         } elsif ( $v[0] eq 'HH:MM:SS' ) {
62                 shift @v;
63                 @direction = map { s/\W+/_/g; s/^K//; $_ } @v;
64         } elsif ( $v[0] =~ m/^(\d\d):(\d\d):(\d\d)/ ) {
65                 next unless $first_skipped++;
66
67                 if ( $last_hour != $hour ) {
68                         ($sec,$min,$hour,$dd,$mm,$yyyy) = localtime(time); $mm++;
69                         $last_hour = $hour;
70                 }
71
72                 $hour = $1; $min = $2; $sec = $3; update_time;
73
74                 reopen_curl;
75                 my @total;
76
77                 foreach my $i ( 0 .. $#if ) {
78
79                         my $if = $if[$i];
80                         
81                         my @tags = ( "if=$if", "host=$host_tags", $ENV{TAGS} || 'no_tags=true' );
82 =for later
83                         if ( $if =~ m/if(\d\d)(\d\d\d\d)/ ) {
84                                 push @tags, "is_vlan=T,prefix=$1,vlan=$2";
85                         } elsif ( $if =~ m/if(\d+)/ ) {
86                                 push @tags, "is_vlan=F,port=$1";
87                         } else {
88                                 push @tags, "unknown_if=$if";
89                         }
90 =cut
91
92                         my $v1 = $v[$i*2+1];
93                         my $v2 = $v[$i*2+2];
94
95                         if ( $v1 =~ m/^\d+\.\d++$/ && $v2 =~ m/^\d+\.\d++$/ ) {
96                                 
97                                 $total[0] += $v1;
98                                 $total[1] += $v2;
99
100                                 $v1 = int( $v1 * 1024 );
101                                 $v2 = int( $v2 * 1024 );
102         
103                                 print $curl "ifstat,", join(',', @tags),
104                                 " ", $direction[$i*2],   "=${v1}i",
105                                 ",", $direction[$i*2+1], "=${v2}i",
106                                 " $time\n" if $v1 < 100_000_000_000_000 && $v2 < 100_000_000_000_000;
107
108                                 $lines++;
109                         } else {
110                                 warn "IGNORED $if $v1 $v2\n";
111                         }
112                 }
113
114                 warn "# $host ", $curl->tell, " totals: $total[0] $total[1]\n";
115                 close($curl);
116         } else {
117                 die "UNPARSED [$_]";
118         }
119 }
120
121