Coverage for railway / core / logging.py: 93%
29 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-11 00:06 +0900
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-11 00:06 +0900
1"""Logging initialization for Railway Framework."""
3import sys
4from typing import TYPE_CHECKING
6from loguru import logger
8if TYPE_CHECKING:
9 from railway.core.settings import LoggingSettings
12def _add_console_handler(
13 settings: "LoggingSettings",
14 handler_level: str,
15) -> None:
16 """Add console handler to logger."""
17 logger.add(
18 sys.stderr,
19 level=handler_level,
20 format=settings.format,
21 colorize=True,
22 )
25def _add_file_handler(
26 settings: "LoggingSettings",
27 path: str,
28 level: str,
29 rotation: str | None,
30 retention: str | None,
31) -> None:
32 """Add file handler to logger."""
33 logger.add(
34 path,
35 level=level,
36 format=settings.format,
37 rotation=rotation,
38 retention=retention,
39 encoding="utf-8",
40 )
43def _add_handler(settings: "LoggingSettings", handler_config: "LoggingSettings") -> None:
44 """Add a single handler based on configuration."""
45 from railway.core.settings import LoggingHandlerSettings
47 if not isinstance(handler_config, LoggingHandlerSettings): 47 ↛ 48line 47 didn't jump to line 48 because the condition on line 47 was never true
48 return
50 if handler_config.type == "console":
51 _add_console_handler(settings, handler_config.level)
52 elif handler_config.type == "file" and handler_config.path: 52 ↛ exitline 52 didn't return from function '_add_handler' because the condition on line 52 was always true
53 _add_file_handler(
54 settings,
55 handler_config.path,
56 handler_config.level,
57 handler_config.rotation,
58 handler_config.retention,
59 )
62def _add_default_handler(settings: "LoggingSettings") -> None:
63 """Add default console handler when no handlers configured."""
64 logger.add(
65 sys.stderr,
66 level=settings.level,
67 format=settings.format,
68 colorize=True,
69 )
72def init_logging(settings: "LoggingSettings") -> None:
73 """
74 Initialize loguru based on configuration.
76 Steps:
77 1. Remove default handler
78 2. Add configured handlers (console, file)
79 3. Apply log level and format
81 Args:
82 settings: LoggingSettings instance
83 """
84 # Remove default handler
85 logger.remove()
87 # Add handlers from config (functional approach using map-like pattern)
88 if settings.handlers:
89 for handler_config in settings.handlers:
90 _add_handler(settings, handler_config) # type: ignore[arg-type]
91 else:
92 # If no handlers configured, add default console handler
93 _add_default_handler(settings)
95 logger.debug(f"Logging initialized (level={settings.level})")
98def get_logger(name: str | None = None) -> "logger": # type: ignore[valid-type]
99 """
100 Get loguru logger instance.
102 Args:
103 name: Optional context name (for future use)
105 Returns:
106 loguru.logger instance
107 """
108 if name:
109 return logger.bind(context=name)
110 return logger
113# Export logger for convenience
114__all__ = ["init_logging", "get_logger", "logger"]