Skip to content

Commit

Permalink
Merge pull request #1134 from scrtlabs/stderr-logs-cosmwasmv1
Browse files Browse the repository at this point in the history
Stderr logs cosmwasmv1
  • Loading branch information
liorbond authored Sep 7, 2022
2 parents 93495f4 + fb635a4 commit 33d39c0
Show file tree
Hide file tree
Showing 13 changed files with 97 additions and 277 deletions.
16 changes: 8 additions & 8 deletions cosmwasm/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions cosmwasm/enclaves/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion cosmwasm/enclaves/execute/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ itertools = { version = "0.8", default-features = false, features = [] }
bit-vec = { version = "0.6", default-features = false }
lazy_static = "1.4"
hex = "0.4.2"
log = "0.4.8"
log = "0.4.17"
simple_logger = { version = "2.3.0", default-features = false, features = ["stderr"] }

[dependencies.webpki]
git = "https://github.com/mesalock-linux/webpki"
Expand Down
137 changes: 5 additions & 132 deletions cosmwasm/enclaves/execute/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,151 +6,24 @@ extern crate sgx_tstd as std;

extern crate sgx_types;

use std::env;

#[allow(unused_imports)]
use ctor::*;
use log::LevelFilter;
use enclave_utils::logger::get_log_level;

// Force linking to all the ecalls/ocalls in this package
pub use enclave_contract_engine;

use enclave_utils::logger::{SimpleLogger, LOG_LEVEL_ENV_VAR};

pub mod registration;

mod tests;

#[allow(unused)]
static LOGGER: SimpleLogger = SimpleLogger;

#[cfg(feature = "production")]
#[ctor]
fn init_logger() {
log::set_logger(&LOGGER).unwrap(); // It's ok to panic at this stage. This shouldn't happen though
set_log_level_or_default(LevelFilter::Error, LevelFilter::Warn);
let default_log_level = log::Level::Warn;
simple_logger::init_with_level(get_log_level(default_log_level)).unwrap();
}

#[cfg(all(not(feature = "production"), not(feature = "test")))]
#[ctor]
fn init_logger() {
log::set_logger(&LOGGER).unwrap(); // It's ok to panic at this stage. This shouldn't happen though
set_log_level_or_default(LevelFilter::Trace, LevelFilter::Trace);
}

fn log_level_from_str(env_log_level: &str) -> Option<LevelFilter> {
match env_log_level {
"OFF" => Some(LevelFilter::Off),
"ERROR" => Some(LevelFilter::Error),
"WARN" => Some(LevelFilter::Warn),
"INFO" => Some(LevelFilter::Info),
"DEBUG" => Some(LevelFilter::Debug),
"TRACE" => Some(LevelFilter::Trace),
_ => None,
}
}

fn set_log_level_or_default(default: LevelFilter, max_level: LevelFilter) {
if default > max_level {
panic!(
"Logging configuration is broken, stopping to prevent secret leaking. default: {:?}, max level: {:?}",
default, max_level
);
}

let mut log_level = default;

if let Some(env_log_level) =
log_level_from_str(&env::var(LOG_LEVEL_ENV_VAR).unwrap_or_default())
{
// We want to make sure log level is not higher than WARN in production to prevent accidental secret leakage
if env_log_level <= max_level {
log_level = env_log_level;
}
}

log::set_max_level(log_level);
}

