diff --git a/check_dmesg.py b/check_dmesg.py new file mode 100644 index 0000000..b7cffa6 --- /dev/null +++ b/check_dmesg.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 + +import subprocess +import re +import sys +import argparse +from datetime import datetime + +def get_dmesg_output(severities): + """ + Uruchamia polecenie dmesg z określonymi poziomami krytyczności. + W przypadku błędu zwraca status UNKNOWN (kod 3). + """ + try: + cmd = ["dmesg", "-T", "-l", severities] + result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, check=True) + return result.stdout.splitlines() + except subprocess.CalledProcessError as e: + print("UNKNOWN - Błąd podczas uruchamiania dmesg:", e) + sys.exit(3) + +def filter_messages(messages, whitelist_regex, date_str): + """ + Filtruje komunikaty: + - uwzględnia tylko linie zawierające dzisiejszą datę, + - ignoruje linie pasujące do whitelist. + """ + filtered = [] + for line in messages: + if date_str in line and not whitelist_regex.search(line): + filtered.append(line) + return filtered + +def tail_messages(messages, tail_count): + """ + Zwraca ostatnie tail_count komunikatów. + """ + return messages[-tail_count:] if messages else [] + +def main(): + parser = argparse.ArgumentParser(description="NRPE check: Monitorowanie krytycznych komunikatów dmesg.") + parser.add_argument("--severities", type=str, default="err,alert,emerg,crit", + help="Poziomy krytyczności dmesg (domyślnie: err,alert,emerg,crit).") + parser.add_argument("--tail", type=int, default=5, + help="Liczba ostatnich komunikatów do wyświetlenia (domyślnie 5).") + args = parser.parse_args() + + # Definicja whitelist – komunikaty ignorowane, m.in. specyficzne dla Proxmox + whitelist_patterns = [ + r"microcode:", + r"Firmware Bug", + r"i8042: No controller", + r"Odd, counter constraints enabled but no core perfctrs detected", + r"Failed to access perfctr msr", + r"echo 0 > /proc/sys", + r"EXT4-fs.*(write access unavailable|mounted filesystem .* ro without journal|unmounting filesystem)", + r"We currently don't support analog TV or stream capture on dual tuners" + ] + whitelist_regex = re.compile("|".join(whitelist_patterns)) + + # Pobranie dzisiejszej daty w formacie odpowiadającym dmesg -T (np. "Wed Mar 23") + today = datetime.now().strftime("%a %b %e") + + messages = get_dmesg_output(args.severities) + filtered = filter_messages(messages, whitelist_regex, today) + tail_filtered = tail_messages(filtered, args.tail) + + if not tail_filtered: + print("OK - Wszystko w porządku.") + sys.exit(0) + else: + # Łączymy komunikaty w jedną linię, aby Nagios miał czytelny output + output = " | ".join(tail_filtered) + print(f"CRITICAL - Krytyczne komunikaty dmesg: {output}") + sys.exit(2) + +if __name__ == "__main__": + main() \ No newline at end of file