check_eth 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. #!/usr/bin/perl -w
  2. use strict;
  3. use warnings;
  4. use Getopt::Long;
  5. use constant BITS => 8;
  6. use constant BYTES => 1;
  7. my $iface = "";
  8. my $bandwidth = "";
  9. my $warning = "";
  10. my $critical = "";
  11. my $percent = "";
  12. GetOptions(
  13. "i|interface=s" => \$iface,
  14. "w|warning=s" => \$warning,
  15. "c|critical=s" => \$critical,
  16. "b|bandwidth=s" => \$bandwidth,
  17. "p|percent" => \$percent
  18. );
  19. my $bitmod = BYTES;
  20. my $tmpfile = "/tmp/traffic";
  21. my $output = "";
  22. my $line = "";
  23. my %status = ( 'OK' => 0,
  24. 'WARNING' => 1,
  25. 'CRITICAL' => 2,
  26. 'UNKNOWN' => 3
  27. );
  28. my $exit_status = $status{OK};
  29. my %data = ( 'time' => 0, 'last_time' => 0,
  30. 'rxbytes' => 0, 'last_rxbytes' => 0,
  31. 'txbytes' => 0, 'last_txbytes' => 0
  32. );
  33. my %speed = ( 'tx' => 0,
  34. 'rx' => 0,
  35. 'interval' => 1
  36. );
  37. usage() if ( !$iface || !$warning || !$critical );
  38. if ( $percent ) {
  39. usage() if ( !$bandwidth || $bandwidth !~ /^\d+[kKmMgG]$/ );
  40. usage() if ( $warning !~ /^\d{1,3}$/ || $warning>100 || $critical !~ /^\d{1,3}$/ || $critical>100 );
  41. $bandwidth = human2bytes($bandwidth);
  42. } else {
  43. $warning = human2bytes($warning);
  44. $critical = human2bytes($critical);
  45. usage() if ( !$warning || !$critical )
  46. }
  47. usage() if ( $warning > $critical );
  48. open ( NET, "</proc/net/dev" ) or die ( "Can't open /proc/net/dev: $!" );
  49. while ( <NET> ) {
  50. chomp();
  51. if ( $_ =~ /^\s*$iface\:\s*(\d+)(?:\s*(?:\d+)){7}\s*(\d+)(?:\s*(?:\d+)){7}\s*$/ ) {
  52. $data{time} = time - 1;
  53. $data{rxbytes} = $1;
  54. $data{txbytes} = $2;
  55. last;
  56. }
  57. }
  58. close( NET );
  59. if ( $data{time} == 0 && $data{rxbytes} == 0 && $data{txbytes} == 0 ) {
  60. exit $status{UNKNOWN};
  61. }
  62. if ( open( TMP, "<$tmpfile-$iface" ) ) {
  63. my @line = <TMP>; chomp( @line );
  64. ( $data{last_time}, $data{last_rxbytes}, $data{last_txbytes} ) = split( ":", $line[0] );
  65. }
  66. if ( open( TMP, ">$tmpfile-$iface" ) ) {
  67. print( TMP "$data{time}:$data{rxbytes}:$data{txbytes}\n" );
  68. close( TMP );
  69. }
  70. $data{last_time} = $data{time} if ( !$data{last_time} || $data{last_time} > $data{time} );
  71. $data{last_rxbytes} = $data{rxbytes} if ( !$data{last_rxbytes} || $data{last_rxbytes} > $data{rxbytes} );
  72. $data{last_txbytes} = $data{txbytes} if ( !$data{last_txbytes} || $data{last_txbytes} > $data{txbytes} );
  73. $speed{interval} = $data{time} - $data{last_time} + 1;
  74. $speed{rx} = ( $data{rxbytes} - $data{last_rxbytes} ) / $speed{interval};
  75. $speed{tx} = ( $data{txbytes} - $data{last_txbytes} ) / $speed{interval};
  76. $output = "RX Bytes: ". bytes2human($data{rxbytes}) ."B, TX Bytes: ". bytes2human($data{txbytes}) ."B; ";
  77. $output .= sprintf( "RX Speed: %s%sps, TX Speed: %s%sps; ",
  78. bytes2human($speed{rx}*$bitmod), ($bitmod==BITS)?"b":"B", bytes2human($speed{tx}*$bitmod), ($bitmod==BITS)?"b":"B" );
  79. if ( $percent ) {
  80. if ( ( $speed{rx} / $bandwidth ) * 100 > $critical || ( $speed{tx} / $bandwidth ) * 100 > $critical ) {
  81. $exit_status = $status{CRITICAL};
  82. $output .= "CRITICAL";
  83. } elsif ( ( $speed{rx} / $bandwidth ) * 100 > $warning || ( $speed{tx} / $bandwidth ) * 100 > $warning ) {
  84. $exit_status = $status{WARNING};
  85. $output .= "WARNING";
  86. } else {
  87. $output .= "OK";
  88. }
  89. } else {
  90. if ( ( $speed{rx} > $critical ) or ( $speed{tx} > $critical ) ) {
  91. $exit_status = $status{CRITICAL};
  92. $output .= "CRITICAL";
  93. } elsif ( ( $speed{rx} > $warning ) or ( $speed{tx} > $warning ) ) {
  94. $exit_status = $status{WARNING};
  95. $output .= "WARNING";
  96. } else {
  97. $output .= "OK";
  98. }
  99. }
  100. $output .= " bandwidth utilization";
  101. $output .= sprintf( " | rx=%.0f;%2.0f;%2.0f tx=%.0f;%2.0f;%2.0f",
  102. $speed{rx}*$bitmod, ($percent)?$warning*$bandwidth/100:$warning, ($percent)?$critical*$bandwidth/100:$critical,
  103. $speed{tx}*$bitmod, ($percent)?$warning*$bandwidth/100:$warning, ($percent)?$critical*$bandwidth/100:$critical );
  104. print "$output\n";
  105. exit( $exit_status );
  106. # helper function
  107. sub bytes2human {
  108. my $bytes = shift;
  109. return 0 if !$bytes;
  110. my @units = ( '','K','M','G','T' );
  111. my $offset = 0;
  112. while ( $bytes > 1024 ){
  113. $bytes = $bytes / 1024;
  114. $offset++;
  115. }
  116. return sprintf( "%2.0f%s", $bytes, $units[$offset] );
  117. }
  118. sub human2bytes {
  119. my $value = shift;
  120. return 0 if ( !$value || $value !~ /^(\d+)(\w)$/ );
  121. my ($number, $scale) = ($1,$2);
  122. my $bitmod = ( $scale =~ /[kmg]/ ) ? BITS : BYTES;
  123. my @units = ( '','K','M','G','T' );
  124. my $offset = 0;
  125. while( $units[$offset] ne "\u$scale" && $offset <= scalar(@units) ) {
  126. $number *= 1024;
  127. $offset++;
  128. }
  129. return $number/$bitmod;
  130. }
  131. sub usage {
  132. print <<EOU;
  133. Usage: $0 -i <interface> -w <warn> -c <critical> [-p -b <bandwidth>]
  134. -i, --interface STRING
  135. Network interface name (example: eth0)
  136. -w, --warning STRING
  137. Warning interface speed level (K/M/G Bps, k/m/g bps)
  138. If using with -p value should be in percentage (1-100)
  139. -c, --critilcal STRING
  140. Critical interface speed level (K/M/G Bps, k/m/g bps)
  141. If using with -p value should be in percentage (1-100)
  142. -p
  143. Calculate warning and critical levels in percentage based on interface bandwidth
  144. -b, --bandwidth STRING
  145. Interface bandwidth value (K/M/G Bps, k/m/g bps)
  146. EOU
  147. unlink($tmpfile);
  148. exit $status{UNKNOWN};
  149. }