import psutil import time import json import logging import argparse import os from collections import defaultdict from datetime import datetime # Globaler Debug-Status _debug_mode = False def set_debug_mode(enabled: bool): """Setzt den globalen Debug-Modus für das Modul.""" global _debug_mode _debug_mode = enabled # Farben für CLI-Ausgabe class LogColors: INFO = "\033[94m" DEBUG = "\033[92m" WARNING = "\033[93m" ERROR = "\033[91m" RESET = "\033[0m" # Logging einrichten LOG_FILE = os.path.expanduser("~/process_monitor.log") logging.basicConfig( filename=LOG_FILE, level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s" ) def log_message(level, message, debug_mode=False): """Loggt Nachrichten mit Farben für die CLI.""" if level == "info": logging.info(message) if debug_mode: print(f"{LogColors.INFO}[INFO]{LogColors.RESET} {message}") elif level == "debug": logging.debug(message) if debug_mode: print(f"{LogColors.DEBUG}[DEBUG]{LogColors.RESET} {message}") elif level == "warning": logging.warning(message) if debug_mode: print(f"{LogColors.WARNING}[WARNING]{LogColors.RESET} {message}") elif level == "error": logging.error(message) if debug_mode: print(f"{LogColors.ERROR}[ERROR]{LogColors.RESET} {message}") def get_process_info(debug=None): """Erfasst alle laufenden Prozesse mit CPU-, Speicher-, Benutzerinfos und Startzeit.""" is_debug = _debug_mode if debug is None else debug log_message("info", "Sammle Prozessinformationen...", debug_mode=is_debug) process_info = [] current_time = time.time() for proc in psutil.process_iter(['pid', 'name', 'username', 'cpu_percent', 'memory_percent', 'status', 'create_time']): try: start_time = datetime.fromtimestamp(proc.info['create_time']).strftime('%Y-%m-%d %H:%M:%S') runtime_seconds = int(current_time - proc.info['create_time']) process_info.append({ "pid": proc.info['pid'], "name": proc.info['name'], "user": proc.info['username'], "cpu": proc.info['cpu_percent'], "memory": proc.info['memory_percent'], "status": proc.info['status'], "start_time": start_time, "runtime_seconds": runtime_seconds }) except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess): continue return sorted(process_info, key=lambda x: (x['name'], x['user'], -x['cpu'], -x['memory'])) def display_processes(process_info, debug=False): """Formatiert und gibt die Prozessinformationen aus.""" log_message("info", f"Gefundene Prozesse: {len(process_info)}", debug_mode=debug) print(f"{LogColors.INFO}Laufende Prozesse:{LogColors.RESET}") for proc in process_info: print(f" {LogColors.DEBUG}{proc['name']} (PID: {proc['pid']}, User: {proc['user']}){LogColors.RESET}") print(f" CPU: {proc['cpu']}% | RAM: {proc['memory']}% | Status: {proc['status']}") print(f" Startzeit: {proc['start_time']} | Laufzeit: {proc['runtime_seconds']} Sekunden") def save_process_info(process_info, filename, debug=False): """Speichert die Prozessinformationen in einer JSON-Datei.""" try: with open(filename, "w") as json_file: json.dump(process_info, json_file, indent=4) log_message("info", f"Prozessdaten gespeichert: {filename}", debug_mode=debug) except Exception as e: log_message("error", f"Fehler beim Speichern der JSON-Datei: {str(e)}", debug_mode=debug) if __name__ == "__main__": parser = argparse.ArgumentParser(description="Überwachung laufender Prozesse mit CPU-, RAM-Nutzung und Startzeit.") parser.add_argument("--debug", action="store_true", help="Aktiviert Debug-Logging auf der CLI.") parser.add_argument("--json", type=str, help="Speichert die Ausgabe in einer JSON-Datei.") args = parser.parse_args() process_data = get_process_info(debug=args.debug) display_processes(process_data, debug=args.debug) if args.json: save_process_info(process_data, args.json, debug=args.debug)