Skip to content

Commit

Permalink
Replace LogEntry struct with LogMessage protobuf (project-oak#568)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
rbehjati committed Mar 13, 2020
1 parent 0bb76ad commit 6c38706
Show file tree
Hide file tree
Showing 8 changed files with 488 additions and 31 deletions.
11 changes: 11 additions & 0 deletions oak/proto/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,17 @@ cc_proto_library(
deps = [":policy_proto"],
)

proto_library(
name = "log_proto",
srcs = ["log.proto"],
deps = [],
)

cc_proto_library(
name = "log_cc_proto",
deps = [":log_proto"],
)

proto_library(
name = "storage_channel_proto",
srcs = ["storage_channel.proto"],
Expand Down
47 changes: 47 additions & 0 deletions oak/proto/log.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// Copyright 2019 The Project Oak Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

syntax = "proto3";

package oak.log;

// This message defines the data that is passed as a log message to a logging pseudo-node. It
// provides a "schema" to keep the logging pseudo-node in sync with the internal representation of
// log messages in Oak sdk.
message LogMessage {
// The source file containing the message.
string file = 1;

// The line containing the message.
uint32 line = 2;

// The verbosity level of the message.
Level level = 3;

// The message body.
string message = 4;
}

// Logging levels as defined in https://docs.rs/log/0.4.10/log/enum.Level.html.
// UNKNOWN_LEVEL is added as the default value.
enum Level {
UNKNOWN_LEVEL = 0;
ERROR = 1;
WARN = 2;
INFO = 3;
DEBUG = 4;
TRACE = 5;
}
1 change: 1 addition & 0 deletions oak/server/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ cc_library(
":channel",
":node_thread",
"//oak/common:handles",
"//oak/proto:log_cc_proto",
"@com_google_absl//absl/memory",
"@com_google_asylo//asylo/util:logging",
],
Expand Down
13 changes: 11 additions & 2 deletions oak/server/logging_node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "absl/memory/memory.h"
#include "asylo/util/logging.h"
#include "oak/proto/log.pb.h"

namespace oak {

Expand Down Expand Up @@ -47,8 +48,16 @@ void LoggingNode::Run(Handle handle) {
if (result.msg == nullptr) {
break;
}
LOG(INFO) << "{" << name_ << "} "
<< "LOG: " << std::string(result.msg->data.data(), result.msg->data.size());
oak::log::LogMessage log_msg;
bool successful_parse =
log_msg.ParseFromArray(result.msg->data.data(), result.msg->data.size());
if (successful_parse) {
LOG(INFO) << "{" << name_ << "} "
<< "LOG: " << oak::log::Level_Name(log_msg.level()) << " " << log_msg.file()
<< ":" << log_msg.line() << ": " << log_msg.message();
} else {
LOG(ERROR) << "{" << name_ << "} Could not parse protobuf message.";
}
// Any channel references included with the message will be dropped.
}
}
Expand Down
1 change: 1 addition & 0 deletions sdk/rust/oak/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ fn main() {
"../../../oak/proto/policy.proto",
"../../../oak/proto/storage.proto",
"../../../oak/proto/storage_channel.proto",
"../../../oak/proto/log.proto",
],
includes: &["../../.."],
customize: protoc_rust::Customize::default(),
Expand Down
47 changes: 18 additions & 29 deletions sdk/rust/oak/src/logger/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,7 @@
use log::{Level, Log, Metadata, Record, SetLoggerError};

struct OakChannelLogger {
channel: crate::io::Sender<LogEntry>,
}

/// An object representing a log entry. Currently just a wrapper around a string, but it may be
/// extended in the future with additional fields, e.g. level or file / line information, though
/// that would probably require defining a cross-language schema such as protobuf or FIDL for it,
/// rather than just a Rust struct.
struct LogEntry {
message: String,
}

/// Trivial implementation of [`oak::io::Encodable`], just converting the log entry message to bytes
/// and no handles.
impl crate::io::Encodable for LogEntry {
fn encode(&self) -> Result<crate::io::Message, crate::OakError> {
let bytes = self.message.as_bytes().into();
let handles = vec![];
Ok(crate::io::Message { bytes, handles })
}
channel: crate::io::Sender<crate::proto::log::LogMessage>,
}

impl Log for OakChannelLogger {
Expand All @@ -53,17 +35,14 @@ impl Log for OakChannelLogger {
if !self.enabled(record.metadata()) {
return;
}
let log_entry = LogEntry {
// We add a newline to the message to force flushing when printed by the host.
message: format!(
"{} {} : {} : {}\n",
record.level(),
record.file().unwrap_or_default(),
record.line().unwrap_or_default(),
record.args()
),
let log_msg = crate::proto::log::LogMessage {
file: record.file().unwrap_or("<unknown-file>").to_string(),
line: record.line().unwrap_or_default(),
level: map_level(record.level()),
message: format!("{}", record.args()),
..Default::default()
};
match self.channel.send(&log_entry) {
match self.channel.send(&log_msg) {
Ok(()) => (),
Err(crate::OakError::OakStatus(crate::OakStatus::ErrTerminated)) => (),
Err(e) => panic!("could not send log message over log channel: {}", e),
Expand All @@ -72,6 +51,16 @@ impl Log for OakChannelLogger {
fn flush(&self) {}
}

fn map_level(level: Level) -> crate::proto::log::Level {
match level {
Level::Error => crate::proto::log::Level::ERROR,
Level::Warn => crate::proto::log::Level::WARN,
Level::Info => crate::proto::log::Level::INFO,
Level::Debug => crate::proto::log::Level::DEBUG,
Level::Trace => crate::proto::log::Level::TRACE,
}
}

/// Default name for predefined node configuration that corresponds to a logging
/// pseudo-Node.
pub const DEFAULT_CONFIG_NAME: &str = "log";
Expand Down
Loading

0 comments on commit 6c38706

Please sign in to comment.