embeddings.py: face embedding cache used 'immich' for lookup but 'insightface' for storage, so the cache was never hit for locally- computed embeddings. Unified to 'insightface'/'siglip' throughout. This affects all users since ENABLE_CACHE now defaults to true. scheduler.py: INSIGHTFACE_HOME=/models/.insightface was having '.insightface' appended again, making buffalo_l check always report 'will download'. Also catch BaseException (not just Exception) so a SystemExit from a library call can't silently kill all future runs. log_config.py: handlers.clear() abandoned open FileHandler fds on each scheduled main() call. Close each handler properly before removal. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
58 lines
1.7 KiB
Python
58 lines
1.7 KiB
Python
"""Logging configuration for winnow."""
|
|
|
|
import logging
|
|
import os
|
|
import warnings
|
|
|
|
from rich.console import Console
|
|
from rich.logging import RichHandler
|
|
|
|
# Shared console instance - must be the same as used by Progress bars
|
|
console = Console()
|
|
|
|
NOISY_LOGGERS = (
|
|
"urllib3",
|
|
"PIL",
|
|
"ultralytics",
|
|
"insightface",
|
|
"onnxruntime",
|
|
"matplotlib",
|
|
"transformers",
|
|
"torch",
|
|
)
|
|
|
|
|
|
def setup_logging(verbose: bool = False) -> logging.Logger:
|
|
"""Configure logging with Rich console and file output."""
|
|
level = logging.DEBUG if verbose else logging.INFO
|
|
|
|
# Configure root logger; close existing handlers before replacing them
|
|
root = logging.getLogger()
|
|
root.setLevel(level)
|
|
for h in root.handlers[:]:
|
|
h.close()
|
|
root.removeHandler(h)
|
|
|
|
# Rich console handler - uses shared console to avoid breaking progress bars
|
|
root.addHandler(RichHandler(rich_tracebacks=True, markup=True, console=console))
|
|
|
|
# File handler (always debug level) — log file respects OUTPUT_DIR if set
|
|
log_dir = os.environ.get("OUTPUT_DIR", ".")
|
|
os.makedirs(log_dir, exist_ok=True)
|
|
log_path = os.path.join(log_dir, "winnow.log")
|
|
file_handler = logging.FileHandler(log_path)
|
|
file_handler.setLevel(logging.DEBUG)
|
|
file_handler.setFormatter(logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s"))
|
|
root.addHandler(file_handler)
|
|
|
|
# Silence noisy libraries
|
|
for lib in NOISY_LOGGERS:
|
|
logging.getLogger(lib).setLevel(logging.WARNING)
|
|
|
|
# Suppress Python warnings from ML libraries
|
|
warnings.filterwarnings("ignore", category=UserWarning, module="onnxruntime")
|
|
warnings.filterwarnings("ignore", category=FutureWarning, module="transformers")
|
|
|
|
return root
|
|
|