4337a31b80
Major improvements to GUI stability and internationalization: - Fix GUI freezing by implementing threaded audio analysis - Add AudioAnalysisWorker thread for background processing - Progress signals with percentage updates - Thread-safe communication via Qt signals - Add comprehensive CLI logging system - 5 log levels: ERROR, WARN, INFO, DEBUG, TRACE - Command line control: --log-level, --log-file - Real-time feedback during analysis operations - Implement CJK font fallback system - FontManager with 3-tier fallback (custom → system → default) - Cross-platform CJK font detection (Windows/macOS/Linux) - Licensing-safe fonts/ directory with gitignored font files - Setup utility and comprehensive documentation - Fix numpy array formatting issue with BPM detection - Add progress indicators for long-running operations - Preserve fonts directory structure with placeholder file 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
95 lines
2.9 KiB
Python
95 lines
2.9 KiB
Python
"""
|
|
Logging configuration for the Audio Mastering Toolkit.
|
|
Provides CLI configurable logging with different verbosity levels.
|
|
"""
|
|
|
|
import logging
|
|
import sys
|
|
from typing import Optional
|
|
|
|
|
|
def setup_logging(level: str = "INFO", log_to_file: bool = False) -> logging.Logger:
|
|
"""
|
|
Setup logging configuration for the application.
|
|
|
|
Args:
|
|
level: Logging level (ERROR, WARN, INFO, DEBUG, TRACE)
|
|
log_to_file: Whether to also log to file
|
|
|
|
Returns:
|
|
Configured logger instance
|
|
"""
|
|
# Convert level string to logging constant
|
|
level_map = {
|
|
'ERROR': logging.ERROR,
|
|
'WARN': logging.WARNING,
|
|
'WARNING': logging.WARNING,
|
|
'INFO': logging.INFO,
|
|
'DEBUG': logging.DEBUG,
|
|
'TRACE': 5 # Custom level below DEBUG
|
|
}
|
|
|
|
# Add custom TRACE level
|
|
logging.addLevelName(5, 'TRACE')
|
|
|
|
numeric_level = level_map.get(level.upper(), logging.INFO)
|
|
|
|
# Create formatter
|
|
formatter = logging.Formatter(
|
|
'%(asctime)s [%(levelname)s] %(name)s: %(message)s',
|
|
datefmt='%H:%M:%S'
|
|
)
|
|
|
|
# Setup console handler
|
|
console_handler = logging.StreamHandler(sys.stdout)
|
|
console_handler.setFormatter(formatter)
|
|
console_handler.setLevel(numeric_level)
|
|
|
|
# Setup root logger
|
|
root_logger = logging.getLogger()
|
|
root_logger.setLevel(numeric_level)
|
|
root_logger.handlers.clear() # Clear any existing handlers
|
|
root_logger.addHandler(console_handler)
|
|
|
|
# Optional file logging
|
|
if log_to_file:
|
|
file_handler = logging.FileHandler('audio_analysis.log')
|
|
file_handler.setFormatter(formatter)
|
|
file_handler.setLevel(numeric_level)
|
|
root_logger.addHandler(file_handler)
|
|
|
|
# Add trace method to all loggers
|
|
def trace(self, message, *args, **kwargs):
|
|
if self.isEnabledFor(5):
|
|
self._log(5, message, args, **kwargs)
|
|
|
|
logging.Logger.trace = trace
|
|
|
|
# Create main application logger
|
|
app_logger = logging.getLogger('audio_mastering')
|
|
app_logger.info(f"Logging initialized at {level.upper()} level")
|
|
|
|
return app_logger
|
|
|
|
|
|
def parse_log_args() -> tuple[str, bool]:
|
|
"""
|
|
Parse command line arguments for logging configuration.
|
|
|
|
Returns:
|
|
Tuple of (log_level, log_to_file)
|
|
"""
|
|
import argparse
|
|
|
|
parser = argparse.ArgumentParser(add_help=False) # Don't interfere with main arg parsing
|
|
parser.add_argument('--log-level', '-l',
|
|
choices=['ERROR', 'WARN', 'INFO', 'DEBUG', 'TRACE'],
|
|
default='INFO',
|
|
help='Set logging verbosity level')
|
|
parser.add_argument('--log-file', action='store_true',
|
|
help='Also log to audio_analysis.log file')
|
|
|
|
# Parse known args only (ignore others for main app)
|
|
args, _ = parser.parse_known_args()
|
|
|
|
return args.log_level, args.log_file |