From 9dca656441169eca4d54266c2318e9a2bd281337 Mon Sep 17 00:00:00 2001 From: Cyberes Date: Fri, 21 Apr 2023 23:54:18 -0600 Subject: [PATCH] check_eth --- check_bandwidth.py | 69 +++++++++++++++++++++++++++++++++++++++++++++ checker/markdown.py | 55 ++++++++++++++++++++++++++++++++++++ requirements.txt | 3 +- 3 files changed, 126 insertions(+), 1 deletion(-) create mode 100755 check_bandwidth.py create mode 100644 checker/markdown.py diff --git a/check_bandwidth.py b/check_bandwidth.py new file mode 100755 index 0000000..00472e1 --- /dev/null +++ b/check_bandwidth.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python3 +import argparse + +import psutil + +from checker.markdown import list_to_markdown_table + +# Parse the bandwidth limit argument +parser = argparse.ArgumentParser(description='Check network interface bandwidth utilization.') +parser.add_argument('--bandwidth', type=float, required=True, help='Bandwidth speed in Mbps.') +parser.add_argument('--critical', type=int, default=75, help='Critical if percent of bandwidth usage is greater than or equal to this.') +parser.add_argument('--warn', type=int, default=50, help='Warning if percent of bandwidth usage is greater than or equal to this.') +args = parser.parse_args() + +data = [] +warn_value = (args.bandwidth * args.warn) +crit_value = (args.bandwidth * args.critical) + +# Get network interface statistics +net_io_counters = psutil.net_io_counters(pernic=True) + +# Calculate bandwidth utilization for each interface +for interface, stats in net_io_counters.items(): + # Get the number of bytes sent and received + bytes_sent = stats.bytes_sent + bytes_recv = stats.bytes_recv + + # Wait for 1 second + psutil.cpu_percent(interval=1) + + # Get the number of bytes sent and received after 1 second + new_stats = psutil.net_io_counters(pernic=True)[interface] + new_bytes_sent = new_stats.bytes_sent + new_bytes_recv = new_stats.bytes_recv + + # Calculate the bandwidth utilization in bits per second + bandwidth_utilization = (8 * (new_bytes_sent - bytes_sent + new_bytes_recv - bytes_recv)) / (1 * 1000 * 1000) + data.append([interface, bandwidth_utilization, 'none']) + +critical = [] +warn = [] +ok = [] +perf_data = [] +for i in range(len(data)): + interface = data[i][0] + bandwidth_utilization = data[i][1] + if bandwidth_utilization >= crit_value: + critical.append(interface) + data[i][2] = 'critical' + elif bandwidth_utilization >= warn_value: + warn.append(interface) + data[i][2] = 'warning' + else: + ok.append(interface) + data[i][2] = 'ok' + perf_data.append(f'{interface}={round(bandwidth_utilization, 2)}Mbps;{warn_value};{crit_value}; ') + +if len(ok): + print(f'OK: {", ".join(ok)}') +if len(warn): + print(f'WARNING: {", ".join(warn)}') +if len(critical): + print(f'CRITICAL: {", ".join(critical)}') + +data = [(x[0], f'{round(x[1], 2)} Mbps', x[2]) for x in data] +data.insert(0, ('Interface', 'Bandwidth', 'State')) +print(list_to_markdown_table(data, align='left')) + +print(f' |{"".join(perf_data)}') diff --git a/checker/markdown.py b/checker/markdown.py new file mode 100644 index 0000000..d86cb42 --- /dev/null +++ b/checker/markdown.py @@ -0,0 +1,55 @@ +def list_to_markdown_table(array, align: str = None): + """ + https://gist.github.com/OsKaR31415/955b166f4a286ed427f667cb21d57bfd + Args: + array: The array to make into a table. Mush be a rectangular array + (constant width and height). + align: The alignment of the cells : 'left', 'center' or 'right'. + """ + # make sure every elements are strings + array = [[str(elt) for elt in line] for line in array] + # get the width of each column + widths = [max(len(line[i]) for line in array) for i in range(len(array[0]))] + # make every width at least 3 colmuns, because the separator needs it + widths = [max(w, 3) for w in widths] + # center text according to the widths + array = [[elt.center(w) for elt, w in zip(line, widths)] for line in array] + + # separate the header and the body + array_head, *array_body = array + + header = '| ' + ' | '.join(array_head) + ' |' + + # alignment of the cells + align = str(align).lower() # make sure `align` is a lowercase string + if align == 'none': + # we are just setting the position of the : in the table. + # here there are none + border_left = '| ' + border_center = ' | ' + border_right = ' |' + elif align == 'center': + border_left = '| ' + border_center = ' | ' + border_right = ' |' + elif align == 'left': + border_left = '| ' + border_center = ' | ' + border_right = ' |' + elif align == 'right': + border_left = '| ' + border_center = ' | ' + border_right = ' |' + else: + raise ValueError("align must be 'left', 'right' or 'center'.") + separator = border_left + border_center.join(['-' * w for w in widths]) + border_right + + # body of the table + del array[0] + body = [''] * len(array) # empty string list that we fill after + for idx, line in enumerate(array): + # for each line, change the body at the correct index + body[idx] = '| ' + ' | '.join(line) + ' |' + body = '\n'.join(body) + + return header + '\n' + separator + '\n' + body diff --git a/requirements.txt b/requirements.txt index 02bbb2a..332ba10 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,4 +10,5 @@ flask~=2.2.3 icinga2api~=0.6.1 urllib3~=1.26.14 aiofiles~=0.6.0 -markdown \ No newline at end of file +markdown~=3.4.1 +psutil~=5.9.4 \ No newline at end of file