Coverage for src / monte_neo / utils / logger.py: 86%

29 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-01-28 16:27 +0200

1"""Logging utilities.""" 

2 

3from __future__ import annotations 

4 

5import logging 

6import sys 

7from pathlib import Path 

8 

9 

10def setup_logging( 

11 level: str = "INFO", 

12 log_file: str | Path | None = None, 

13) -> None: 

14 """Setup application logging. 

15 

16 Args: 

17 level: Log level string. 

18 log_file: Optional log file path. 

19 """ 

20 log_level = getattr(logging, level.upper(), logging.INFO) 

21 

22 # Create formatter 

23 formatter = logging.Formatter( 

24 "%(asctime)s | %(levelname)-8s | %(name)s | %(message)s", 

25 datefmt="%Y-%m-%d %H:%M:%S", 

26 ) 

27 

28 # Console handler 

29 console_handler: logging.Handler 

30 try: 

31 from rich.logging import RichHandler 

32 

33 from monte_neo.utils.console import console as shared_console 

34 

35 console_handler = RichHandler( 

36 console=shared_console, 

37 rich_tracebacks=True, 

38 show_time=True, 

39 show_path=False, 

40 ) 

41 except ImportError: 

42 console_handler = logging.StreamHandler(sys.stdout) 

43 console_handler.setFormatter(formatter) 

44 

45 console_handler.setLevel(log_level) 

46 

47 # Root logger 

48 root_logger = logging.getLogger("monte_neo") 

49 root_logger.setLevel(log_level) 

50 

51 # Remove existing handlers to avoid duplicates 

52 for h in root_logger.handlers[:]: 

53 root_logger.removeHandler(h) 

54 

55 root_logger.addHandler(console_handler) 

56 

57 # File handler if specified 

58 if log_file: 

59 file_handler = logging.FileHandler(log_file) 

60 file_handler.setFormatter(formatter) 

61 file_handler.setLevel(log_level) 

62 root_logger.addHandler(file_handler) 

63 

64 

65def get_logger(name: str) -> logging.Logger: 

66 """Get a logger for a module. 

67 

68 Args: 

69 name: Module name (typically __name__). 

70 

71 Returns: 

72 Logger instance. 

73 """ 

74 if name.startswith("monte_neo"): 

75 return logging.getLogger(name) 

76 return logging.getLogger(f"monte_neo.{name}")