90 lines
2.4 KiB
Python
Executable File
90 lines
2.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Check arp cache usage and alert."""
|
|
# -*- coding: us-ascii -*-
|
|
|
|
# Copyright (C) 2019 Canonical
|
|
# All rights reserved
|
|
|
|
import argparse
|
|
import os
|
|
|
|
from nagios_plugin3 import (
|
|
CriticalError,
|
|
UnknownError,
|
|
WarnError,
|
|
try_check,
|
|
)
|
|
|
|
|
|
def check_arp_cache(warn, crit):
|
|
"""Check the usage of arp cache against gc_thresh.
|
|
|
|
Alerts when the number of arp entries exceeds a threshold of gc_thresh3.
|
|
See https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt for
|
|
full details.
|
|
|
|
:param warn: integer, % level of hard limit at which to raise Warning
|
|
:param crit: integer, % level of hard limit at which to raise Critical
|
|
"""
|
|
arp_table_entries = "/proc/net/arp"
|
|
gc_thresh_location = "/proc/sys/net/ipv4/neigh/default/gc_thresh3"
|
|
|
|
if not os.path.exists(arp_table_entries):
|
|
raise UnknownError("No arp table found!")
|
|
if not os.path.exists(gc_thresh_location):
|
|
raise UnknownError("sysctl entry net.ipv4.neigh.default.gc_thresh3 not found!")
|
|
|
|
with open(gc_thresh_location) as fd:
|
|
gc_thresh3 = int(fd.read())
|
|
|
|
with open(arp_table_entries) as fd:
|
|
arp_cache = fd.read().count("\n") - 1 # remove header
|
|
extra_info = "arp cache entries: {}".format(arp_cache)
|
|
|
|
warn_threshold = gc_thresh3 * warn / 100
|
|
crit_threshold = gc_thresh3 * crit / 100
|
|
|
|
if arp_cache >= crit_threshold:
|
|
message = "CRITICAL: arp cache is more than {} of limit, {}".format(
|
|
crit, extra_info
|
|
)
|
|
raise CriticalError(message)
|
|
if arp_cache >= warn_threshold:
|
|
message = "WARNING: arp cache is more than {} of limit, {}".format(
|
|
warn, extra_info
|
|
)
|
|
raise WarnError(message)
|
|
|
|
print("OK: arp cache is healthy: {}".format(extra_info))
|
|
|
|
|
|
def parse_args():
|
|
"""Parse command-line options."""
|
|
parser = argparse.ArgumentParser(description="Check bond status")
|
|
parser.add_argument(
|
|
"--warn",
|
|
"-w",
|
|
type=int,
|
|
help="% of gc_thresh3 to exceed for warning",
|
|
default=60,
|
|
)
|
|
parser.add_argument(
|
|
"--crit",
|
|
"-c",
|
|
type=int,
|
|
help="% of gc_thresh3 to exceed for critical",
|
|
default=80,
|
|
)
|
|
args = parser.parse_args()
|
|
return args
|
|
|
|
|
|
def main():
|
|
"""Parse args and check the arp cache."""
|
|
args = parse_args()
|
|
try_check(check_arp_cache, args.warn, args.crit)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|