From d12d05378db9c436396040c3afb796a7d89ad551 Mon Sep 17 00:00:00 2001 From: gru Date: Tue, 2 Dec 2025 10:13:16 +0100 Subject: [PATCH] Update check_xfs.py --- check_xfs.py | 60 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/check_xfs.py b/check_xfs.py index fa9d536..8d6cfee 100644 --- a/check_xfs.py +++ b/check_xfs.py @@ -3,6 +3,7 @@ import subprocess import sys import re import argparse +import os 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]) 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): output = run_cmd(f"df -h {mount}") for line in output.splitlines(): @@ -42,24 +48,18 @@ def check_xfs_repair(mount): return False, 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(): parser = argparse.ArgumentParser( - add_help=False, # Disable default help to customize + add_help=False, description="XFS Filesystem Health Check", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" 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 /data # Check specific mount %(prog)s -m /data,/var # Check multiple mounts %(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('-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') args = parser.parse_args() + # Nagios: --help and --list exit 0 (OK) if args.help: parser.print_help() sys.exit(0) @@ -92,18 +92,14 @@ Examples: target_mounts = [] if args.mount: 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] else: target_mounts = find_xfs_mounts() + # Nagios: No mounts = UNKNOWN (3) if not target_mounts: - print(color_text("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") + print(color_text("UNKNOWN No XFS mount points found or specified|", "yellow")) sys.exit(3) warn_threshold = args.warn_threshold @@ -111,6 +107,7 @@ Examples: global_status = 0 all_perfdata = [] + # Human-readable output (colorful) print(color_text("Checking XFS filesystems:", "bold")) print(f"Thresholds: WARN>{warn_threshold}%% CRIT>{crit_threshold}%%") print("=" * 60) @@ -118,10 +115,18 @@ Examples: for mount in target_mounts: 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) if usage_pct is None: print(color_text(" UNKNOWN: Unable to read disk usage", "red")) global_status = max(global_status, 3) + all_perfdata.append(f"{mount}_status=3") continue usage_status = 0 @@ -135,22 +140,35 @@ Examples: repair_ok, repair_out = check_xfs_repair(mount) if not repair_ok: - print(color_text(" CRITICAL: XFS filesystem issues detected:", "red")) - print(f" {repair_out[:400]}...") + print(color_text(" CRITICAL: XFS filesystem issues detected", "red")) + print(f" {repair_out[:200]}...") global_status = max(global_status, 2) + xfs_status = 2 else: print(color_text(" XFS filesystem OK (xfs_repair dry-run)", "green")) + xfs_status = 0 - global_status = max(global_status, usage_status) - all_perfdata.append(f"{mount}_used_pct={usage_pct};{warn_threshold};{crit_threshold} size={size} avail={avail}") + # Final status for this mount + 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) - print("\n" + "=" * 60) 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" + print("\n" + "=" * 60) print(color_text(f"FINAL STATUS: {status_text[global_status]}", status_color)) 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) if __name__ == "__main__":