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:
2026-01-10 20:46:19 +02:00
parent ce00f9bd95
commit 32c2a7b930
34 changed files with 2766 additions and 936 deletions

View File

@@ -8,6 +8,9 @@ import globals
from langchain_community.vectorstores import FAISS
from langchain_text_splitters import CharacterTextSplitter, RecursiveCharacterTextSplitter
from langchain_core.documents import Document
from utils.logger import get_logger
logger = get_logger('core')
# switch_model() removed - llama-swap handles model switching automatically
@@ -21,7 +24,7 @@ async def is_miku_addressed(message) -> bool:
# Safety check: ensure guild and guild.me exist
if not message.guild or not message.guild.me:
print(f"⚠️ Warning: Invalid guild or guild.me in message from {message.author}")
logger.warning(f"Invalid guild or guild.me in message from {message.author}")
return False
# If message contains a ping for Miku, return true
@@ -35,7 +38,7 @@ async def is_miku_addressed(message) -> bool:
if referenced_msg.author == message.guild.me:
return True
except Exception as e:
print(f"⚠️ Could not fetch referenced message: {e}")
logger.warning(f"Could not fetch referenced message: {e}")
cleaned = message.content.strip()