feat: Implement comprehensive non-hierarchical logging system
- Created new logging infrastructure with per-component filtering - Added 6 log levels: DEBUG, INFO, API, WARNING, ERROR, CRITICAL - Implemented non-hierarchical level control (any combination can be enabled) - Migrated 917 print() statements across 31 files to structured logging - Created web UI (system.html) for runtime configuration with dark theme - Added global level controls to enable/disable levels across all components - Added timestamp format control (off/time/date/datetime options) - Implemented log rotation (10MB per file, 5 backups) - Added API endpoints for dynamic log configuration - Configured HTTP request logging with filtering via api.requests component - Intercepted APScheduler logs with proper formatting - Fixed persistence paths to use /app/memory for Docker volume compatibility - Fixed checkbox display bug in web UI (enabled_levels now properly shown) - Changed System Settings button to open in same tab instead of new window Components: bot, api, api.requests, autonomous, persona, vision, llm, conversation, mood, dm, scheduled, gpu, media, server, commands, sentiment, core, apscheduler All settings persist across container restarts via JSON config.
This commit is contained in:
@@ -9,6 +9,9 @@ import os
|
||||
import random
|
||||
import json
|
||||
import globals
|
||||
from utils.logger import get_logger
|
||||
|
||||
logger = get_logger('persona')
|
||||
|
||||
# ============================================================================
|
||||
# EVIL MODE PERSISTENCE
|
||||
@@ -40,16 +43,16 @@ def save_evil_mode_state(saved_role_color=None):
|
||||
}
|
||||
with open(EVIL_MODE_STATE_FILE, "w", encoding="utf-8") as f:
|
||||
json.dump(state, f, indent=2)
|
||||
print(f"💾 Saved evil mode state: {state}")
|
||||
logger.debug(f"Saved evil mode state: {state}")
|
||||
except Exception as e:
|
||||
print(f"⚠️ Failed to save evil mode state: {e}")
|
||||
logger.error(f"Failed to save evil mode state: {e}")
|
||||
|
||||
|
||||
def load_evil_mode_state():
|
||||
"""Load evil mode state from JSON file"""
|
||||
try:
|
||||
if not os.path.exists(EVIL_MODE_STATE_FILE):
|
||||
print(f"ℹ️ No evil mode state file found, using defaults")
|
||||
logger.info(f"No evil mode state file found, using defaults")
|
||||
return False, "evil_neutral", None
|
||||
|
||||
with open(EVIL_MODE_STATE_FILE, "r", encoding="utf-8") as f:
|
||||
@@ -58,10 +61,10 @@ def load_evil_mode_state():
|
||||
evil_mode = state.get("evil_mode_enabled", False)
|
||||
evil_mood = state.get("evil_mood", "evil_neutral")
|
||||
saved_role_color = state.get("saved_role_color")
|
||||
print(f"📂 Loaded evil mode state: evil_mode={evil_mode}, mood={evil_mood}, saved_color={saved_role_color}")
|
||||
logger.debug(f"Loaded evil mode state: evil_mode={evil_mode}, mood={evil_mood}, saved_color={saved_role_color}")
|
||||
return evil_mode, evil_mood, saved_role_color
|
||||
except Exception as e:
|
||||
print(f"⚠️ Failed to load evil mode state: {e}")
|
||||
logger.error(f"Failed to load evil mode state: {e}")
|
||||
return False, "evil_neutral", None
|
||||
|
||||
|
||||
@@ -70,13 +73,13 @@ def restore_evil_mode_on_startup():
|
||||
evil_mode, evil_mood, saved_role_color = load_evil_mode_state()
|
||||
|
||||
if evil_mode:
|
||||
print("😈 Restoring evil mode from previous session...")
|
||||
logger.debug("Restoring evil mode from previous session...")
|
||||
globals.EVIL_MODE = True
|
||||
globals.EVIL_DM_MOOD = evil_mood
|
||||
globals.EVIL_DM_MOOD_DESCRIPTION = load_evil_mood_description(evil_mood)
|
||||
print(f"😈 Evil mode restored: {evil_mood}")
|
||||
logger.info(f"Evil mode restored: {evil_mood}")
|
||||
else:
|
||||
print("🎤 Normal mode active")
|
||||
logger.info("Normal mode active")
|
||||
|
||||
return evil_mode
|
||||
|
||||
@@ -90,7 +93,7 @@ def get_evil_miku_lore() -> str:
|
||||
with open("evil_miku_lore.txt", "r", encoding="utf-8") as f:
|
||||
return f.read()
|
||||
except Exception as e:
|
||||
print(f"⚠️ Failed to load evil_miku_lore.txt: {e}")
|
||||
logger.error(f"Failed to load evil_miku_lore.txt: {e}")
|
||||
return "## EVIL MIKU LORE\n[File could not be loaded]"
|
||||
|
||||
|
||||
@@ -100,7 +103,7 @@ def get_evil_miku_prompt() -> str:
|
||||
with open("evil_miku_prompt.txt", "r", encoding="utf-8") as f:
|
||||
return f.read()
|
||||
except Exception as e:
|
||||
print(f"⚠️ Failed to load evil_miku_prompt.txt: {e}")
|
||||
logger.error(f"Failed to load evil_miku_prompt.txt: {e}")
|
||||
return "## EVIL MIKU PROMPT\n[File could not be loaded]"
|
||||
|
||||
|
||||
@@ -110,7 +113,7 @@ def get_evil_miku_lyrics() -> str:
|
||||
with open("evil_miku_lyrics.txt", "r", encoding="utf-8") as f:
|
||||
return f.read()
|
||||
except Exception as e:
|
||||
print(f"⚠️ Failed to load evil_miku_lyrics.txt: {e}")
|
||||
logger.error(f"Failed to load evil_miku_lyrics.txt: {e}")
|
||||
return "## EVIL MIKU LYRICS\n[File could not be loaded]"
|
||||
|
||||
|
||||
@@ -178,7 +181,7 @@ def load_evil_mood_description(mood_name: str) -> str:
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
return f.read().strip()
|
||||
except FileNotFoundError:
|
||||
print(f"⚠️ Evil mood file '{mood_name}' not found. Falling back to evil_neutral.")
|
||||
logger.warning(f"Evil mood file '{mood_name}' not found. Falling back to evil_neutral.")
|
||||
try:
|
||||
with open(os.path.join("moods", "evil", "evil_neutral.txt"), "r", encoding="utf-8") as f:
|
||||
return f.read().strip()
|
||||
@@ -338,13 +341,13 @@ async def get_current_role_color(client) -> str:
|
||||
if role.name.lower() in ["miku color", "miku colour", "miku-color"]:
|
||||
# Convert discord.Color to hex
|
||||
hex_color = f"#{role.color.value:06x}"
|
||||
print(f"🎨 Current role color: {hex_color}")
|
||||
logger.debug(f"Current role color: {hex_color}")
|
||||
return hex_color
|
||||
|
||||
print("⚠️ No 'Miku Color' role found in any server")
|
||||
logger.warning("No 'Miku Color' role found in any server")
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"⚠️ Failed to get current role color: {e}")
|
||||
logger.warning(f"Failed to get current role color: {e}")
|
||||
return None
|
||||
|
||||
|
||||
@@ -377,14 +380,14 @@ async def set_role_color(client, hex_color: str):
|
||||
if color_role:
|
||||
await color_role.edit(color=discord_color, reason="Evil mode color change")
|
||||
updated_count += 1
|
||||
print(f" 🎨 Updated role color in {guild.name}: #{hex_color}")
|
||||
logger.debug(f"Updated role color in {guild.name}: #{hex_color}")
|
||||
except Exception as e:
|
||||
print(f" ⚠️ Failed to update role color in {guild.name}: {e}")
|
||||
logger.warning(f"Failed to update role color in {guild.name}: {e}")
|
||||
|
||||
print(f"🎨 Updated role color in {updated_count} server(s) to #{hex_color}")
|
||||
logger.info(f"Updated role color in {updated_count} server(s) to #{hex_color}")
|
||||
return updated_count > 0
|
||||
except Exception as e:
|
||||
print(f"⚠️ Failed to set role color: {e}")
|
||||
logger.error(f"Failed to set role color: {e}")
|
||||
return False
|
||||
|
||||
|
||||
@@ -398,7 +401,7 @@ async def apply_evil_mode_changes(client, change_username=True, change_pfp=True,
|
||||
change_nicknames: Whether to change server nicknames (default True, but skip on startup restore)
|
||||
change_role_color: Whether to change role color (default True, but skip on startup restore)
|
||||
"""
|
||||
print("😈 Enabling Evil Mode...")
|
||||
logger.info("Enabling Evil Mode...")
|
||||
|
||||
# Save current role color before changing (if we're actually changing it)
|
||||
if change_role_color:
|
||||
@@ -412,9 +415,9 @@ async def apply_evil_mode_changes(client, change_username=True, change_pfp=True,
|
||||
if change_username:
|
||||
try:
|
||||
await client.user.edit(username="Evil Miku")
|
||||
print("✅ Changed bot username to 'Evil Miku'")
|
||||
logger.debug("Changed bot username to 'Evil Miku'")
|
||||
except Exception as e:
|
||||
print(f"⚠️ Could not change bot username: {e}")
|
||||
logger.error(f"Could not change bot username: {e}")
|
||||
|
||||
# Update nicknames in all servers
|
||||
if change_nicknames:
|
||||
@@ -431,7 +434,7 @@ async def apply_evil_mode_changes(client, change_username=True, change_pfp=True,
|
||||
# Save state to file
|
||||
save_evil_mode_state()
|
||||
|
||||
print("😈 Evil Mode enabled!")
|
||||
logger.info("Evil Mode enabled!")
|
||||
|
||||
|
||||
async def revert_evil_mode_changes(client, change_username=True, change_pfp=True, change_nicknames=True, change_role_color=True):
|
||||
@@ -444,16 +447,16 @@ async def revert_evil_mode_changes(client, change_username=True, change_pfp=True
|
||||
change_nicknames: Whether to change server nicknames (default True, but skip on startup restore)
|
||||
change_role_color: Whether to restore role color (default True, but skip on startup restore)
|
||||
"""
|
||||
print("🎤 Disabling Evil Mode...")
|
||||
logger.info("Disabling Evil Mode...")
|
||||
globals.EVIL_MODE = False
|
||||
|
||||
# Change bot username back
|
||||
if change_username:
|
||||
try:
|
||||
await client.user.edit(username="Hatsune Miku")
|
||||
print("✅ Changed bot username back to 'Hatsune Miku'")
|
||||
logger.debug("Changed bot username back to 'Hatsune Miku'")
|
||||
except Exception as e:
|
||||
print(f"⚠️ Could not change bot username: {e}")
|
||||
logger.error(f"Could not change bot username: {e}")
|
||||
|
||||
# Update nicknames in all servers back to normal
|
||||
if change_nicknames:
|
||||
@@ -469,16 +472,16 @@ async def revert_evil_mode_changes(client, change_username=True, change_pfp=True
|
||||
_, _, saved_color = load_evil_mode_state()
|
||||
if saved_color:
|
||||
await set_role_color(client, saved_color)
|
||||
print(f"🎨 Restored role color to {saved_color}")
|
||||
logger.debug(f"Restored role color to {saved_color}")
|
||||
else:
|
||||
print("⚠️ No saved role color found, skipping color restoration")
|
||||
logger.warning("No saved role color found, skipping color restoration")
|
||||
except Exception as e:
|
||||
print(f"⚠️ Failed to restore role color: {e}")
|
||||
logger.error(f"Failed to restore role color: {e}")
|
||||
|
||||
# Save state to file (this will clear saved_role_color since we're back to normal)
|
||||
save_evil_mode_state(saved_role_color=None)
|
||||
|
||||
print("🎤 Evil Mode disabled!")
|
||||
logger.info("Evil Mode disabled!")
|
||||
|
||||
|
||||
async def update_all_evil_nicknames(client):
|
||||
@@ -505,9 +508,9 @@ async def update_evil_server_nickname(client, guild_id: int):
|
||||
me = guild.get_member(client.user.id)
|
||||
if me:
|
||||
await me.edit(nick=nickname)
|
||||
print(f"😈 Changed nickname to '{nickname}' in server {guild.name}")
|
||||
logger.debug(f"Changed nickname to '{nickname}' in server {guild.name}")
|
||||
except Exception as e:
|
||||
print(f"⚠️ Failed to update evil nickname in guild {guild_id}: {e}")
|
||||
logger.error(f"Failed to update evil nickname in guild {guild_id}: {e}")
|
||||
|
||||
|
||||
async def revert_all_nicknames(client):
|
||||
@@ -524,7 +527,7 @@ async def set_evil_profile_picture(client):
|
||||
evil_pfp_path = "memory/profile_pictures/evil_pfp.png"
|
||||
|
||||
if not os.path.exists(evil_pfp_path):
|
||||
print(f"⚠️ Evil profile picture not found at {evil_pfp_path}")
|
||||
logger.error(f"Evil profile picture not found at {evil_pfp_path}")
|
||||
return False
|
||||
|
||||
try:
|
||||
@@ -532,10 +535,10 @@ async def set_evil_profile_picture(client):
|
||||
avatar_bytes = f.read()
|
||||
|
||||
await client.user.edit(avatar=avatar_bytes)
|
||||
print("😈 Set evil profile picture")
|
||||
logger.debug("Set evil profile picture")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"⚠️ Failed to set evil profile picture: {e}")
|
||||
logger.error(f"Failed to set evil profile picture: {e}")
|
||||
return False
|
||||
|
||||
|
||||
@@ -554,12 +557,12 @@ async def restore_normal_profile_picture(client):
|
||||
avatar_bytes = f.read()
|
||||
|
||||
await client.user.edit(avatar=avatar_bytes)
|
||||
print(f"🎤 Restored normal profile picture from {path}")
|
||||
logger.debug(f"Restored normal profile picture from {path}")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"⚠️ Failed to restore from {path}: {e}")
|
||||
logger.error(f"Failed to restore from {path}: {e}")
|
||||
|
||||
print("⚠️ Could not restore normal profile picture - no backup found")
|
||||
logger.error("Could not restore normal profile picture - no backup found")
|
||||
return False
|
||||
|
||||
|
||||
@@ -602,4 +605,4 @@ async def rotate_evil_mood():
|
||||
globals.EVIL_DM_MOOD_DESCRIPTION = load_evil_mood_description(new_mood)
|
||||
save_evil_mode_state() # Save state when mood rotates
|
||||
|
||||
print(f"😈 Evil mood rotated from {old_mood} to {new_mood}")
|
||||
logger.info(f"Evil mood rotated from {old_mood} to {new_mood}")
|
||||
|
||||
Reference in New Issue
Block a user