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

Replace LogEntry struct with LogMessage protobuf (#568) #697

Merged
merged 1 commit into from
Mar 13, 2020

Conversation

rbehjati
Copy link
Contributor

  • Struct LogEntry in sdk/rust/oak/src/logger/mod.rs is removed
  • New file oak/proto/logger.proto containing LogMessage is added
  • OakChannelLogger is updated to send LogMessage instead of string
  • LoggingNode is updated to handle LogMessage instances

Fixes #568

Checklist

  • Pull request affects core Oak functionality (e.g. runtime, SDK, ABI)
    • I have written tests that cover the code changes.
    • I have checked that these tests are run by Cloudbuild
    • I have updated documentation accordingly.
    • I have raised an issue to
      cover any TODOs and/or unfinished work.
  • Pull request includes prototype/experimental work that is under
    construction.

Copy link
Collaborator

@tiziano88 tiziano88 left a comment

Choose a reason for hiding this comment

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

Thanks, looking good!


// Logging levels as defined in https://docs.rs/log/0.4.10/log/enum.Level.html.
enum Level {
ERROR = 0;
Copy link
Collaborator

Choose a reason for hiding this comment

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

It is good practice to have a default unknown value for enums, so that if a sender forgets to set it, or sets it to a value that the receiver does not recognize, it can be detected. See https://engdoc.corp.google.com/eng/doc/devguide/proto/index.md?cl=head#do-include-an-unknown-value-in-an-enum

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added UNKNOWN_LEVEL as the default value.

INFO = 2;
DEBUG = 3;
TRACE = 4;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Missing newline.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed!


syntax = "proto3";

package oak.logging;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would rename this to oak.log and also the file name to log.proto.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done!

@@ -32,6 +32,7 @@ class LoggingNode final : public NodeThread {
explicit LoggingNode(BaseRuntime* runtime, const std::string& name) : NodeThread(runtime, name) {}

private:
static const std::string log_levels[5];
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not sure why this needs to be a member of this class, as opposed to just a constant in an unnamed namespace?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed. Found that protobuf compiler generates a function that returns the enum name corresponding to a numeric value.

Comment on lines 43 to 44
cached_size: ::std::default::Default::default(),
unknown_fields: ::std::default::Default::default(),
Copy link
Collaborator

Choose a reason for hiding this comment

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

You should use the ..Default::default() idiom to ensure that all fields are filled in, see elsewhere.

fn main() {
oak_utils::run_protoc_rust_grpc(protoc_rust_grpc::Args {
out_dir: "src/proto",
input: &["../../proto/hello_world.proto"],
includes: &["../../proto", "../../../../third_party"],
rust_protobuf: true, // also generate protobuf messages, not just services
..Default::default()
})

Copy link
Contributor Author

@rbehjati rbehjati Mar 13, 2020

Choose a reason for hiding this comment

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

Nice idiom. Thanks. Fixed :)

record.args()
),
let log_msg = crate::proto::logger::LogMessage {
file: record.file().unwrap_or_default().to_string(),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Perhaps make this more explicit, e.g. unwrap_or("<unknown>") or similar.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed it to file: record.file().unwrap_or("<unknown-file>").to_string(),.
The next line also calls unwrap_or_default(), but on an int value. Do we need an explicit default value there too?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I guess that's enough, obviously it will show up as 0 in the output, but I guess that's fine for now.


namespace oak {

const std::string LoggingNode::log_levels[5] = {"ERROR", "WARN", "INFO", "DEBUG", "TRACE"};
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there any way of getting this string representation out of an actual enum value?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. Fixed using Level_Name function.

@@ -47,8 +50,12 @@ void LoggingNode::Run(Handle handle) {
if (result.msg == nullptr) {
break;
}
oak::logging::LogMessage log_msg;
std::string msg_str(result.msg->data.begin(), result.msg->data.end());
Copy link
Collaborator

Choose a reason for hiding this comment

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

It's slightly annoying to have to make this extra copy, is there any way to parse the protobuf message directly from the bytes field? Failing that, perhaps creating a string_view would at least avoid the copy, even though it would still require an explicit conversion here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I could not make it work with string_view. Apparently the compiler does not recognize it!
This is the code I used:

      oak::log::LogMessage log_msg;
      std::string_view str(result.msg->data.data(), result.msg->data.size());
      log_msg.ParseFromString(str.data());

And the error message is: no member named 'string_view' in namespace 'std'.

I also tried to parse the protobuf directly: log_msg.ParseFromString(result.msg->data.data());, but it results in memory corruption, when running the examples with -s asan. We need a null-terminated string here, and for that we have to make a copy. Can you think of a work around?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think string_view is in absl, not in std yet (but i have not checked).

Anyways, it seems maybe https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.message_lite#MessageLite.ParseFromArray would do the trick here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed using ParseFromArray. Thanks for suggesting it @tiziano88.

@rbehjati rbehjati force-pushed the feature/oak-568 branch 2 times, most recently from 74bd183 to f451143 Compare March 13, 2020 15:48
@rbehjati rbehjati requested a review from tiziano88 March 13, 2020 16:25
Copy link
Collaborator

@tiziano88 tiziano88 left a comment

Choose a reason for hiding this comment

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

Let me know when I should take another look, thanks!

@@ -47,8 +48,11 @@ void LoggingNode::Run(Handle handle) {
if (result.msg == nullptr) {
break;
}
oak::log::LogMessage log_msg;
log_msg.ParseFromArray(result.msg->data.data(), result.msg->data.size());
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this parsing may fail, what happens if so? Does this return a status / error code?


package oak.log;

message LogMessage {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could you add a comment explaining what this is used for?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done!


package oak.log;

message LogMessage {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done!

LOG(INFO) << "{" << name_ << "} "
<< "LOG: " << oak::log::Level_Name(log_msg.level()) << " " << log_msg.file()
<< ":" << log_msg.line() << ": " << log_msg.message();
} else {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think this parsing may fail, what happens if so? Does this return a status / error code?

Error message if the parse fails.

oak/proto/log.proto Outdated Show resolved Hide resolved
oak/server/logging_node.cc Outdated Show resolved Hide resolved
@googlebot
Copy link

We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors. If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google.
In order to pass this check, please resolve this problem and then comment @googlebot I fixed it.. If the bot doesn't comment, it means it doesn't think anything has changed.

ℹ️ Googlers: Go here for more info.

1 similar comment
@googlebot
Copy link

We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors. If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google.
In order to pass this check, please resolve this problem and then comment @googlebot I fixed it.. If the bot doesn't comment, it means it doesn't think anything has changed.

ℹ️ Googlers: Go here for more info.

* LogEntry in sdk/rust/oak/src/logger/mod.rs is removed
* oak/proto/logger.proto containing LogMessage is added
* OakChannelLogger is updated to send LogMessage instead of string
* LoggingNode is updated to handle LogMessage instances
@googlebot
Copy link

CLAs look good, thanks!

ℹ️ Googlers: Go here for more info.

@rbehjati rbehjati merged commit 54a31e7 into project-oak:master Mar 13, 2020
@@ -47,8 +48,16 @@ void LoggingNode::Run(Handle handle) {
if (result.msg == nullptr) {
break;
}
LOG(INFO) << "{" << name_ << "} "
Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, there are actually two runtime implementations of the logging pseudo-Node – you also need to update oak/server/rust/oak_runtime/src/node/logger.rs to cope with proto-encoded logging messages.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh! Thanks for letting me know. I'll fix it :)

@rbehjati rbehjati deleted the feature/oak-568 branch March 16, 2020 15:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Replace LogEntry Rust struct with a protobuf object
4 participants