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

BAI-1246 Python Logging #1284

Merged
merged 6 commits into from
Jun 6, 2024
Merged

BAI-1246 Python Logging #1284

merged 6 commits into from
Jun 6, 2024

Conversation

bw27492
Copy link
Member

@bw27492 bw27492 commented May 30, 2024

No description provided.

@bw27492 bw27492 requested review from GB27247 and a3957273 and removed request for GB27247 May 30, 2024 12:13
Copy link
Member

Choose a reason for hiding this comment

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

Logging should not be configured on a library. But instead should be used by developers wanting to debug code in application bound tasks. To prevent general users getting log messages we can add this line to the top level initialiser. logging.getLogger(__name__).addHandler(logging.NullHandler())

There is some good information on logging with libraries here.

Developers can then use something like this to enable logging:

import logging

logging.basicConfig()
logging.getLogger('bailo').propagate = True

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

@@ -25,9 +29,12 @@ def __init__(
"""
self.verify = verify

logger.debug("Base Agent initiated successfully.")
Copy link
Member

Choose a reason for hiding this comment

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

Normally logging is used for unexpected behaviour and noteworthy events. I think we should use this sparingly and not for stuff such as creating objects.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done - object creation logs removed. Other debug messages changed to info


latest_release = max(releases)
logger.info(f"Latest release ({str(latest_release.version)}) for {self.model_id} retrieved successfully.")

return max(releases)
Copy link
Member

Choose a reason for hiding this comment

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

Could we change this to latest_release?

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

@@ -319,6 +339,14 @@ def from_mlflow(self, tracking_uri: str, experiment_id: str):
if ml_flow:
client = mlflow.tracking.MlflowClient(tracking_uri=tracking_uri)
runs = client.search_runs(experiment_id)
if len(runs) > 0:
Copy link
Member

Choose a reason for hiding this comment

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

We can get rid of >0 It doesn't have any effect on this condition.

Copy link
Member Author

@bw27492 bw27492 Jun 4, 2024

Choose a reason for hiding this comment

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

Done - there was a few instances of this so I've changed them all

Comment on lines 220 to 222
logger.info(
f"Downloading {len(file_names)} of {len(orig_file_names)} files for version {str(self.version)} of {self.model_id}..."
)
Copy link
Member

Choose a reason for hiding this comment

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

We can use f-strings with this although logging has the intended behaviour of formatting additional arguments into the log. We can use something like this. This applies to all the other places this is used.

logger.info(
    f"Downloading %d of %d files for version %s of %s", len(file_names), len(orig_file_names), str(self.version), self.model_id
)

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

except KeyError:
logger.error("Access key not found in BAILO_ACCESS_KEY environment variable. Requires user input.")
Copy link
Member

Choose a reason for hiding this comment

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

Normally logging errors are given when something is unrecoverable within the application. I think info should be used here instead

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

def __request(self, method, *args, **kwargs):
kwargs["verify"] = self.verify

logger.debug(f"{method} to {args[0]}")
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this is needed. Requests provide there own logging that does the same thing but with a bit more detail in terms of sessions and ports.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

name = os.path.split(path)[-1]

if data is None:
if is_zip := os.path.isdir(path):
logger.warning(f"Given path ({path}) is a directory. This will be converted to a zip file for upload.")
warnings.warn(f"Given path ({path}) is a directory. This will be converted to a zip file for upload.")
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this is a warning. Probably should be information as it's expected behaviour.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

Comment on lines 24 to 27
logging.basicConfig()
logger = logging.getLogger(__name__)
logger.addHandler(logging.NullHandler())
logger.propagate = False
Copy link
Member

Choose a reason for hiding this comment

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

basicConfig is redundant as your setting a NullHandler already. Propagate is not needed either. This attribute will just propagate logs to higher loggers. Since this is top level it's redundant. logging.getLogger(__name__).addHandler(logging.NullHandler()) should be sufficient.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

Comment on lines +346 to +348
warnings.warn(
f"MLFlow experiment {experiment_id} does not have any runs and publishing requires at least one valid run. Are you sure the ID is correct?"
)
Copy link
Member

Choose a reason for hiding this comment

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

This should probably be info level as this is an expected behaviour.

Copy link
Member Author

Choose a reason for hiding this comment

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

This is not expected behaviour - MLFlow does not return an error if you request an invalid experiment, instead it will send an empty list. Hence this warning

@bw27492 bw27492 merged commit 8bc70e7 into main Jun 6, 2024
14 checks passed
@bw27492 bw27492 deleted the BAI-1246-python-logging branch June 6, 2024 11:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants