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

Logging #127

Merged
merged 13 commits into from
Sep 19, 2024
Merged

Logging #127

merged 13 commits into from
Sep 19, 2024

Conversation

TeaganKing
Copy link
Collaborator

@TeaganKing TeaganKing commented Aug 29, 2024

This PR should address #82 by adding logging capabilities to CUPiD instead of using print statements. This should accomplish the following three tasks:

It is useful to implement logging instead of using print statements because log files can be retrieved in the future (whereas print statements are not saved) and this reduces the amount of printing to the console that can get overwhelming for users.

All Submissions:

  • Have you followed the guidelines in our Contributor's Guide (including the pre-commit check)?
  • Have you checked to ensure there aren't other open Pull Requests for the same update/change?

New Feature Submissions:

  1. Have you lint your code locally prior to submission?

Changes to Core Features:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you successfully tested your changes locally?

@TeaganKing TeaganKing self-assigned this Aug 29, 2024
@TeaganKing TeaganKing linked an issue Aug 29, 2024 that may be closed by this pull request
@TeaganKing
Copy link
Collaborator Author

This page provides some examples of basic pipelines that can be used to set up logging for ploomber; however, this calls dag in a slightly different manner and will require a bit more looking into.

@TeaganKing
Copy link
Collaborator Author

TeaganKing commented Sep 4, 2024

Given that within the CESM workflow, log files such as cupid.o#### and cupid.e#### where #### is a timestamp will be automatically generated, we can remove the filename from the logger instantiation.

  • It would be useful to set up logging levels in the configuration file so that users can choose what amount of output they want printed to the console.

@TeaganKing
Copy link
Collaborator Author

I'd like to test this a bit more thoroughly to make sure it didn't break cupid-run or timeseries generation. Thus, the testing might be on hold until HPC systems are back up, but this should be ready for testing/review next week.

@TeaganKing
Copy link
Collaborator Author

The timeseries generation and cupid-run seem to work as expected, so this is ready for review.

Copy link
Collaborator

@mnlevy1981 mnlevy1981 left a comment

Choose a reason for hiding this comment

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

This looks great! There are a couple of in-line comments, plus I wanted to note that I grepped for print (only in the cupid/ subdirectory) and found two more occurrences that we may want to address:

$ cd cupid
$ git grep -n print
timeseries.py:87:        print(f"\n  No time series files requested for {component}...")
util.py:55:        print(f"ERROR: {config_path} not found")

cupid/util.py Outdated
Comment on lines 104 to 126
log_level = control["computation_config"].get("log_level", None)
if log_level:
if log_level == "debug":
logging.basicConfig(
level=logging.DEBUG,
)
if log_level == "info":
logging.basicConfig(
level=logging.INFO,
)
if log_level == "warning":
logging.basicConfig(
level=logging.WARNING,
)
if log_level == "error":
logging.basicConfig(
level=logging.ERROR,
)
else:
# default level is info if log level is not set in config
logging.basicConfig(
level=logging.INFO,
)
Copy link
Collaborator

Choose a reason for hiding this comment

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

If you change line 104 to

log_level = control["computation_config"].get("log_level", "info")

Then you don't need the if statement at 105 or the entire else block from 122 - 126 (maybe move the # default level is info if log level is not set in config comment to above setting log_level?)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Thinking about this more, should we use

        if log_level == "debug":
            logging.basicConfig(
                level=logging.DEBUG,
            )
        elif log_level == "info":
            logging.basicConfig(
                level=logging.INFO,
            )
        elif log_level == "warning":
            logging.basicConfig(
                level=logging.WARNING,
            )
        elif log_level == "error":
            logging.basicConfig(
                level=logging.ERROR,
            )
        else:

and trap the case when log_level is not one of the four expected strings?



def derive_cam_variables(vars_to_derive=None, ts_dir=None, overwrite=None):
def derive_cam_variables(vars_to_derive=None, ts_dir=None, overwrite=None, logger=None):
Copy link
Collaborator

Choose a reason for hiding this comment

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

This function is called from create_time_series(), which uses logger prior to calling in... so I think we want logger to be a required argument. This will let us remove

if logger is None:
    logger = cupid.util.setup_logging("config.yml")

at lines 370-372 (and I think also the import cupid.util at lines 17 & 18)

@TeaganKing
Copy link
Collaborator Author

Thanks for this review, @mnlevy1981 !

I addressed those comments, except for the one print statement in cupid/util.py-- the get_control_dict function is needed prior to logging implementation (because logging uses info from the config file). Thus, I think this one would have circular implementation if both functions call one another.

@TeaganKing TeaganKing marked this pull request as ready for review September 19, 2024 16:35
cupid/util.py Outdated
Comment on lines 107 to 123
if log_level == "debug":
logging.basicConfig(
level=logging.DEBUG,
)
if log_level == "info":
logging.basicConfig(
level=logging.INFO,
)
if log_level == "warning":
logging.basicConfig(
level=logging.WARNING,
)
if log_level == "error":
logging.basicConfig(
level=logging.ERROR,
)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Did you see my follow-up comment about this (#127 (comment))? What happens if someone puts log_level: all_messages (or even just log_level: DEBUG) in config.yml? none of these if statements will evaluate to true, so we won't call logging.basicConfig() at all... I think we want to catch that and raise an exception.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Oh! I think I marked it as resolved and then the response was hidden. Sorry about that.

I added an 'else' statement back in and also included the all-caps versions of the log levels.

Copy link
Collaborator

@mnlevy1981 mnlevy1981 left a comment

Choose a reason for hiding this comment

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

This looks great, thanks!

@TeaganKing TeaganKing merged commit ac54079 into NCAR:main Sep 19, 2024
1 check passed
@TeaganKing TeaganKing changed the title [WIP] Logging Logging Sep 19, 2024
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.

Add logging capabilitites
2 participants