-
Notifications
You must be signed in to change notification settings - Fork 80
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
Add logging final version #893
Add logging final version #893
Conversation
MLCommons CLA bot All contributors have signed the MLCommons CLA ✍️ ✅ |
add logging testing
add logging test in test_full
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would recommend adding a Logging
section in the documentation for extending GaNDLF detailing this process and how a developer needs to use this correctly. For example, there should be 2 sub-sections to this:
- What does someone need to do when they are extending an existing function or class?
- What does someone need to do when they are adding a new function or class?
- Anything else?
Am I missing something @VukW?
@sarthakpati I agree it would be nice to mention logging in extension guide. However, the whole PR is created in the way that we hide all configuration from the developer - so developer almost doesn't need to bother about it. So, I believe there is not a big need to describe how to create loggers in new or modified code, but instead it would be useful to describe how logging is configured right now and how to log stuff sustainably
|
Sounds good, @VukW! Thank you for the explanation. 😄 |
Hi guys @VukW, @sarthakpati, |
Co-authored-by: Sarthak Pati <[email protected]>
@sarthakpati @VukW |
GANDLF/utils/gandlf_logger.py
Outdated
output_dir = Path(log_dir) | ||
Path(output_dir).mkdir(parents=True, exist_ok=True) | ||
with resources.open_text("GANDLF", config_path) as file: | ||
config_dict = yaml.safe_load(file) | ||
config_dict["handlers"]["rotatingFileHandler"]["filename"] = str( | ||
Path.joinpath(output_dir, "gandlf.log") | ||
) | ||
logging.config.dictConfig(config_dict) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here, I will suggest the following (pseudo-code):
try:
write a single line to the `log_file` (something like `"Starting GaNDLF logging session"`).
except:
# this means that the user does not have write access to the location given by `log_file`, so give that error, and tell the user that we are falling back to the default of flushing output to console
call logging setup again but with `log_file` as `None`
Co-authored-by: Sarthak Pati <[email protected]>
Co-authored-by: Sarthak Pati <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor comments, and we should be ready to merge! Thanks a ton for this, @benmalef!
GANDLF/utils/gandlf_logger.py
Outdated
try: | ||
if log_file is None: # create tmp file | ||
log_tmp_file = _create_tmp_log_file() | ||
_save_logs_in_file(log_tmp_file, config_path) | ||
logging.info(f"The logs are saved in {log_tmp_file}") | ||
else: # create the log file | ||
_create_log_file(log_file) | ||
_save_logs_in_file(log_file, config_path) | ||
except Exception as e: | ||
_flush_to_console() | ||
logging.error(f"log_file:{e}") | ||
logging.warning("The logs will be flushed to console") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest the following execution order for clarity (also, try
is no longer needed since the temp file should always have user-level write access):
try: | |
if log_file is None: # create tmp file | |
log_tmp_file = _create_tmp_log_file() | |
_save_logs_in_file(log_tmp_file, config_path) | |
logging.info(f"The logs are saved in {log_tmp_file}") | |
else: # create the log file | |
_create_log_file(log_file) | |
_save_logs_in_file(log_file, config_path) | |
except Exception as e: | |
_flush_to_console() | |
logging.error(f"log_file:{e}") | |
logging.warning("The logs will be flushed to console") | |
log_tmp_file = log_file | |
if log_file is None: # create tmp file | |
log_tmp_file = _create_tmp_log_file() | |
logging.info(f"The logs are saved in {log_tmp_file}") | |
_create_log_file(log_tmp_file) | |
_save_logs_in_file(log_tmp_file, config_path) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this code is cleaner. Thanks for the refactor.!
GANDLF/utils/gandlf_logger.py
Outdated
def _flush_to_console(): | ||
formatter = colorlog.ColoredFormatter( | ||
"%(log_color)s%(asctime)s - %(levelname)s - %(message)s", | ||
datefmt="%Y-%m-%d %H:%M:%S", | ||
log_colors={ | ||
"DEBUG": "blue", | ||
"INFO": "green", | ||
"WARNING": "yellow", | ||
"ERROR": "red", | ||
"CRITICAL": "bold_red", | ||
}, | ||
) | ||
console_handler = logging.StreamHandler() | ||
console_handler.setFormatter(formatter) | ||
logging.root.setLevel(logging.DEBUG) | ||
logging.root.addHandler(console_handler) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the try
block is removed from the module below, then this function is no longer needed, right?
def _flush_to_console(): | |
formatter = colorlog.ColoredFormatter( | |
"%(log_color)s%(asctime)s - %(levelname)s - %(message)s", | |
datefmt="%Y-%m-%d %H:%M:%S", | |
log_colors={ | |
"DEBUG": "blue", | |
"INFO": "green", | |
"WARNING": "yellow", | |
"ERROR": "red", | |
"CRITICAL": "bold_red", | |
}, | |
) | |
console_handler = logging.StreamHandler() | |
console_handler.setFormatter(formatter) | |
logging.root.setLevel(logging.DEBUG) | |
logging.root.addHandler(console_handler) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes if we don't want to flush to the console, the function is no longer needed.
Co-authored-by: Sarthak Pati <[email protected]>
@sarthakpati I made the proposed changes...!! Thanks a lot for the suggestions.!! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor semantic change. This PR should be good to merge after this.
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## new-apis_v0.1.0-dev #893 +/- ##
=======================================================
+ Coverage 94.41% 94.46% +0.04%
=======================================================
Files 159 160 +1
Lines 9387 9482 +95
=======================================================
+ Hits 8863 8957 +94
- Misses 524 525 +1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
GANDLF/entrypoints/cli_tool.py
Outdated
@@ -24,7 +24,8 @@ def gandlf(ctx, loglevel): | |||
"""GANDLF command-line tool.""" | |||
ctx.ensure_object(dict) | |||
ctx.obj["LOGLEVEL"] = loglevel | |||
setup_logging(loglevel) | |||
# setup_logging(loglevel) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's remove redundant old loglevel stuff here
tmp_dir = Path(tempfile.gettempdir()) | ||
log_dir = Path.joinpath(tmp_dir, ".gandlf") | ||
log_dir.mkdir(parents=True, exist_ok=True) | ||
log_file = Path.joinpath(log_dir, get_unique_timestamp() + ".log") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
GANDLF/utils/gandlf_logging.py
Outdated
log_file.write_text("Starting GaNDLF logging session \n") | ||
|
||
|
||
def _save_logs_in_file(log_file, config_path): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just a nitpick - this function is not saving any logs, instead just configures logging. Maybe rename it to smth more relevant? For ex,
def _save_logs_in_file(log_file, config_path): | |
def _configure_logging_with_logfile(log_file, config_path): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checked the overall code, no any significant issues, looks good to me! Thanks, man @benmalef
The recent changes are good for me to merge. @VukW, if you are okay as well, let's merge this in and start the process of migrating the current master to an |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sarthakpati Agree, looks good to me, let's merge it (just to remind, I believe @benmalef cannot merge it till your previous PR review result Request Changes
is active)
Fixes #755
Brief Description
This PR fixes the issues from this PR
I have tried to implement this ref
I have NOT implemented the tqdm ref. I will create a separate PR.
Screenshots
This screenshot shows how logging messages are in the file.
Proposed Changes
Checklist
CONTRIBUTING
guide has been followed.typing
is used to provide type hints, including and not limited to usingOptional
if a variable has a pre-defined value).pip install
step is needed for PR to be functional), please ensure it is reflected in all the files that control the CI, namely: python-test.yml, and all docker files [1,2,3].