110 lines
4.2 KiB
Python
110 lines
4.2 KiB
Python
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)
|