Skip to content
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

Use developer log level, protect logger defaults in test #473

Merged
merged 4 commits into from
Feb 8, 2024

Conversation

al-rigazzi
Copy link
Collaborator

The current log.get_logger() function has two issues.

  1. it uses _get_log_level() to access the value of SMARTSIM_LOG_LEVEL, and uses its return value to define whether the logger name should just be SmartSim, or the user-provided one. The problem is that the user-provided one is used only when _get_log_level() returns developer, but that is never the case, as developer gets translated to debug.
  2. As a consequence of 1, calling get_logger(name="MY_LOGGER", log_level="INFO") will always get the logger named SmartSim and set its level to info. When this is done in a test, then the log level will be set for all subsequent tests, no matter what the name is set to.

I proposed to replace the _get_log_level() with _translate_log_level() and use the return value to set the log level when log level is not set to developer. To be honest, I think it is kind of weird that users can provide a name for the logger and that it gets thrown away 99.9% of the times, but I guess they could also use a different logger if they wanted something more flexible, and with the changes of this PR, the API is consistent with the docs.

Copy link

codecov bot commented Feb 2, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (106d70f) 90.43% compared to head (a4c0737) 90.83%.
Report is 3 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop     #473      +/-   ##
===========================================
+ Coverage    90.43%   90.83%   +0.39%     
===========================================
  Files           60       60              
  Lines         3837     3818      -19     
===========================================
- Hits          3470     3468       -2     
+ Misses         367      350      -17     
Files Coverage Δ
smartsim/log.py 96.26% <100.00%> (+2.62%) ⬆️

... and 6 files with indirect coverage changes

@al-rigazzi al-rigazzi changed the title Use developer setting, protect logger defaults in test Use developer log level, protect logger defaults in test Feb 2, 2024
Copy link
Member

@MattToast MattToast left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great catch! I have a couple of small nits for you, but otherwise LGTM!!

smartsim/log.py Outdated
@@ -63,7 +63,7 @@
_PR = ParamSpec("_PR")


def _get_log_level() -> str:
def _translate_log_level(user_log_level: t.Optional[str] = "info") -> str:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor typing nit: t.Optional[str] implies that

_translate_log_level(user_log_level=None)

is a valid call. Did you mean

Suggested change
def _translate_log_level(user_log_level: t.Optional[str] = "info") -> str:
def _translate_log_level(user_log_level: str = "info") -> str:

?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You know, I don't know. I think it's better as you say, as it is an internal function we should only call one way.

smartsim/log.py Outdated
@@ -205,7 +204,7 @@ def get_logger(
"""
# if name is None, then logger is the root logger
# if not root logger, get the name of file without prefix.
user_log_level = _get_log_level()
user_log_level = os.environ.get("SMARTSIM_LOG_LEVEL", "info")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding

Suggested change
user_log_level = os.environ.get("SMARTSIM_LOG_LEVEL", "info")
user_log_level = os.environ.get("SMARTSIM_LOG_LEVEL", "info").lower()

otherwise

export SMARTSIM_LOG_LEVEL=QUIET

will default to "info" which would technically be an API break

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, totally right

@@ -77,15 +77,14 @@ def _get_log_level() -> str:
:returns: Log level for coloredlogs
:rtype: str
"""
log_level = os.environ.get("SMARTSIM_LOG_LEVEL", "info").lower()
if log_level == "quiet":
if user_log_level == "quiet":
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we shorten this to:

if user_log_level in ['quiet', 'info', 'debug','warning']:
    return user_log_level

if user_log_level == "developer":
    return "info"

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you missed one case, but I got the point and modified implementation accordingly.

smartsim/log.py Outdated
@@ -205,7 +204,7 @@ def get_logger(
"""
# if name is None, then logger is the root logger
# if not root logger, get the name of file without prefix.
user_log_level = _get_log_level()
user_log_level = os.environ.get("SMARTSIM_LOG_LEVEL", "info")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder what you & @MattToast think about trying to move all os.environ['xyz'] calls into the smartsim._core.config.Config

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was already there...

"""Ensure that experiment loggers are added when context info exists"""
monkeypatch.setenv("SMARTSIM_LOG_LEVEL", "developer")
test_dir = pathlib.Path(test_dir)
test_dir.mkdir(parents=True, exist_ok=True)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding direct unit test of new method:

@pytest.mark.parametrize(
        "input_level,exp_level",
        [
            pytest.param("INFO", "info", id="lowercasing only, INFO"),
            pytest.param("info", "info", id="input back, info"),
            pytest.param("WARNING", "warning", id="lowercasing only, WARNING"),
            pytest.param("warning", "warning", id="input back, warning"),
            pytest.param("QUIET", "warning", id="lowercasing only, QUIET"),
            pytest.param("quiet", "warning", id="translation back, quiet"),
            pytest.param("DEVELOPER", "debug", id="lowercasing only, DEVELOPER"),
            pytest.param("developer", "debug", id="translation back, developer"),
        ]
)
def test_translate_log_level(input_level: str, exp_level: str, turn_on_tm):
    """Ensure the correct logger type is instantiated"""
    translated_level = smartsim.log._translate_log_level(input_level)
    assert exp_level == translated_level

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think I need turn_on_tm, do I? @ankona

@al-rigazzi al-rigazzi requested a review from MattToast February 6, 2024 18:34
Copy link
Member

@MattToast MattToast left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, pending tests!!

@al-rigazzi al-rigazzi added bug: minor A minor bug short task Issues that can be completed and reviewed quickly type: bug General bug tag before severity classification labels Feb 8, 2024
@al-rigazzi al-rigazzi merged commit 8408368 into CrayLabs:develop Feb 8, 2024
34 checks passed
@al-rigazzi al-rigazzi deleted the logger_enhancements branch February 8, 2024 08:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug: minor A minor bug short task Issues that can be completed and reviewed quickly type: bug General bug tag before severity classification
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants