Spaces:
Sleeping
Sleeping
| from __future__ import annotations | |
| import logging | |
| from typing import Iterable, Optional | |
| _CONFIGURED = False | |
| class _SrcOnlyFilter(logging.Filter): | |
| def filter(self, record: logging.LogRecord) -> bool: | |
| return bool(record.name.startswith("src.")) | |
| def configure_logging( | |
| *, | |
| level: int = logging.INFO, | |
| log_file: Optional[str] = "fin_assistant.log", | |
| src_only: bool = True, | |
| quiet_loggers: Optional[Iterable[str]] = None, | |
| ) -> None: | |
| """ | |
| Configure application logging once. | |
| - src_only=True: only emit logs from modules under the `src.` namespace. | |
| - quiet_loggers: set these logger names to WARNING to reduce noise. | |
| """ | |
| global _CONFIGURED | |
| if _CONFIGURED: | |
| return | |
| root = logging.getLogger() | |
| root.setLevel(level) | |
| formatter = logging.Formatter( | |
| fmt="%(asctime)s - %(name)s - %(levelname)s - %(message)s" | |
| ) | |
| handlers: list[logging.Handler] = [] | |
| stream_handler = logging.StreamHandler() | |
| stream_handler.setFormatter(formatter) | |
| handlers.append(stream_handler) | |
| if log_file: | |
| file_handler = logging.FileHandler(log_file) | |
| file_handler.setFormatter(formatter) | |
| handlers.append(file_handler) | |
| if src_only: | |
| f = _SrcOnlyFilter() | |
| for h in handlers: | |
| h.addFilter(f) | |
| # Avoid duplicating handlers on Streamlit reloads if something else configured root. | |
| # Only attach if root has no handlers yet. | |
| if not root.handlers: | |
| for h in handlers: | |
| root.addHandler(h) | |
| # Silence noisy third-party loggers by default. | |
| defaults = [ | |
| "httpx", | |
| "httpcore", | |
| "openai", | |
| "chromadb", | |
| "urllib3", | |
| "requests", | |
| "langchain", | |
| "langchain_core", | |
| "langchain_community", | |
| ] | |
| for name in list(quiet_loggers or []) + defaults: | |
| logging.getLogger(name).setLevel(logging.WARNING) | |
| _CONFIGURED = True | |