From 1a97a0a78e57b862018b83cf830b48c6555e5b73 Mon Sep 17 00:00:00 2001 From: Kami Date: Tue, 4 Feb 2025 13:16:03 +0100 Subject: [PATCH] Reworked logging to optionally log to file as well --- bots.py | 51 ++++++++++++++++++++++++++++++++++++--------------- config.json | 5 ++++- 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/bots.py b/bots.py index e3f367d..246da08 100644 --- a/bots.py +++ b/bots.py @@ -31,6 +31,13 @@ except json.JSONDecodeError as e: print(f"Error parsing config.json: {e}") sys.exit(1) +# Initiate logfile +logfile_path = config_data["logfile_path"] +logfile = open(logfile_path, "a") +if not config_data["log_to_terminal"] and not config_data["log_to_file"]: + print(f"!!! WARNING !!! CONSOLE AND LOGFILE OUTPUT DISABLED !!!\n!!! NO LOGS WILL BE PROVIDED !!!") +first_log_entry = True + ############################### # Simple Logging System ############################### @@ -40,35 +47,49 @@ def log(message, level="INFO", exec_info=False): A simple logging function with adjustable log levels. Logs messages in a structured format. - Available levels: - DEBUG, INFO, WARNING, ERROR, CRITICAL, FATAL + Available levels:\n + DEBUG = Information useful for debugging\n + INFO = Informational messages\n + WARNING = Something happened that may lead to issues\n + ERROR = A non-critical error has happened\n + CRITICAL = A critical, but non-fatal, error\n + FATAL = Fatal error. Program exits after logging this\n\n See 'config.json' for disabling/enabling logging levels """ from modules import utility log_levels = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL", "FATAL"] + if level not in log_levels: level = "INFO" # Default to INFO if an invalid level is provided - if level in config_data["log_levels"]: - + if level in config_data["log_levels"] or first_log_entry: elapsed = time.time() - globals.get_bot_start_time() uptime_str, _ = utility.format_uptime(elapsed) timestamp = time.strftime('%Y-%m-%d %H:%M:%S') log_message = f"[{timestamp} - {uptime_str}] [{level}] {message}" - - # If traceback is requested (e.g., for errors) - if exec_info or level == "CRITICAL" or level == "FATAL": + + # Include traceback for certain error levels + if exec_info or level in ["CRITICAL", "FATAL"]: log_message += f"\n{traceback.format_exc()}" - try: - print(log_message) # Print to terminal - if level == "FATAL": - print(f"!!! FATAL ERROR LOGGED, SHUTTING DOWN !!!") - sys.exit(1) - except Exception: - pass # Prevent logging failures from crashing the bot + # Print to terminal if enabled + if config_data["log_to_terminal"]: + print(log_message) - # Placeholder for future expansions (e.g., file logging, Discord alerts, etc.) + # Write to file if enabled + if config_data["log_to_file"]: + try: + with open(config_data["logfile_path"], "a", encoding="utf-8") as logfile: + logfile.write(f"{log_message}\n") + logfile.flush() # Ensure it gets written immediately + except Exception as e: + print(f"[WARNING] Failed to write to logfile: {e}") + + # Handle fatal errors with shutdown + if level == "FATAL": + if config_data["log_to_terminal"]: + print(f"!!! FATAL ERROR LOGGED, SHUTTING DOWN !!!") + sys.exit(1) ############################### # Main Event Loop diff --git a/config.json b/config.json index 47e080b..83fa435 100644 --- a/config.json +++ b/config.json @@ -2,6 +2,9 @@ "discord_guilds": [896713616089309184], "twitch_channels": ["OokamiKunTV", "ookamipup"], "command_modules": ["cmd_discord", "cmd_twitch", "cmd_common"], - "log_levels": ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL", "FATAL"] + "log_levels": ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL", "FATAL"], + "log_to_file": true, + "log_to_terminal": true, + "logfile_path": "logfile.log" } \ No newline at end of file