From a120f2cc1439328d38e4aa274d14f7db6b378f85 Mon Sep 17 00:00:00 2001 From: tsmorz Date: Tue, 21 Oct 2025 10:27:43 +0200 Subject: [PATCH] add logger setup tools --- .coverage | Bin 53248 -> 53248 bytes src/__main__.py | 8 ------ src/change_me/__main__.py | 22 +++++++++++++++ src/change_me/definitions.py | 35 ++++++++++++++++++++++- src/change_me/utils.py | 52 +++++++++++++++++++++++++++++++++++ tests/utils_test.py | 15 ++++++++++ 6 files changed, 123 insertions(+), 9 deletions(-) delete mode 100644 src/__main__.py create mode 100644 src/change_me/__main__.py create mode 100644 src/change_me/utils.py create mode 100644 tests/utils_test.py diff --git a/.coverage b/.coverage index ee26b86057de49bb8e31357602d8bc76dbd6ca39..b4c119fca9d21fe12b318eba9414cd95f0c9e6a5 100644 GIT binary patch delta 275 zcmZozz}&Eac>{|BA1hxP1OFQSP<|G^U3_Vq1qDL*n1Wa*uk-ih%uUS9i;veUsGNMz z&vCMkKPQ_%GYdnb@?=4O%gL|(x%f&;GINT7@}W#XVSSkJz6FlciA)0v9v? zeFpxY{BQa10}a2(ug}BG!pJGbyi4fAPsUTSTueZo7*o{8kaxnYj4Yg-d`w&n3=GWt dZyET1^MB!g3)FO{|B4-4Nx2L3htq5Rx@2R91}Y~-7~%g>QJH!(9WK3=b&(t~;O9zPGZ zP$m|JM*YbL{46KG_UD>B&p!>Q@el()58omFwftc~jhpybJy{w>8G&l7`Qh4GU}7$8 z%wa5z`XFhr5u4}5rzvnS@qc9C|H=OmsQ)RyG#e8OBPSmd7b_zRCx~WXU|{0^!odHV Q{|ivT3;xYt=JOZ;0M+|9J^%m! diff --git a/src/__main__.py b/src/__main__.py deleted file mode 100644 index 5f43e54..0000000 --- a/src/__main__.py +++ /dev/null @@ -1,8 +0,0 @@ -"""Sample doc string.""" - -from loguru import logger - - -def main() -> None: - """Run the pipeline.""" - logger.info("Hello world!") diff --git a/src/change_me/__main__.py b/src/change_me/__main__.py new file mode 100644 index 0000000..60bef99 --- /dev/null +++ b/src/change_me/__main__.py @@ -0,0 +1,22 @@ +"""Sample doc string.""" + +import argparse + +from loguru import logger + +from change_me.definitions import DEFAULT_LOG_LEVEL +from change_me.utils import setup_logger + + +def main(log_level: str) -> None: + """Run the pipeline.""" + setup_logger(filename="log_file", log_dir=None, log_level=log_level) + logger.info("Hello world!") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("--log-level", default=DEFAULT_LOG_LEVEL, type=str) + args = parser.parse_args() + + main(log_level=args.log_level) diff --git a/src/change_me/definitions.py b/src/change_me/definitions.py index c35ec0d..973e831 100644 --- a/src/change_me/definitions.py +++ b/src/change_me/definitions.py @@ -1,3 +1,36 @@ -"""Sample doc string.""" +"""Common definitions for this module.""" + +from dataclasses import dataclass +from pathlib import Path + +import numpy as np + +np.set_printoptions(precision=3, floatmode="fixed", suppress=True) + + +# --- Directories --- +ROOT_DIR: Path = Path("src").parent +DATA_DIR: Path = ROOT_DIR / "data" +RECORDINGS_DIR: Path = DATA_DIR / "recordings" +LOG_DIR: Path = DATA_DIR / "logs" + +# Default encoding +ENCODING: str = "utf-8" + +DATE_FORMAT = "%Y-%m-%d_%H-%M-%S" DUMMY_VARIABLE = "dummy_variable" + + +@dataclass +class LogLevel: + """Log levels for loguru.""" + + debug: str = "DEBUG" + info: str = "INFO" + warning: str = "WARNING" + error: str = "ERROR" + critical: str = "CRITICAL" + + +DEFAULT_LOG_LEVEL = LogLevel.info diff --git a/src/change_me/utils.py b/src/change_me/utils.py new file mode 100644 index 0000000..2ecbf64 --- /dev/null +++ b/src/change_me/utils.py @@ -0,0 +1,52 @@ +"""Configure the logger.""" + +import sys +from datetime import datetime +from pathlib import Path + +from loguru import logger + +from change_me.definitions import DATE_FORMAT, DEFAULT_LOG_LEVEL, ENCODING, LOG_DIR + + +def create_timestamped_filepath(suffix: str, output_dir: Path, prefix: str) -> Path: + """Generate a timestamped filename. + + :param suffix: Suffix to append to the timestamped filename. + :param output_dir: Output directory. + :param prefix: Prefix to append to the timestamped filename. + :return: Path to the timestamped filename. + """ + timestamp = datetime.now().strftime(DATE_FORMAT) + filepath = output_dir / f"{prefix}_{timestamp}.{suffix}" + filepath.parent.mkdir(parents=True, exist_ok=True) # create dirs if missing + filepath.touch(exist_ok=True) # create empty file (don't overwrite) + return filepath + + +def setup_logger( + filename: str, + stderr_level: str = DEFAULT_LOG_LEVEL, + log_level: str = DEFAULT_LOG_LEVEL, + log_dir: Path | None = None, +) -> Path: + """Configure the logger. + + :param filename: Name of the file to create. + :param stderr_level: Logging level to use. + :param log_level: Logging level to use. + :param log_dir: Logging directory to use. + :return: Path to the created logfile. + """ + logger.remove() + + if log_dir is None: + log_filepath = LOG_DIR + else: + log_filepath = log_dir + filepath_with_time = create_timestamped_filepath( + output_dir=log_filepath, prefix=filename, suffix="log" + ) + logger.add(sys.stderr, level=stderr_level) + logger.add(filepath_with_time, level=log_level, encoding=ENCODING, enqueue=True) + return filepath_with_time diff --git a/tests/utils_test.py b/tests/utils_test.py new file mode 100644 index 0000000..e5ddf72 --- /dev/null +++ b/tests/utils_test.py @@ -0,0 +1,15 @@ +"""Test the utils module.""" + +from pathlib import Path +from tempfile import TemporaryDirectory + +from change_me.utils import setup_logger + + +def test_logger_init(): + """Test logger initialization.""" + with TemporaryDirectory() as log_dir: + log_dir_path = Path(log_dir) + log_filepath = setup_logger(filename="log_file", log_dir=log_dir_path) + assert Path(log_filepath).exists() + assert not Path(log_filepath).exists()