"""Logging utilities for Myanmar Ghost project.""" import logging import sys from datetime import datetime from pathlib import Path from typing import Optional from loguru import logger as _logger def setup_logger( name: str = "myanmar_ghost", log_dir: Optional[str] = None, level: str = "INFO", format: str = None, ) -> logging.Logger: """Set up logger with file and console output. Args: name: Logger name log_dir: Directory for log files level: Logging level format: Custom log format Returns: Configured logger """ if format is None: format = ( "{time:YYYY-MM-DD HH:mm:ss} | " "{level: <8} | " "{name}:{function}:{line} | " "{message}" ) # Remove default handler _logger.remove() # Console output _logger.add( sys.stdout, format=format, level=level, colorize=True, ) # File output if log_dir: log_path = Path(log_dir) log_path.mkdir(parents=True, exist_ok=True) timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") log_file = log_path / f"{name}_{timestamp}.log" _logger.add( log_file, format=format, level=level, rotation="100 MB", retention="30 days", compression="zip", ) return _logger def get_logger(name: str = None) -> logging.Logger: """Get logger instance. Args: name: Logger name (optional) Returns: Logger instance """ return _logger class TrainingLogger: """Logger for training metrics and progress.""" def __init__( self, log_dir: str = "outputs/logs", experiment_name: str = "experiment", ): self.log_dir = Path(log_dir) self.log_dir.mkdir(parents=True, exist_ok=True) self.experiment_name = experiment_name self.metrics_history = [] timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") self.log_file = self.log_dir / f"{experiment_name}_{timestamp}.log" def log_metrics(self, metrics: dict, step: int) -> None: """Log metrics at a specific step.""" entry = { "step": step, "timestamp": datetime.now().isoformat(), **metrics, } self.metrics_history.append(entry) log_line = f"Step {step}: " + ", ".join( f"{k}={v:.4f}" if isinstance(v, float) else f"{k}={v}" for k, v in metrics.items() ) _logger.info(log_line) def log_epoch(self, epoch: int, metrics: dict) -> None: """Log metrics at epoch end.""" entry = { "epoch": epoch, "timestamp": datetime.now().isoformat(), **metrics, } self.metrics_history.append(entry) log_line = f"Epoch {epoch}: " + ", ".join( f"{k}={v:.4f}" if isinstance(v, float) else f"{k}={v}" for k, v in metrics.items() ) _logger.info(log_line) def save_history(self) -> str: """Save metrics history to file.""" import json with open(self.log_file, "w", encoding="utf-8") as f: json.dump(self.metrics_history, f, indent=2) return str(self.log_file) if __name__ == "__main__": logger = setup_logger("test_logger", "outputs/logs") logger.info("Logger initialized successfully")