File size: 1,940 Bytes
3d0bf41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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