From 3cd4d1e85dcb6aa8d195ed0a35e458661600ca5e Mon Sep 17 00:00:00 2001 From: Guillaume Broggi <25569517+GuillaumeBroggi@users.noreply.github.com> Date: Thu, 21 Sep 2023 14:07:24 +0200 Subject: [PATCH] added flexible logging #171 --- src/f3dasm/_src/logger.py | 38 +++++++++++++++++++++--------- src/f3dasm/_src/logger_config.yaml | 36 ++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 11 deletions(-) create mode 100644 src/f3dasm/_src/logger_config.yaml diff --git a/src/f3dasm/_src/logger.py b/src/f3dasm/_src/logger.py index d41e8543..ea1d9bc5 100644 --- a/src/f3dasm/_src/logger.py +++ b/src/f3dasm/_src/logger.py @@ -9,8 +9,10 @@ import logging import os from logging import FileHandler, StreamHandler +from pathlib import Path from time import sleep from typing import TextIO +import yaml if os.name == 'nt': import msvcrt @@ -30,10 +32,6 @@ # # ============================================================================= -# Logging things -logging.basicConfig(format="%(asctime)s - %(message)s", level=logging.INFO) -logging.getLogger('tensorflow').setLevel(logging.ERROR) - class DistributedFileHandler(FileHandler): def __init__(self, filename): @@ -68,7 +66,9 @@ def emit(self, record): except IOError as e: # the file is locked by another process if e.errno == errno.EAGAIN: - logger.debug("The log file is currently locked by another process. Retrying in 1 second...") + logger.debug( + "The log file is currently locked by another process. Retrying in 1 second..." + ) sleep(1) else: logger.info(f"An unexpected IOError occurred: {e}") @@ -107,19 +107,35 @@ def _unlock_file(file): fcntl.flock(file, fcntl.LOCK_UN) -def _time_and_log( - func: Callable, logger=logging.Logger -) -> Callable: +def _time_and_log(func: Callable, logger=logging.Logger) -> Callable: @wraps(func) def wrapper(*args: Any, **kwargs: Any) -> Any: start_time = perf_counter() value = func(*args, **kwargs) - logger.debug(f"Called {func.__name__} and time taken: {perf_counter() - start_time:.2f}s") + logger.debug( + f"Called {func.__name__} and time taken: {perf_counter() - start_time:.2f}s" + ) return value return wrapper +# f3dasm can be used as a library or as an application +# If used as a library, the user is responsible to define a f3dasm logger +# Otherwise, the default behavior is to load the f3dsam logging configuration + +logger_name = "f3dsam" + +# Check for the existence of the f3dsam logger +# This is required because getLogger() creates the logger if it does not exist +# Loggers are stored in the logger manager (undocumented feature) +if logger_name not in logging.Logger.manager.loggerDict.keys(): + # If not, load the logging configuration that should create a f3dasm logger + config_path = Path(__file__).parent/"logger_config.yaml" + with open(config_path, "r") as f: + config = yaml.safe_load(f.read()) + logging.config.dictConfig(config) + +# Get existing logger without overwriting the existing configuration +logger = logging.getLogger(name="f3dsam") -# Create a logger -logger = logging.getLogger("f3dasm") time_and_log = partial(_time_and_log, logger=logger) diff --git a/src/f3dasm/_src/logger_config.yaml b/src/f3dasm/_src/logger_config.yaml new file mode 100644 index 00000000..220a0942 --- /dev/null +++ b/src/f3dasm/_src/logger_config.yaml @@ -0,0 +1,36 @@ +# This configuration file defines the default logging behavior of f3dasm. +# +# Authorship & Credits +# ============================================================================= +# __author__ = 'Guillaume Broggi (g.broggi@tudelft.nl)' +# __credits__ = ['Guillaume Broggi'] +# __status__ = 'Stable' +# ============================================================================= +# +version: 1 +disable_existing_loggers: False +formatters: + standard: + format: "%(asctime)s - %(name)s - %(message)s" +handlers: + console: + class: logging.StreamHandler + level: INFO + formatter: standard + stream: ext://sys.stderr + file: + class: logging.handlers.RotatingFileHandler + level: INFO + formatter: standard + filename: f3dsam.log + maxBytes: 10485760 # 10MB + backupCount: 5 # After reaching maxBytes, a new file is opened + encoding: utf8 + mode: w # is ignored and forced to "a" with RotatingFileHandler +loggers: + f3dsam: + level: INFO + handlers: [console, file] + propagate: no + +