Coverage for src/semware/utils/logging.py: 67%
15 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-09-09 02:15 -0700
« prev ^ index » next coverage.py v7.10.6, created at 2025-09-09 02:15 -0700
1"""Logging configuration using Loguru."""
3import sys
4from pathlib import Path
6from loguru import logger
9def setup_logging(
10 level: str = "INFO",
11 log_file: str | None = None,
12 rotation: str = "10 MB",
13 retention: str = "1 month",
14 compression: str = "zip",
15) -> None:
16 """Setup logging configuration with Loguru.
18 Args:
19 level: Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
20 log_file: Path to log file, if None only console logging
21 rotation: Log file rotation policy
22 retention: Log file retention policy
23 compression: Compression for rotated files
24 """
25 # Remove default handler
26 logger.remove()
28 # Add console handler with colors
29 logger.add(
30 sys.stderr,
31 level=level,
32 format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> | "
33 "<level>{level: <8}</level> | "
34 "<cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - "
35 "<level>{message}</level>",
36 colorize=True,
37 )
39 # Add file handler if specified
40 if log_file:
41 log_path = Path(log_file)
42 log_path.parent.mkdir(parents=True, exist_ok=True)
44 logger.add(
45 str(log_path),
46 level=level,
47 format="{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {name}:{function}:{line} - {message}",
48 rotation=rotation,
49 retention=retention,
50 compression=compression,
51 enqueue=True, # For thread safety
52 )
54 logger.info(f"Logging configured with level: {level}")
55 if log_file:
56 logger.info(f"Log file: {log_file}")
59def get_logger(name: str):
60 """Get a logger instance for the given name.
62 Args:
63 name: Logger name, typically __name__
65 Returns:
66 Logger instance
67 """
68 return logger.bind(name=name)