-
Notifications
You must be signed in to change notification settings - Fork 1
GEOPY-2420: change get_logger function to define setLevel #151
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from 3 commits
644b7bb
287c50d
0c93d04
1f68d31
797d413
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,14 +10,61 @@ | |
| from __future__ import annotations | ||
|
|
||
| import logging | ||
| from enum import Enum | ||
|
|
||
|
|
||
| class LoggerLevel(str, Enum): | ||
| """ | ||
| The different possible log levels. | ||
| """ | ||
|
|
||
| WARNING = "warning" | ||
| INFO = "info" | ||
| DEBUG = "debug" | ||
| ERROR = "error" | ||
| CRITICAL = "critical" | ||
|
|
||
| @property | ||
| def level(self) -> int: | ||
| """ | ||
| Get the current state of the logger. | ||
| """ | ||
| if self == LoggerLevel.WARNING: | ||
| return logging.WARNING | ||
| if self == LoggerLevel.INFO: | ||
| return logging.INFO | ||
| if self == LoggerLevel.DEBUG: | ||
| return logging.DEBUG | ||
| if self == LoggerLevel.ERROR: | ||
| return logging.ERROR | ||
| if self == LoggerLevel.CRITICAL: | ||
| return logging.CRITICAL | ||
| return logging.NOTSET | ||
|
|
||
| @classmethod | ||
| def get_logger(cls, level: str | LoggerLevel) -> int: | ||
| """ | ||
| Get the logger level from a string or LoggerLevel. | ||
|
|
||
| :param level: The log level as a string or LoggerLevel. | ||
|
|
||
| :return: The corresponding logging level. | ||
| """ | ||
| if isinstance(level, str): | ||
| level = cls(level.lower()) | ||
| if not isinstance(level, cls): | ||
| raise TypeError(f"Level must be a string or LoggerLevel, got {type(level)}") | ||
| return level.level | ||
|
|
||
|
|
||
| def get_logger( | ||
| name: str | None = None, | ||
| *, | ||
| timestamp: bool = False, | ||
| level_name: bool = True, | ||
| propagate: bool = True, | ||
| add_name: bool = True, | ||
| level: str | LoggerLevel | None = None, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Even wonder if we should not simplify and just expect a
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because it's something we are using everywhere, we can have the luxury to create our loggers from a string in this function. That's for us. |
||
| ) -> logging.Logger: | ||
| """ | ||
| Get a logger with a timestamped stream and specified log level. | ||
|
|
@@ -27,6 +74,7 @@ def get_logger( | |
| :param level_name: Whether to include the log level name in the log format. | ||
| :param propagate: Whether to propagate log messages to the parent logger. | ||
| :param add_name: Whether to include the logger name in the log format. | ||
| :param level: Logging level to use. | ||
|
|
||
| :return: Configured logger instance. | ||
| """ | ||
|
|
@@ -51,6 +99,10 @@ def get_logger( | |
| formatter = logging.Formatter(formatting + "%(message)s") | ||
| stream_handler.setFormatter(formatter) | ||
| log.addHandler(stream_handler) | ||
| log.propagate = propagate | ||
|
|
||
| if level: | ||
| log.setLevel(LoggerLevel.get_logger(level)) | ||
| elif propagate: | ||
| log.propagate = propagate | ||
|
|
||
| return log | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' | ||
| # Copyright (c) 2025 Mira Geoscience Ltd. ' | ||
| # ' | ||
| # This file is part of geoapps-utils package. ' | ||
| # ' | ||
| # geoapps-utils is distributed under the terms and conditions of the MIT License ' | ||
| # (see LICENSE file at the root of this source code package). ' | ||
| # ' | ||
| # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' | ||
| from __future__ import annotations | ||
|
|
||
| import logging | ||
|
|
||
| import pytest | ||
|
|
||
| from geoapps_utils.utils.logger import get_logger | ||
|
|
||
|
|
||
| def test_logger_warning(caplog): | ||
| """ | ||
| Test that the logger is set up correctly. | ||
| """ | ||
| # test with everything | ||
| logger = get_logger( | ||
| "my-app", | ||
| timestamp=True, | ||
| level_name=True, | ||
| propagate=True, # will be set to false because level | ||
| add_name=True, | ||
| level="warning", | ||
| ) | ||
|
|
||
| with caplog.at_level(logging.WARNING): | ||
| logger.warning("Test log message") | ||
|
|
||
| assert "Test log message" in caplog.text | ||
| assert "my-app" in caplog.text | ||
| assert "WARNING" in caplog.text | ||
|
|
||
|
|
||
| def test_logger_info(caplog): | ||
| # test with nothing (expect propagate) | ||
| logger_2 = get_logger( | ||
| timestamp=False, | ||
| level_name=False, | ||
| propagate=True, | ||
| add_name=False, | ||
| ) | ||
|
|
||
| with caplog.at_level(logging.INFO): | ||
| logger_2.info("Test log message") | ||
|
|
||
| assert "Test log message" in caplog.text | ||
| assert caplog.records[0].levelname == "INFO" | ||
| assert caplog.records[0].name == "root" | ||
|
|
||
|
|
||
| def test_logger_no_propagate(caplog): | ||
| # test with propagate false | ||
| logger_3 = get_logger( | ||
| "my-app", timestamp=False, level_name=False, propagate=False, add_name=False | ||
| ) | ||
|
|
||
| with caplog.at_level(logging.INFO): | ||
| logger_3.info("Test log message") | ||
|
|
||
| assert caplog.text == "" | ||
|
|
||
|
|
||
| def test_logger_level_errors(): | ||
| with pytest.raises(TypeError, match="Level must be a string or LoggerLevel"): | ||
| get_logger(level=5) # type: ignore |
Uh oh!
There was an error while loading. Please reload this page.