Commit 8e9d22fe authored by Jan Reimes's avatar Jan Reimes
Browse files

♻️ refactor(logging): restructure logger configuration and console instance

- Moved logger configuration to a dedicated function for clarity.
- Introduced a singleton console instance for consistent logging output.
- Removed direct console instantiation from the logging module.
- Updated imports in CLI modules to use the new console instance.
parent f1c3ba55
Loading
Loading
Loading
Loading
+0 −5
Original line number Diff line number Diff line
@@ -2,16 +2,11 @@

from __future__ import annotations

import logging
from pathlib import Path
from typing import Annotated

import typer

from tdoc_crawler.logging import DEFAULT_LEVEL as LOGGING_DEFAULT_LEVEL

DEFAULT_VERBOSITY = logging.getLevelName(LOGGING_DEFAULT_LEVEL)

# Arguments
TDocIdsArgument = Annotated[list[str] | None, typer.Argument(help="TDoc identifiers to query")]
TDocIdArgument = Annotated[str, typer.Argument(help="TDoc identifier to download and open")]

src/tdoc_crawler/cli/console.py

deleted100644 → 0
+0 −21
Original line number Diff line number Diff line
"""Singleton Console instance for CLI output.

This module provides a cached Console instance to avoid multiple
instantiations across the CLI module.
"""

from __future__ import annotations

from functools import cache

from rich.console import Console


@cache
def get_console() -> Console:
    """Get the singleton Console instance.

    Returns:
        Cached Console instance for consistent CLI output.
    """
    return Console()
+1 −1
Original line number Diff line number Diff line
@@ -6,8 +6,8 @@ from typing import Any

from rich.table import Table

from tdoc_crawler.cli.console import get_console
from tdoc_crawler.database.specs import SpecCrawlResult
from tdoc_crawler.logging import get_console
from tdoc_crawler.meetings.models import MeetingMetadata
from tdoc_crawler.specs.models import SpecQueryResult
from tdoc_crawler.tdocs.models import TDocMetadata
+41 −15
Original line number Diff line number Diff line
@@ -14,10 +14,16 @@ from rich.logging import RichHandler
# Default logging level for all loggers
DEFAULT_LEVEL: Final[int] = logging.WARNING

# Configure the root logger with RichHandler on first import
_console: Final[Console] = Console()

@functools.cache
def configure_logger() -> None:
    """Configure the root logger with RichHandler.

    This function sets up the RichHandler on the root logger, which all
    child loggers will inherit. It is called on first import of this module.
    """
    _rich_handler: RichHandler = RichHandler(
    console=_console,
        console=get_console(),
        show_time=True,
        show_path=False,
        rich_tracebacks=True,
@@ -31,6 +37,22 @@ logging.root.addHandler(_rich_handler)
    logging.root.setLevel(DEFAULT_LEVEL)


@functools.cache
def get_console() -> Console:
    """Get the Rich console instance used by the logging handlers.

    This allows other parts of the application to use the same console
    for consistent output formatting.

    @functools.cache decorator ensures a simple singleton instance of Console is used throughout the application.

    Returns:
        The Rich Console instance configured for logging.
    """
    _console: Console = Console()
    return _console


@functools.cache
def get_logger(name: str) -> logging.Logger:
    """Get a logger instance with RichHandler configured.
@@ -77,3 +99,7 @@ def set_verbosity(level: int | str) -> None:
            raise ValueError(f"Invalid logging level name: {level}")

    logging.root.setLevel(level)


# initialize logger configuration on first import (@functools.cache ensures this runs only once)
configure_logger()