Compare commits

...

4 commits

Author SHA1 Message Date
c3699bcbe9 Add separate thresholds for upstream and downstream transfer rate
The old thresholds are the default and apply to both if they are not explicitly set.
2025-05-16 17:35:00 +02:00
3d47561c9d Improve code with temporary variable retransmits 2025-05-16 17:35:00 +02:00
9a9f710651 Improve code formatting 2025-05-16 17:35:00 +02:00
479312ad5e Add command and service definition for icinga2 2025-05-16 17:35:00 +02:00
3 changed files with 152 additions and 23 deletions

View file

@ -166,8 +166,10 @@ def determine_result(options, json_data) -> Tuple[int, Optional[List[str]]]:
Args:
options: An object with threshold attributes used for evaluation.
Expected attributes include:
- rate_warn (int): Warning threshold for bits per second.
- rate_crit (int): Critical threshold for bits per second.
- rate_up_warn (int): Warning threshold for upstream rate in bits per second.
- rate_up_crit (int): Critical threshold for upstream rate in bits per second.
- rate_down_warn (int): Warning threshold for downstream rate in bits per second.
- rate_down_crit (int): Critical threshold for downstream rate in bits per second.
- retrans_warn (int): Warning threshold for retransmissions (TCP only).
- retrans_crit (int): Critical threshold for retransmissions (TCP only).
- udp (bool): Whether the test was run over UDP (retransmissions are ignored if True).
@ -188,19 +190,34 @@ def determine_result(options, json_data) -> Tuple[int, Optional[List[str]]]:
if "error" in json_data:
nagexit(3, json_data["error"])
if options.rate_crit and options.rate_warn:
if json_data["end"]["sum_sent"]["bits_per_second"] <= options.rate_crit:
json_end = json_data['end']
bps_avg_up = json_end['sum_sent']['bits_per_second'] if options.bidir or not options.downstream else None
bps_avg_down = json_end['sum_sent_bidir_reverse']['bits_per_second'] if options.bidir else \
json_data['end']['sum_sent']['bits_per_second'] if options.downstream else None
if bps_avg_up is not None:
if options.rate_up_crit and bps_avg_up <= options.rate_up_crit:
rc = max(rc, 2)
statuslines.append("transfer rate below critical threshold")
elif json_data["end"]["sum_sent"]["bits_per_second"] <= options.rate_warn:
statuslines.append("upstream rate below critical threshold")
elif options.rate_up_warn and bps_avg_up <= options.rate_up_warn:
rc = max(rc, 1)
statuslines.append("transfer rate below warning threshold")
statuslines.append("upstream rate below warning threshold")
if bps_avg_down is not None:
if options.rate_down_crit and bps_avg_down <= options.rate_down_crit:
rc = max(rc, 2)
statuslines.append("downpstream rate below critical threshold")
elif options.rate_down_warn and bps_avg_down <= options.rate_down_warn:
rc = max(rc, 1)
statuslines.append("downstream rate below warning threshold")
if not options.udp and options.retrans_crit and options.retrans_warn:
if json_data["end"]["sum_sent"]["retransmits"] >= options.retrans_crit:
retransmits = json_data["end"]["sum_sent"]["retransmits"]
if retransmits >= options.retrans_crit:
rc = max(rc, 2)
statuslines.append("retransmissions over critical threshold")
elif json_data["end"]["sum_sent"]["retransmits"] >= options.retrans_warn:
elif retransmits >= options.retrans_warn:
rc = max(rc, 1)
statuslines.append("retransmissions over warning threshold")
@ -287,8 +304,10 @@ def build_perfdata(options, json_data: dict) -> List[str]:
- bidir (bool): Whether the test was bidirectional.
- downstream (bool): Whether to use reverse (download) direction.
- udp (bool): Whether the test used UDP (retransmissions ignored).
- rate_warn (int): Warning threshold for throughput (in bits/sec).
- rate_crit (int): Critical threshold for throughput.
- rate_up_warn (int): Warning threshold for upstream rate in bits per second.
- rate_up_crit (int): Critical threshold for upstream rate in bits per second.
- rate_down_warn (int): Warning threshold for downstream rate in bits per second.
- rate_down_crit (int): Critical threshold for downstream rate in bits per second.
- retrans_warn (int): Warning threshold for retransmissions (TCP only).
- retrans_crit (int): Critical threshold for retransmissions.
json_data (dict): Parsed iperf3 output containing measurement results.
@ -305,19 +324,19 @@ def build_perfdata(options, json_data: dict) -> List[str]:
json_end = json_data['end']
bps_avg_up = json_end['sum_sent']['bits_per_second'] if options.bidir or not options.downstream else None
bps_avg_down = json_end['sum_sent_bidir_reverse']['bits_per_second'] if options.bidir else json_data[
'end']['sum_sent']['bits_per_second'] if options.downstream else None
bps_avg_down = json_end['sum_sent_bidir_reverse']['bits_per_second'] if options.bidir else \
json_data['end']['sum_sent']['bits_per_second'] if options.downstream else None
if not options.udp:
retrans_sum_up = json_end['sum_sent']['retransmits'] if options.bidir or not options.downstream else None
retrans_sum_down = json_end['sum_sent_bidir_reverse']['retransmits'] if options.bidir else json_data[
'end']['sum_sent']['retransmits'] if options.downstream else None
retrans_sum_down = json_end['sum_sent_bidir_reverse']['retransmits'] if options.bidir else \
json_data['end']['sum_sent']['retransmits'] if options.downstream else None
if bps_avg_up is not None:
perfdata.append(build_single_perfdata("bps_avg_up", bits_per_second(
bps_avg_up), options.rate_warn, options.rate_crit))
bps_avg_up), options.rate_up_warn, options.rate_up_crit))
if bps_avg_down is not None:
perfdata.append(build_single_perfdata("bps_avg_down", bits_per_second(
bps_avg_down), options.rate_warn, options.rate_crit))
bps_avg_down), options.rate_down_warn, options.rate_down_crit))
if not options.udp:
if retrans_sum_up is not None:
@ -327,10 +346,10 @@ def build_perfdata(options, json_data: dict) -> List[str]:
perfdata.append(build_single_perfdata("retrans_sum_down", packets(
retrans_sum_down), options.retrans_warn, options.retrans_crit))
perfdata.append(build_single_perfdata("local_cpu", percent(
json_end['cpu_utilization_percent']['host_total'])))
perfdata.append(build_single_perfdata("remote_cpu", percent(
json_end['cpu_utilization_percent']['remote_total'])))
perfdata.append(build_single_perfdata("local_cpu",
percent(json_end['cpu_utilization_percent']['host_total'])))
perfdata.append(build_single_perfdata("remote_cpu",
percent(json_end['cpu_utilization_percent']['remote_total'])))
return perfdata
def check_iperf3(options):
@ -350,8 +369,10 @@ def check_iperf3(options):
- bidir (bool): Whether the test should be bidirectional.
- downstream (bool): Whether the test should use reverse mode (server to client).
- udp (bool): Whether the test should use UDP instead of TCP.
- rate_warn (int): Warning threshold for throughput (in bits/sec).
- rate_crit (int): Critical threshold for throughput.
- rate_up_warn (int): Warning threshold for upstream rate in bits per second.
- rate_up_crit (int): Critical threshold for upstream rate in bits per second.
- rate_down_warn (int): Warning threshold for downstream rate in bits per second.
- rate_down_crit (int): Critical threshold for downstream rate in bits per second.
- retrans_warn (int): Warning threshold for retransmissions (TCP only).
- retrans_crit (int): Critical threshold for retransmissions (TCP only).
- bytes (str): Optional. Data to transfer (e.g., '10M').
@ -383,6 +404,18 @@ if __name__ == "__main__":
thres_opts.add_option("-c", "--rate-critical", dest="rate_crit",
type="int", metavar="BITS", action="store",
help="Defines the transfer rate's critical threshold")
thres_opts.add_option("--rate-up-warning", dest="rate_up_warn",
type="int", metavar="BITS", action="store",
help="Defines the upstream rate's warning threshold")
thres_opts.add_option("--rate-up-critical", dest="rate_up_crit",
type="int", metavar="BITS", action="store",
help="Defines the upstream rate's critical threshold")
thres_opts.add_option("--rate-down-warning", dest="rate_down_warn",
type="int", metavar="BITS", action="store",
help="Defines the downstream rate's warning threshold")
thres_opts.add_option("--rate-down-critical", dest="rate_down_crit",
type="int", metavar="BITS", action="store",
help="Defines the downstream rate's critical threshold")
# retransmits
thres_opts.add_option("-W", "--retransmit-warning", dest="retrans_warn",
@ -431,6 +464,14 @@ if __name__ == "__main__":
if not opts.remote or opts.time <= 0:
parser.print_help()
sys.exit(3)
if not opts.rate_up_warn:
opts.rate_up_warn = opts.rate_warn
if not opts.rate_down_warn:
opts.rate_down_warn = opts.rate_warn
if not opts.rate_up_crit:
opts.rate_up_crit = opts.rate_crit
if not opts.rate_down_crit:
opts.rate_down_crit = opts.rate_crit
check_iperf3(opts)

70
command_check_iperf3.conf Normal file
View file

@ -0,0 +1,70 @@
object CheckCommand "iperf3" {
import "plugin-check-command"
command = [ "/home/nagios/check_iperf3/check_iperf3.py" ]
arguments = {
"--remote" = {
description = "iperf3 server to connect to"
value = "$check_iperf3_remote$"
required = true
}
"--port" = {
description = "iperf3 server port to connect to"
value = "$check_iperf3_port$"
}
"--downstream" = {
description = "measure downstream instead of upstream"
set_if = "$check_iperf3_downstream$"
}
"--bidir" = {
description = "test in both directions (normal and reverse), with both the client and server sending and receiving data simultaneously"
set_if = "$check_iperf3_bidir$"
}
"--udp" = {
description = "use UDP rather than TCP"
set_if = "$check_iperf3_udp$"
}
"--time" = {
description = "time in seconds to transmit for"
value = "$check_iperf3_time$"
}
"--bytes" = {
description = "number of bytes to transmit (instead of `time`)"
value = "$check_iperf3_bytes$"
}
"--rate-warning" = {
description = "defines the transfer rate's warning threshold"
value = "$check_iperf3_rate_warning$"
}
"--rate-critical" = {
description = "defines the transfer rate's critical threshold"
value = "$check_iperf3_rate_critical$"
}
"--rate-up-warning" = {
description = "defines the upstream rate's warning threshold"
value = "$check_iperf3_rate_up_warning$"
}
"--rate-up-critical" = {
description = "defines the upstream rate's critical threshold"
value = "$check_iperf3_rate_up_critical$"
}
"--rate-down-warning" = {
description = "defines the downstream rate's warning threshold"
value = "$check_iperf3_rate_down_warning$"
}
"--rate-down-critical" = {
description = "defines the downstream rate's critical threshold"
value = "$check_iperf3_rate_down_critical$"
}
"--retransmission-warning" = {
description = "defines the transfer retransmission's warning threshold"
value = "$check_iperf3_retransmission_warning$"
}
"--retransmission-critical" = {
description = "defines the transfer retransmission's critical threshold"
value = "$check_iperf3_retransmission_critical$"
}
}
}

18
service_check_iperf3.conf Normal file
View file

@ -0,0 +1,18 @@
apply Service "iperf3" {
import "generic-service"
check_command = "iperf3"
check_interval = 4h
retry_interval = 15m
vars.notification_interval = 1d
for (k => v in host.vars.iperf3) {
if (match("_*", k)) {
vars[k.substr(1)] = v
} else {
vars["check_iperf3_" + k] = v
}
}
assign where host.vars.iperf3 != null
}