#[cfg(feature = "test")]
pub mod logging_tests {
use std::sync::SgxMutex;
use std::{env, panic};

use log::*;
// use log::{Metadata, Record};

use ctor::*;
use lazy_static::lazy_static;

use crate::{count_failures, set_log_level_or_default};

lazy_static! {
static ref LOG_BUF: SgxMutex<Vec<String>> = SgxMutex::new(Vec::new());
}
pub struct TestLogger;
impl log::Log for TestLogger {
fn enabled(&self, _metadata: &Metadata) -> bool {
true
}
fn log(&self, record: &Record) {
LOG_BUF.lock().unwrap().push(format!(
"{} [{}] {}",
record.level(),
record.target(),
record.args()
));
}
fn flush(&self) {}
}

#[ctor]
fn init_logger_test() {
log::set_logger(&TestLogger).unwrap();
}

pub fn run_tests() {
println!();
let mut failures = 0;

count_failures!(failures, {
test_log_level();
test_log_default_greater_than_max();
});

if failures != 0 {
panic!("{}: {} tests failed", file!(), failures);
}
}

fn test_log_level() {
env::set_var("LOG_LEVEL", "WARN");
set_log_level_or_default(LevelFilter::Error, LevelFilter::Info);
assert_eq!(log::max_level(), LevelFilter::Warn);
info!("Should not process");
assert!(LOG_BUF.lock().unwrap().is_empty());

env::set_var("LOG_LEVEL", "TRACE");
set_log_level_or_default(LevelFilter::Error, LevelFilter::Info);
assert_eq!(log::max_level(), LevelFilter::Error);
debug!("Should not process");
assert!(LOG_BUF.lock().unwrap().is_empty());

env::set_var("LOG_LEVEL", "WARN");
set_log_level_or_default(LevelFilter::Warn, LevelFilter::Warn);
assert_eq!(log::max_level(), LevelFilter::Warn);
trace!("Should not process");
assert!(LOG_BUF.lock().unwrap().is_empty());

warn!("This should process");
assert_eq!(LOG_BUF.lock().unwrap().len(), 1);
}

fn test_log_default_greater_than_max() {
eprintln!("The following should fail:");
let result = panic::catch_unwind(|| {
set_log_level_or_default(LevelFilter::Trace, LevelFilter::Error);
});
assert!(result.is_err());
}
let default_log_level = log::Level::Trace;
simple_logger::init_with_level(get_log_level(default_log_level)).unwrap();
}
1 change: 0 additions & 1 deletion cosmwasm/enclaves/execute/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ mod test {
enclave_contract_engine::tests::run_tests();
enclave_cosmos_types::tests::run_tests();
crate::registration::tests::run_tests();
crate::logging_tests::run_tests();

// example failing tests:
// panic!("AAAAA");
Expand Down
3 changes: 2 additions & 1 deletion cosmwasm/enclaves/query/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ sgx_types = { rev = "a37ffb9449ba6d5b6e4a9d586bbab864ae732269", git = "https://g
enclave_contract_engine = { path = "../shared/contract-engine", features = ["query-only"] }
enclave_utils = { path = "../shared/utils", features = ["query-only"] }

log = "0.4.8"
log = "0.4.17"
simple_logger = { version = "2.3.0", default-features = false, features = ["stderr"] }
ctor = "0.1.13"

[dev-dependencies]
Expand Down
52 changes: 5 additions & 47 deletions cosmwasm/enclaves/query/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,64 +4,22 @@ extern crate sgx_tstd as std;

extern crate sgx_types;

use std::env;

#[allow(unused_imports)]
use ctor::*;
use log::LevelFilter;
use enclave_utils::logger::get_log_level;

// Force linking to all the ecalls/ocalls in this package
pub use enclave_contract_engine;

use enclave_utils::logger::{SimpleLogger, LOG_LEVEL_ENV_VAR};

#[allow(unused)]
static LOGGER: SimpleLogger = SimpleLogger;

#[cfg(feature = "production")]
#[ctor]
fn init_logger() {
log::set_logger(&LOGGER).unwrap(); // It's ok to panic at this stage. This shouldn't happen though
set_log_level_or_default(LevelFilter::Error, LevelFilter::Warn);
let default_log_level = log::Level::Warn;
simple_logger::init_with_level(get_log_level(default_log_level)).unwrap();
}

#[cfg(all(not(feature = "production"), not(feature = "test")))]
#[ctor]
fn init_logger() {
log::set_logger(&LOGGER).unwrap(); // It's ok to panic at this stage. This shouldn't happen though
set_log_level_or_default(LevelFilter::Trace, LevelFilter::Trace);
}

fn log_level_from_str(env_log_level: &str) -> Option<LevelFilter> {
match env_log_level {
"OFF" => Some(LevelFilter::Off),
"ERROR" => Some(LevelFilter::Error),
"WARN" => Some(LevelFilter::Warn),
"INFO" => Some(LevelFilter::Info),
"DEBUG" => Some(LevelFilter::Debug),
"TRACE" => Some(LevelFilter::Trace),
_ => None,
}
}

fn set_log_level_or_default(default: LevelFilter, max_level: LevelFilter) {
if default > max_level {
panic!(
"Logging configuration is broken, stopping to prevent secret leaking. default: {:?}, max level: {:?}",
default, max_level
);
}

let mut log_level = default;

if let Some(env_log_level) =
log_level_from_str(&env::var(LOG_LEVEL_ENV_VAR).unwrap_or_default())
{
// We want to make sure log level is not higher than WARN in production to prevent accidental secret leakage
if env_log_level <= max_level {
log_level = env_log_level;
}
}

log::set_max_level(log_level);
let default_log_level = log::Level::Trace;
simple_logger::init_with_level(get_log_level(default_log_level)).unwrap();
}
4 changes: 1 addition & 3 deletions cosmwasm/enclaves/shared/utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ sgx_types = { rev = "a37ffb9449ba6d5b6e4a9d586bbab864ae732269", git = "https://g

[dependencies]
sgx_trts = { rev = "a37ffb9449ba6d5b6e4a9d586bbab864ae732269", git = "https://github.com/apache/teaclave-sgx-sdk.git" }

enclave-ffi-types = { path = "../../ffi-types" }

log = "0.4.14"
log = "0.4.17"
lazy_static = "1.4"
39 changes: 22 additions & 17 deletions cosmwasm/enclaves/shared/utils/src/logger.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
use log::{Metadata, Record};

pub const LOG_LEVEL_ENV_VAR: &str = "LOG_LEVEL";
use std::env;

pub struct SimpleLogger;

impl log::Log for SimpleLogger {
fn enabled(&self, _metadata: &Metadata) -> bool {
// Not really needed since we set logging level at lib.rs in the init function
true
pub fn log_level_from_str(env_log_level: &str) -> Option<log::Level> {
let uppercase = &env_log_level.to_uppercase()[..];
match uppercase {
"ERROR" => Some(log::Level::Error),
"WARN" => Some(log::Level::Warn),
"INFO" => Some(log::Level::Info),
"DEBUG" => Some(log::Level::Debug),
"TRACE" => Some(log::Level::Trace),
_ => None,
}
}

fn log(&self, record: &Record) {
println!(
"{} [{}] {}",
record.level(),
record.target(),
record.args()
);
pub fn get_log_level(default: log::Level) -> log::Level {
let env_level = &env::var(LOG_LEVEL_ENV_VAR).unwrap_or_default();
match log_level_from_str(env_level) {
Some(level) => {
if level > default {
default
} else {
level
}
}
None => default,
}

fn flush(&self) {}
}
Loading

0 comments on commit 33d39c0

Please sign in to comment.