check_pps.sh 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. #!/usr/bin/env bash
  2. # Author: Jon Schipp
  3. ########
  4. # Examples:
  5. # 1.) Return critical if there's more than 10k PPS
  6. # $ ./check_pps.sh -i eth0 -w 8000 -c 10000 -p
  7. #
  8. # 2.) Return critical if there's more than 1m BPS
  9. # $ ./check_pps.sh -i eth0 -w 500000 -c 1000000 -b
  10. #
  11. # 2.) Return critical if we've reach 70% of the NIC's line-rate capacity
  12. # $ ./check_pps.sh -i eth0 -w 50 -c 70 -r
  13. #
  14. # Nagios Exit Codes
  15. OK=0
  16. WARNING=1
  17. CRITICAL=2
  18. UNKNOWN=3
  19. usage()
  20. {
  21. cat <<EOF
  22. Nagios plug-in that calculates receiving PPS, BPS, and percentage of line-rate (LR)
  23. from Linux kernel statistics by reading from procfs and reports if above a given threshold.
  24. Options:
  25. -i Network interface
  26. -p Use PPS as criteria
  27. -b Use BPS as criteria
  28. -r Use percentage of line-rate as criteria
  29. -t <int> Time interval in seconds (def: 1)
  30. -w <int> Warning threshold
  31. -c <int> Critical threshold
  32. EOF
  33. }
  34. argcheck() {
  35. if [ $ARGC -lt $1 ]; then
  36. echo "Please specify an argument!, try $0 -h for more information"
  37. exit 1
  38. fi
  39. }
  40. get_network_data() {
  41. # Get speed of NIC
  42. speed=$(cat /sys/class/net/$INT/speed)
  43. # Get number of packets for interface
  44. rxppsold=$(awk "/$INT/ "'{ sub(":", " "); print $3 }' /proc/net/dev)
  45. txppsold=$(awk "/$INT/ "'{ sub(":", " "); print $11 }' /proc/net/dev)
  46. # Get number of bytes for interface
  47. rxbytesold=$(awk "/$INT/ "'{ sub(":", " "); print $2 }' /proc/net/dev)
  48. txbytesold=$(awk "/$INT/ "'{ sub(":", " "); print $10 }' /proc/net/dev)
  49. sleep $INTERVAL
  50. # Get number of packets for interface again and subtract from old
  51. rxppsnew=$(awk -v rxppsold="$rxppsold" "/$INT/ "'{ \
  52. sub(":", " "); rxppsnew = $3; print rxppsnew - rxppsold }' /proc/net/dev)
  53. txppsnew=$(awk -v txppsold="$txppsold" "/$INT/ "'{ \
  54. sub(":", " "); txppsnew = $11; print txppsnew - txppsold }' /proc/net/dev)
  55. # Get number of bytes for interface again and subtract from old
  56. rxbytesnew=$(awk -v rxbytesold="$rxbytesold" "/$INT/ "'{ \
  57. sub(":", " "); rxbytesnew = $2; print rxbytesnew - rxbytesold }' /proc/net/dev)
  58. txbytesnew=$(awk -v txbytesold="$txbytesold" "/$INT/ "'{ \
  59. sub(":", " "); txbytesnew = $10; print txbytesnew - txbytesold }' /proc/net/dev)
  60. # Calculate percentage of line-rate from number of bytes per second.
  61. rxlinerate=$(echo "$rxbytesnew / 125000 / $speed * 100" | bc -l)
  62. txlinerate=$(echo "$txbytesnew / 125000 / $speed * 100" | bc -l)
  63. # Format line-rate values by truncating after the 1000th decimal place.
  64. rxlr=$(printf "%1.3f" $rxlinerate)
  65. txlr=$(printf "%1.3f" $txlinerate)
  66. rxlrint=$(printf "%.0f" $rxlinerate)
  67. txlrint=$(printf "%.0f" $txlinerate)
  68. # Print the results
  69. echo -e "Int: ${INT} | [RX] PPS: ${rxppsnew} | BPS: ${rxbytesnew} | % of LR: $rxlr -- [TX] PPS: ${txppsnew} | BPS: $txbytesnew | % of LR: $txlr"
  70. }
  71. threshold_calculation() {
  72. if [ $1 -gt $CRIT ]; then
  73. exit $CRITICAL
  74. elif [ $1 -gt $WARN ]; then
  75. exit $WARNING
  76. else
  77. exit $OK
  78. fi
  79. }
  80. PPS=0
  81. BPS=0
  82. LINERATE=0
  83. INTERVAL=1
  84. WARN=0
  85. CRIT=0
  86. ARGC=$#
  87. # Check for dependency filesystems
  88. if ! [ -d /sys ] || ! [ -d /proc ]; then
  89. echo "$0 requires sysfs and procfs"
  90. exit $UNKNOWN
  91. fi
  92. # Print warning and exit if less than n arguments specified
  93. argcheck 1
  94. # option and argument handling
  95. while getopts "hi:c:w:t:pbr" OPTION
  96. do
  97. case $OPTION in
  98. h)
  99. usage
  100. exit
  101. ;;
  102. i)
  103. INT=$OPTARG
  104. ;;
  105. p)
  106. PPS=1
  107. ;;
  108. b)
  109. BPS=1
  110. ;;
  111. r)
  112. LINERATE=1
  113. ;;
  114. t)
  115. INTERVAL=$OPTARG
  116. ;;
  117. c)
  118. CRIT=$OPTARG
  119. ;;
  120. w)
  121. WARN=$OPTARG
  122. ;;
  123. *)
  124. exit $UNKNOWN
  125. ;;
  126. esac
  127. done
  128. get_network_data
  129. if [ $PPS -eq 1 ]; then
  130. threshold_calculation $rxppsnew
  131. elif [ $BPS -eq 1 ]; then
  132. threshold_calculation $rxbytesnew
  133. elif [ $LINERATE -eq 1 ]; then
  134. threshold_calculation $rxlrint
  135. else
  136. echo "Error: Criteria required!"
  137. exit $UNKNOWN
  138. fi