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

Swell logger extends logging.Logger #450

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from

Conversation

mranst
Copy link
Contributor

@mranst mranst commented Oct 28, 2024

Description

#428 – This PR implements the swell logger as an extension of the logging library. This means that Swell loggers are now handled in a similar way to the base library.

The Logger class in the logging library is invoked through the getLogger method, rather than directly. This method goes through a manager class, which handles initialized logger objects. This PR introduces the get_logger method, which overrides the base logging.Manager object so it uses the swell Logger. Functions from Logger such as info() override the base functions, so the behavior doesn't change. Invoking Logger directly will still work, but if accepted, logger instances should ideally be invoked using get_logger in the future.

Copy link
Collaborator

@ashiklom ashiklom left a comment

Choose a reason for hiding this comment

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

Nice work!

Though, now that you've gone through and replaced Logger(...) with get_logger(...) throughout (which I approve!), I think we might as well consider deprecating our custom Logger class altogether and just teaching get_logger to create logging.Logger objects with the semantics we expect.


def __init__(self, task_name: str) -> None:
super().__init__(task_name)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Strictly speaking, if you are doing inheritance, you should obey the Liskov Substitution Principle; i.e., if a swell.Logger object is a subclass of logging.Logger, then you should be able to use a swell.Logger anywhere where you can use logging.Logger object.

In practice, the specific complaint here is that the __init__ methods for logging.Logger and swell.logging.Logger have incompatible argument signatures. Something like this, swell.logging.Logger(name="this", level="DEBUG"), will throw an error, but under a strict inheritance hierarchy, this should work.

A simple fix is to (1) change task_name to just name (for consistency with logging.Logger and (2) accept **kwargs as an optional argument that gets passed on via super().__init__(name, **kwargs).

src/swell/utilities/logger.py Show resolved Hide resolved
src/swell/utilities/logger.py Outdated Show resolved Hide resolved
@mranst
Copy link
Contributor Author

mranst commented Oct 29, 2024

Nice work!

Though, now that you've gone through and replaced Logger(...) with get_logger(...) throughout (which I approve!), I think we might as well consider deprecating our custom Logger class altogether and just teaching get_logger to create logging.Logger objects with the semantics we expect.

I think this makes a lot of sense, pretty much everything should be able to go through logging internals. The one exception might be the abort function, which seems very convenient and doesn't seem to have an obvious alternative in logging (though I'm still looking into it). At the very least, I think I can accomplish the same thing with a much simpler extension of Logger than I currently have.

@mranst
Copy link
Contributor Author

mranst commented Nov 14, 2024

I tried to implement some more elegant solutions to this problem, but ended up sort of going in a circle. Logging actually doesn't seem to have very complex formatting for message levels. The implementation now at least makes better use of inheritence for the logging levels.

The customization for detail is simpler now. Setting the LOGLEVEL environment variable will control the minimum priority logging level, and by default it will include messages at INFO or above. This is in line with how logging usually works.

@mranst mranst requested a review from ashiklom November 14, 2024 14:10
@Dooruk Dooruk removed the request for review from asewnath January 23, 2025 21:27
@Dooruk
Copy link
Collaborator

Dooruk commented Feb 10, 2025

Is this still active and pending for a review? Figure it might have been forgotten in other numerous PRs 😃

@mranst
Copy link
Contributor Author

mranst commented Feb 10, 2025

Is this still active and pending for a review? Figure it might have been forgotten in other numerous PRs 😃

Yeah, I had sort of forgotten about it too. I think I had it where I wanted it on the latest commit

@@ -25,5 +25,9 @@ def test_wrong_hash(self) -> None:
abort_message = "Wrong commit hashes found for these repositories in jedi_bundle: [oops]"
# Run check hash (expect abort)
with self.assertRaises(SystemExit) as abort, suppress_stdout():
# Suppress logging output for test
log_level = logger.level
logger.setLevel(60)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Magic number. Can you add a comment to what 60 means here?

Copy link
Collaborator

@ashiklom ashiklom left a comment

Choose a reason for hiding this comment

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

Pending one tiny fix (add a comment about what loglevel(60) means), and assuming this passes all our tests, we can get this merged.

Eventually, I still would like us to remove our own logging.Logger class in favor of using Python's builtin logger only where appropriate (for logging; not for error handling or taking user input) and using more appropriate tools for managing other things. But for now, let's get this in and tackle the rest of the problem later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants