Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions src/harmonization_framework/replay_log/replay_logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,34 @@ class Event:
dataset: str

def to_log(self):
"""
Serialize an event to a JSON-compatible dict.

Returns:
dict with keys:
- action: serialized harmonization rule
- dataset: dataset identifier
"""
log = {
"action": self.action.serialize(),
"dataset": self.dataset,
}
return log

def _get_log_level(level: int):
"""
Map a numeric log level to a logging module constant.

Args:
level: integer in the range 1-4.
1 -> CRITICAL
2 -> ERROR
3 -> INFO
4 -> DEBUG

Returns:
A logging level constant.
"""
match level:
case 1:
return logging.CRITICAL
Expand All @@ -29,9 +50,22 @@ def _get_log_level(level: int):
return ValueError(f"Invalid log level: {level}")

def configure_logger(level: int, log_file: str):
"""
Configure a replay logger that writes JSON lines to a file.

Args:
level: integer log level (1-4).
log_file: path to the output log file.

Returns:
A configured logger instance.
"""
# create logger
logger = logging.getLogger("ReplayLogger")

# clear any existing handlers to avoid duplicate log entries
logger.handlers.clear()

# set logging level
log_level = _get_log_level(level)
logger.setLevel(log_level)
Expand All @@ -48,5 +82,8 @@ def configure_logger(level: int, log_file: str):
return logger

def log_operation(logger, action, dataset):
"""
Log a single replay event for a given harmonization action and dataset.
"""
event = Event(action, dataset)
logger.info(json.dumps(event.to_log()))
20 changes: 20 additions & 0 deletions tests/test_replay_logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import logging

from harmonization_framework.replay_log import replay_logger as rlog


def test_configure_logger_clears_handlers(tmp_path):
log1 = tmp_path / "log1.jsonl"
log2 = tmp_path / "log2.jsonl"

logger1 = rlog.configure_logger(3, str(log1))
assert len(logger1.handlers) == 1

logger2 = rlog.configure_logger(3, str(log2))
assert logger2 is logger1
assert len(logger2.handlers) == 1

# Ensure the active handler points to the most recent log file
handler = logger2.handlers[0]
assert isinstance(handler, logging.FileHandler)
assert handler.baseFilename == str(log2)