feat(log): add SimpleLogger for terminal logging without external backends
This commit is contained in:
parent
d9202b0390
commit
ae483b306f
2 changed files with 85 additions and 0 deletions
|
|
@ -6,10 +6,12 @@ This package provides a unified interface for logging to multiple backends
|
|||
|
||||
from experiment_logger.config_utils import load_yaml_config, merge_config_with_cli
|
||||
from experiment_logger.unified_logger import UnifiedLogger, get_logger
|
||||
from experiment_logger.simple_logger import SimpleLogger
|
||||
from experiment_logger.wandb_utils import finish_wandb, init_wandb
|
||||
|
||||
__all__ = [
|
||||
"UnifiedLogger",
|
||||
"SimpleLogger",
|
||||
"get_logger",
|
||||
"init_wandb",
|
||||
"finish_wandb",
|
||||
|
|
|
|||
83
src/experiment_logger/simple_logger.py
Normal file
83
src/experiment_logger/simple_logger.py
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
"""Simple terminal logger for running without external backends.
|
||||
|
||||
This is used for standalone package usage where WandB or TensorBoard are not desired.
|
||||
It preserves the same API as UnifiedLogger but simply prints to stdout.
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
|
||||
class SimpleLogger:
|
||||
"""Simple logger that implements the UnifiedLogger interface via print statements."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
run_name: str = "simple_run",
|
||||
config: Optional[Dict[str, Any]] = None,
|
||||
project_name: str = "none",
|
||||
entity: Optional[str] = None,
|
||||
base_dir: str = "runs",
|
||||
use_wandb: bool = False,
|
||||
save_code: bool = False,
|
||||
log_level: int = logging.INFO,
|
||||
_set_as_global: bool = False,
|
||||
):
|
||||
self.is_interactive = True
|
||||
self.run_name = run_name
|
||||
self.config = config or {}
|
||||
print(f"[INIT] SimpleLogger initialized for run: {run_name}")
|
||||
|
||||
def set_level(self, level: int):
|
||||
pass
|
||||
|
||||
def log_non_interactive(self, msg: str, *args, **kwargs):
|
||||
"""In SimpleLogger, we just print everything as we assume interactive use."""
|
||||
self.info(msg, *args, **kwargs)
|
||||
|
||||
def progress_bar(self, iterable=None, *args, **kwargs):
|
||||
"""Standard tqdm wrapper that falls back to range if tqdm is missing."""
|
||||
try:
|
||||
import tqdm
|
||||
|
||||
return tqdm.tqdm(iterable, *args, **kwargs)
|
||||
except ImportError:
|
||||
return iterable
|
||||
|
||||
def info(self, msg: str, *args, **kwargs):
|
||||
print(f"[INFO] {msg}")
|
||||
|
||||
def warning(self, msg: str, *args, **kwargs):
|
||||
print(f"[WARNING] {msg}")
|
||||
|
||||
def error(self, msg: str, *args, **kwargs):
|
||||
print(f"[ERROR] {msg}")
|
||||
|
||||
def debug(self, msg: str, *args, **kwargs):
|
||||
print(f"[DEBUG] {msg}")
|
||||
|
||||
def log(self, metrics: Dict[str, Any], step: Optional[int] = None, commit: bool = True):
|
||||
step_str = f"Step {step}" if step is not None else "Log"
|
||||
metric_str = ", ".join(f"{k}: {v}" for k, v in metrics.items())
|
||||
print(f"[{step_str}] {metric_str}")
|
||||
|
||||
def save_checkpoint(
|
||||
self,
|
||||
params: Any,
|
||||
step: int,
|
||||
prefix: str = "checkpoint",
|
||||
metadata: Optional[Dict[str, Any]] = None,
|
||||
):
|
||||
print(f"[SAVE] Checkpoint '{prefix}' would be saved at step {step} (SimpleLogger: No-Op)")
|
||||
|
||||
def save_final_model(self, params: Any, metadata: Optional[Dict[str, Any]] = None):
|
||||
print("[SAVE] Final model would be saved (SimpleLogger: No-Op)")
|
||||
|
||||
def finish(self):
|
||||
print(f"[FINISH] SimpleLogger finished for run: {self.run_name}")
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
self.finish()
|
||||
Reference in a new issue