Update check_xfs.py

This commit is contained in:
gru
2025-12-02 10:13:16 +01:00
parent 36d8c52e8b
commit d12d05378d

View File

@@ -3,6 +3,7 @@ import subprocess
import sys import sys
import re import re
import argparse import argparse
import os
ESC = {"reset": "\033[0m", "red": "\033[31m", "yellow": "\033[33m", "green": "\033[32m", "cyan": "\033[36m", "bold": "\033[1m"} ESC = {"reset": "\033[0m", "red": "\033[31m", "yellow": "\033[33m", "green": "\033[32m", "cyan": "\033[36m", "bold": "\033[1m"}
@@ -24,6 +25,11 @@ def find_xfs_mounts():
xfs_mounts.append(parts[2]) xfs_mounts.append(parts[2])
return xfs_mounts return xfs_mounts
def is_xfs_mount(mount):
"""Check if mount point is actually XFS"""
mounts_output = run_cmd(f"mount | grep {re.escape(mount)}")
return "xfs" in mounts_output.lower()
def check_disk_usage(mount): def check_disk_usage(mount):
output = run_cmd(f"df -h {mount}") output = run_cmd(f"df -h {mount}")
for line in output.splitlines(): for line in output.splitlines():
@@ -42,24 +48,18 @@ def check_xfs_repair(mount):
return False, output return False, output
return True, output return True, output
def print_status(status, msg):
color_map = {0: "green", 1: "yellow", 2: "red", 3: "red"}
prefix = {0: "OK", 1: "WARNING", 2: "CRITICAL", 3: "UNKNOWN"}
print(f"{color_text(prefix[status], color_map[status])}: {msg}")
def main(): def main():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
add_help=False, # Disable default help to customize add_help=False,
description="XFS Filesystem Health Check", description="XFS Filesystem Health Check",
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=""" epilog="""
Examples: Examples:
%(prog)s # Check all XFS mounts (shows help if no mounts found) %(prog)s # Check all XFS mounts
%(prog)s --list # List available XFS mounts %(prog)s --list # List available XFS mounts
%(prog)s /data # Check specific mount %(prog)s /data # Check specific mount
%(prog)s -m /data,/var # Check multiple mounts %(prog)s -m /data,/var # Check multiple mounts
%(prog)s -w 85 -c 95 # Custom thresholds %(prog)s -w 85 -c 95 # Custom thresholds
%(prog)s -m /data -w 80 -c 90 # Mount + thresholds
""" """
) )
@@ -69,11 +69,11 @@ Examples:
parser.add_argument('-w', '--warn-threshold', type=int, default=80, help='Warning threshold %% (default: 80)') parser.add_argument('-w', '--warn-threshold', type=int, default=80, help='Warning threshold %% (default: 80)')
parser.add_argument('-c', '--crit-threshold', type=int, default=90, help='Critical threshold %% (default: 90)') parser.add_argument('-c', '--crit-threshold', type=int, default=90, help='Critical threshold %% (default: 90)')
# Positional argument for single mount
parser.add_argument('mount', nargs='?', help='Single mount point to check') parser.add_argument('mount', nargs='?', help='Single mount point to check')
args = parser.parse_args() args = parser.parse_args()
# Nagios: --help and --list exit 0 (OK)
if args.help: if args.help:
parser.print_help() parser.print_help()
sys.exit(0) sys.exit(0)
@@ -92,18 +92,14 @@ Examples:
target_mounts = [] target_mounts = []
if args.mount: if args.mount:
target_mounts = [m.strip() for m in args.mount.split(',') if m.strip()] target_mounts = [m.strip() for m in args.mount.split(',') if m.strip()]
elif args.mount is not None: # Positional arg elif args.mount is not None:
target_mounts = [args.mount] target_mounts = [args.mount]
else: else:
target_mounts = find_xfs_mounts() target_mounts = find_xfs_mounts()
# Nagios: No mounts = UNKNOWN (3)
if not target_mounts: if not target_mounts:
print(color_text("No XFS mount points found or specified.", "yellow")) print(color_text("UNKNOWN No XFS mount points found or specified|", "yellow"))
print("\nAvailable commands:")
print(" python3 check_xfs.py --list # Show available XFS mounts")
print(" python3 check_xfs.py /data # Check specific mount")
print(" python3 check_xfs.py -m /data,/var # Check multiple mounts")
print(" python3 check_xfs.py -h # Full help")
sys.exit(3) sys.exit(3)
warn_threshold = args.warn_threshold warn_threshold = args.warn_threshold
@@ -111,6 +107,7 @@ Examples:
global_status = 0 global_status = 0
all_perfdata = [] all_perfdata = []
# Human-readable output (colorful)
print(color_text("Checking XFS filesystems:", "bold")) print(color_text("Checking XFS filesystems:", "bold"))
print(f"Thresholds: WARN>{warn_threshold}%% CRIT>{crit_threshold}%%") print(f"Thresholds: WARN>{warn_threshold}%% CRIT>{crit_threshold}%%")
print("=" * 60) print("=" * 60)
@@ -118,10 +115,18 @@ Examples:
for mount in target_mounts: for mount in target_mounts:
print(f"\n{color_text(mount, 'cyan')}") print(f"\n{color_text(mount, 'cyan')}")
# Validate it's actually XFS
if not is_xfs_mount(mount):
print(color_text(" UNKNOWN: Mount point not found or not XFS", "red"))
global_status = max(global_status, 3)
all_perfdata.append(f"{mount}_status=3")
continue
usage_pct, size, avail = check_disk_usage(mount) usage_pct, size, avail = check_disk_usage(mount)
if usage_pct is None: if usage_pct is None:
print(color_text(" UNKNOWN: Unable to read disk usage", "red")) print(color_text(" UNKNOWN: Unable to read disk usage", "red"))
global_status = max(global_status, 3) global_status = max(global_status, 3)
all_perfdata.append(f"{mount}_status=3")
continue continue
usage_status = 0 usage_status = 0
@@ -135,22 +140,35 @@ Examples:
repair_ok, repair_out = check_xfs_repair(mount) repair_ok, repair_out = check_xfs_repair(mount)
if not repair_ok: if not repair_ok:
print(color_text(" CRITICAL: XFS filesystem issues detected:", "red")) print(color_text(" CRITICAL: XFS filesystem issues detected", "red"))
print(f" {repair_out[:400]}...") print(f" {repair_out[:200]}...")
global_status = max(global_status, 2) global_status = max(global_status, 2)
xfs_status = 2
else: else:
print(color_text(" XFS filesystem OK (xfs_repair dry-run)", "green")) print(color_text(" XFS filesystem OK (xfs_repair dry-run)", "green"))
xfs_status = 0
global_status = max(global_status, usage_status) # Final status for this mount
all_perfdata.append(f"{mount}_used_pct={usage_pct};{warn_threshold};{crit_threshold} size={size} avail={avail}") mount_status = max(usage_status, xfs_status)
global_status = max(global_status, mount_status)
# Nagios perfdata: metric=value;warn;crit;min;max
perf = f"used_pct={usage_pct};{warn_threshold};{crit_threshold};0;100 size={size} avail={avail} xfs_repair={xfs_status}"
all_perfdata.append(perf)
perfdata = " ".join(all_perfdata) perfdata = " ".join(all_perfdata)
print("\n" + "=" * 60)
status_text = {0: "OK", 1: "WARNING", 2: "CRITICAL", 3: "UNKNOWN"} status_text = {0: "OK", 1: "WARNING", 2: "CRITICAL", 3: "UNKNOWN"}
# Colorful human output
status_color = "green" if global_status == 0 else "yellow" if global_status == 1 else "red" status_color = "green" if global_status == 0 else "yellow" if global_status == 1 else "red"
print("\n" + "=" * 60)
print(color_text(f"FINAL STATUS: {status_text[global_status]}", status_color)) print(color_text(f"FINAL STATUS: {status_text[global_status]}", status_color))
print(f"| {perfdata}") print(f"| {perfdata}")
# NAGIOS: Clean single-line output (no colors, parseable)
print(f"\n{status_text[global_status]} XFS check complete| {perfdata}")
# Nagios standard exit codes
sys.exit(global_status) sys.exit(global_status)
if __name__ == "__main__": if __name__ == "__main__":