Attach a file handler for formal runtime logs.
(settings: Settings | None = None)
| 49 | |
| 50 | |
| 51 | def configure_logging(settings: Settings | None = None) -> Path: |
| 52 | """Attach a file handler for formal runtime logs.""" |
| 53 | |
| 54 | settings = settings or get_settings() |
| 55 | log_dir = settings.runtime_logs_dir |
| 56 | log_dir.mkdir(parents=True, exist_ok=True) |
| 57 | |
| 58 | root_logger = logging.getLogger() |
| 59 | for handler in root_logger.handlers: |
| 60 | if getattr(handler, "_glm_desk_runtime_handler", False): |
| 61 | return log_dir |
| 62 | |
| 63 | handler = TimedRotatingFileHandler( |
| 64 | filename=str(log_dir / "app.log"), |
| 65 | when="midnight", |
| 66 | interval=1, |
| 67 | backupCount=max(settings.runtime_log_retention_days, 3), |
| 68 | encoding="utf-8", |
| 69 | ) |
| 70 | handler._glm_desk_runtime_handler = True # type: ignore[attr-defined] |
| 71 | handler.setLevel(getattr(logging, settings.runtime_log_level.upper(), logging.INFO)) |
| 72 | handler.setFormatter( |
| 73 | logging.Formatter( |
| 74 | "%(asctime)s | %(levelname)s | %(name)s | %(threadName)s | %(message)s", |
| 75 | datefmt="%Y-%m-%d %H:%M:%S", |
| 76 | ) |
| 77 | ) |
| 78 | root_logger.addHandler(handler) |
| 79 | desired_level = getattr(logging, settings.runtime_log_level.upper(), logging.INFO) |
| 80 | if root_logger.level == logging.NOTSET or root_logger.level > desired_level: |
| 81 | root_logger.setLevel(desired_level) |
| 82 | logging.captureWarnings(True) |
| 83 | return log_dir |
| 84 | |
| 85 | |
| 86 | class RuntimeLogService: |
no test coverage detected