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

Implement a logging function #643

Merged
merged 3 commits into from
Sep 27, 2023
Merged

Conversation

stcui007
Copy link
Contributor

@stcui007 stcui007 commented Sep 19, 2023

This PR creates an initial logging solution that mimics Python's logging functionality.

Additions

include/utilities/logging_utils.h
This header file contains the following logging functions as described in Issue#574:
void debug(char *)
void info(char *)
void warning(char *)
void error(char *)
void critical(char *)
that handle different types of output.

Also added a unit test code:
test/utils/logging_Test.cpp

Removals

Changes

As an illustration, Bmi_Module_Formulation.hpp is modified with some codes to use logging_utils.h to output various messages

A few CMakelist.txt files related to the logging functionalities and unit test have minor changes.

Testing

Run ngen test
Unit tests

Screenshots

Notes

Todos

Checklist

  • PR has an informative and human-readable title
  • [x ] Changes are limited to a single goal (no scope creep)
  • [x ] Code can be automatically merged (no conflicts)
  • [x ] Code follows project standards (link if applicable)
  • [x ] Passes all existing automated tests
  • [x ] Any change in functionality is tested
  • [x ] New functions are documented (with a description, list of inputs, and expected output)
  • [x ] Placeholder code is flagged / future todos are captured in comments
  • [x ] Project documentation has been updated (including the "Unreleased" section of the CHANGELOG)
  • [x ] Reviewers requested with the Reviewers tool ➡️

Testing checklist (automated report can be put here)

Target Environment support

  • [x ] Linux

@mattw-nws mattw-nws linked an issue Sep 19, 2023 that may be closed by this pull request
include/utilities/logging_utils.h Outdated Show resolved Hide resolved
include/utilities/logging_utils.h Outdated Show resolved Hide resolved
Comment on lines 654 to 657

logging_msg = "case Real: Cannot pass non-numeric lists as a BMI parameter, skipping " + param.first+"\n";
log_msg_ptr = &logging_msg[0];
logging::critical(log_msg_ptr);
Copy link
Contributor

Choose a reason for hiding this comment

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

Several different things here.

  1. With the other change below to the method signature (const char*), all that should be required is this:
logging::critical(("case Real: Cannot pass non-numeric lists as a BMI parameter, skipping " + param.first + "\n").c_str());

So the logging_msg and log_msg_ptr variables can be removed and this simplifies the usage a lot.

  1. This message is in the wrong place, I think you intended to add this example further down on line 688(old)/675(new)--what happens in this code path (for type Real) is expected and shouldn't generate any message.
  2. This would not be a good use of critical, "critical" would usually be used right before an assert, ending the program. The condition down below, where you are "skipping" is probably a warning. Or, if it's that important, we probably shouldn't just skip it and keep going.

//std::cout<<"Skipping parameter: "<<param.first<<std::endl;
std::string logging_msg = "Cannot pass non-numeric lists as a BMI parameter, skipping "+param.first+"\n";
char* log_msg_ptr = &logging_msg[0];
logging::error(log_msg_ptr);
Copy link
Contributor

Choose a reason for hiding this comment

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

As mentioned above, these are probably all warning conditions if the program is going to continue regardless.

@@ -681,13 +688,22 @@ namespace realization {
}
catch (const std::exception &e)
{
std::cout<<"Exception setting parameter value: "<< e.what()<<std::endl;
std::cout<<"Skipping parameter: "<<param.first<<std::endl;
std::cerr<<"Exception setting parameter value: "<< e.what()<<std::endl;
Copy link
Contributor

Choose a reason for hiding this comment

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

Did you mean to leave this in?

continue;
}
value_ptr = get_values_as_type(type, double_vec.begin(), double_vec.end());
break;
default:
std::cout<<"Cannot pass parameter of type "<<geojson::get_propertytype_name(param.second.get_type())<<" as a BMI parameter, skipping "<<param.first<<std::endl;
//std::cout<<"Cannot pass parameter of type "<<geojson::get_propertytype_name(param.second.get_type())<<" as a BMI parameter, skipping "<<param.first<<std::endl;
Copy link
Contributor

Choose a reason for hiding this comment

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

Please go ahead and remove commented old code throughout.

{
#ifndef NGEN_QUIET
std::string msg_str = std::string(msg);
if (msg_str.size() > MAX_STRING_SIZE) {
Copy link
Contributor

Choose a reason for hiding this comment

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

The purpose of MAX_STRING_SIZE is not to prevent clients from giving us messages larger than we want to read. Rather, it is to give a bound to C implementations that may need to allocate specific buffer sizes, and perhaps to specify a point at which reading should be stopped if the string is not properly null-terminated. If this latter is the case, std::string::size is probably not going to work anyway.

For a C++ implementation as we have here, what probably makes the most sense is to ignore it. If we get a string that's not properly terminated, we probably can't know what to do with it anyway. Just pass the input to std::cerr... someone else might disagree, the most we could do is check the C-string length with something like strnlen, but this has the same problem as std::string::size. I would probably just ignore the MAX_STRING_SIZE in this implementation.

This simplifies these functions significantly, allowing you to get rid of multiple variables and copies of the string.

@stcui007
Copy link
Contributor Author

stcui007 commented Sep 19, 2023 via email

}
#endif

#endif //NGEN_LOGGING_UTILS_H
Copy link
Contributor

Choose a reason for hiding this comment

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

Additionally, really any new functionality added should have some unit tests. This is pretty simple so the unit test doesn't have to be huge, but something that puts a message through each function and makes sure it comes out with the expected text would be good. You can look at this approach from one of @program-- 's old commits for an example of how to do that:
https://github.com/program--/ngen/blob/4a1d137bff0ff3324cfb2239ac1eaec72b66705d/test/forcing/CsvPerFeatureForcingProvider_Test.cpp#L202-L216

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agree. this should be done.

mattw-nws

This comment was marked as resolved.

@mattw-nws mattw-nws self-requested a review September 27, 2023 16:10
@mattw-nws mattw-nws dismissed their stale review September 27, 2023 16:11

Team change

@hellkite500 hellkite500 merged commit 72f121a into NOAA-OWP:master Sep 27, 2023
18 of 19 checks passed
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.

Implement a logging solution
3 participants