From 4ad2cfe0c2e2682e71ac46a50fdc33b51634c446 Mon Sep 17 00:00:00 2001 From: Ruoqing He Date: Wed, 25 Oct 2023 08:16:53 +0000 Subject: [PATCH] runtime-rs: Log system enhancement By modifying RuntimeLevelFilter drain to improve logging control, enabling isolation of change effect of the loggers between components, tuning clh logs to be logged according to their log levels given by cloud-hypervisor. Fixes: #8310 Signed-off-by: Ruoqing He --- src/libs/Cargo.lock | 2 + src/libs/kata-types/src/config/agent.rs | 16 +++ .../kata-types/src/config/hypervisor/mod.rs | 15 +++ src/libs/kata-types/src/config/runtime.rs | 15 +++ src/libs/logging/Cargo.toml | 2 + src/libs/logging/src/lib.rs | 118 +++++++++++++++--- src/runtime-rs/Cargo.lock | 19 +-- .../config/configuration-dragonball.toml.in | 33 +++++ src/runtime-rs/crates/hypervisor/Cargo.toml | 1 + .../hypervisor/src/ch/inner_hypervisor.rs | 42 ++++++- src/runtime-rs/crates/resource/src/manager.rs | 3 + .../crates/resource/src/rootfs/mod.rs | 1 + src/runtime-rs/crates/runtimes/src/manager.rs | 63 +++++++++- .../crates/runtimes/virt_container/src/lib.rs | 3 + src/runtime-rs/crates/service/src/manager.rs | 3 + src/runtime-rs/crates/shim/src/logger.rs | 5 + src/runtime-rs/crates/shim/src/shim_run.rs | 3 + 17 files changed, 312 insertions(+), 32 deletions(-) diff --git a/src/libs/Cargo.lock b/src/libs/Cargo.lock index 4e36020eec..add379ce93 100644 --- a/src/libs/Cargo.lock +++ b/src/libs/Cargo.lock @@ -629,6 +629,8 @@ dependencies = [ name = "logging" version = "0.1.0" dependencies = [ + "arc-swap", + "lazy_static", "serde_json", "slog", "slog-async", diff --git a/src/libs/kata-types/src/config/agent.rs b/src/libs/kata-types/src/config/agent.rs index f30ab9a238..1ac7515cad 100644 --- a/src/libs/kata-types/src/config/agent.rs +++ b/src/libs/kata-types/src/config/agent.rs @@ -24,6 +24,17 @@ pub struct Agent { #[serde(default, rename = "enable_debug")] pub debug: bool, + /// The log log level will be applied to agent. + /// Possible values are: + /// - trace + /// - debug + /// - info + /// - warn + /// - error + /// - critical + #[serde(default = "default_agent_log_level")] + pub log_level: String, + /// Enable agent tracing. /// /// If enabled, the agent will generate OpenTelemetry trace spans. @@ -88,6 +99,7 @@ impl std::default::Default for Agent { fn default() -> Self { Self { debug: true, + log_level: "info".to_string(), enable_tracing: false, debug_console_enabled: false, server_port: DEFAULT_AGENT_VSOCK_PORT, @@ -102,6 +114,10 @@ impl std::default::Default for Agent { } } +fn default_agent_log_level() -> String { + String::from("info") +} + fn default_server_port() -> u32 { DEFAULT_AGENT_VSOCK_PORT } diff --git a/src/libs/kata-types/src/config/hypervisor/mod.rs b/src/libs/kata-types/src/config/hypervisor/mod.rs index a7a5c94bd7..69c25200de 100644 --- a/src/libs/kata-types/src/config/hypervisor/mod.rs +++ b/src/libs/kata-types/src/config/hypervisor/mod.rs @@ -379,6 +379,17 @@ pub struct DebugInfo { #[serde(default)] pub enable_debug: bool, + /// The log log level will be applied to hypervisor. + /// Possible values are: + /// - trace + /// - debug + /// - info + /// - warn + /// - error + /// - critical + #[serde(default = "default_hypervisor_log_level")] + pub log_level: String, + /// Enable dumping information about guest page structures if true. #[serde(default)] pub guest_memory_dump_paging: bool, @@ -408,6 +419,10 @@ impl DebugInfo { } } +fn default_hypervisor_log_level() -> String { + String::from("info") +} + /// Virtual machine device configuration information. #[derive(Clone, Debug, Default, Deserialize, Serialize)] pub struct DeviceInfo { diff --git a/src/libs/kata-types/src/config/runtime.rs b/src/libs/kata-types/src/config/runtime.rs index 65e48f7bf6..99820dd5f4 100644 --- a/src/libs/kata-types/src/config/runtime.rs +++ b/src/libs/kata-types/src/config/runtime.rs @@ -37,6 +37,17 @@ pub struct Runtime { #[serde(default, rename = "enable_debug")] pub debug: bool, + /// The log level will be applied to runtime. + /// Possible values are: + /// - trace + /// - debug + /// - info + /// - warn + /// - error + /// - critical + #[serde(default = "default_runtime_log_level")] + pub log_level: String, + /// Enabled experimental feature list, format: ["a", "b"]. /// /// Experimental features are features not stable enough for production, they may break @@ -226,6 +237,10 @@ impl Runtime { } } +fn default_runtime_log_level() -> String { + String::from("info") +} + #[cfg(not(feature = "enable-vendor"))] mod vendor { use super::*; diff --git a/src/libs/logging/Cargo.toml b/src/libs/logging/Cargo.toml index 4d19d90c67..3b06a5e124 100644 --- a/src/libs/logging/Cargo.toml +++ b/src/libs/logging/Cargo.toml @@ -18,6 +18,8 @@ slog-json = "2.4.0" slog-term = "2.9.0" slog-async = "2.7.0" slog-scope = "4.4.0" +lazy_static = "1.3.0" +arc-swap = "1.5.0" [dev-dependencies] tempfile = "3.2.0" diff --git a/src/libs/logging/src/lib.rs b/src/libs/logging/src/lib.rs index b662174598..9e6c42544c 100644 --- a/src/libs/logging/src/lib.rs +++ b/src/libs/logging/src/lib.rs @@ -3,13 +3,16 @@ // SPDX-License-Identifier: Apache-2.0 // +#[macro_use] +extern crate lazy_static; +use arc_swap::ArcSwap; use slog::{o, record_static, BorrowedKV, Drain, Key, OwnedKV, OwnedKVList, Record, KV}; use std::collections::HashMap; use std::io; use std::io::Write; use std::process; use std::result; -use std::sync::Mutex; +use std::sync::Arc; mod file_rotate; mod log_writer; @@ -17,12 +20,19 @@ mod log_writer; pub use file_rotate::FileRotator; pub use log_writer::LogWriter; +lazy_static! { + pub static ref FILTER_RULE: ArcSwap> = + ArcSwap::from(Arc::new(HashMap::new())); + pub static ref LOGGERS: ArcSwap> = + ArcSwap::from(Arc::new(HashMap::new())); +} + #[macro_export] macro_rules! logger_with_subsystem { ($name: ident, $subsystem: expr) => { macro_rules! $name { () => { - slog_scope::logger().new(slog::o!("subsystem" => $subsystem)) + slog::Logger::clone(logging::LOGGERS.load().get($subsystem).unwrap_or(&slog_scope::logger().new(slog::o!("subsystem" => $subsystem)))) }; } }; @@ -46,8 +56,19 @@ pub fn create_term_logger(level: slog::Level) -> (slog::Logger, slog_async::Asyn // Ensure only a unique set of key/value fields is logged let unique_drain = UniqueDrain::new(term_drain).fuse(); + // Adjust the level which will be applied to the log-system + // Info is the default level, but if Debug flag is set, the overall log level will be changed to Debug here + FILTER_RULE.rcu(|inner| { + let mut updated_inner = HashMap::new(); + updated_inner.clone_from(inner); + for v in updated_inner.values_mut() { + *v = level; + } + updated_inner + }); + // Allow runtime filtering of records by log level - let filter_drain = RuntimeLevelFilter::new(unique_drain, level).fuse(); + let filter_drain = RuntimeComponentLevelFilter::new(unique_drain).fuse(); // Ensure the logger is thread-safe let (async_drain, guard) = slog_async::Async::new(filter_drain) @@ -79,8 +100,19 @@ where // Ensure only a unique set of key/value fields is logged let unique_drain = UniqueDrain::new(json_drain).fuse(); + // Adjust the level which will be applied to the log-system + // Info is the default level, but if Debug flag is set, the overall log level will be changed to Debug here + FILTER_RULE.rcu(|inner| { + let mut updated_inner = HashMap::new(); + updated_inner.clone_from(inner); + for v in updated_inner.values_mut() { + *v = level; + } + updated_inner + }); + // Allow runtime filtering of records by log level - let filter_drain = RuntimeLevelFilter::new(unique_drain, level).fuse(); + let filter_drain = RuntimeComponentLevelFilter::new(unique_drain).fuse(); // Ensure the logger is thread-safe let (async_drain, guard) = slog_async::Async::new(filter_drain) @@ -126,6 +158,37 @@ pub fn slog_level_to_level_name(level: slog::Level) -> Result<&'static str, &'st Err("invalid slog level") } +pub fn register_component_logger(component_name: &str) { + let component = String::from(component_name); + LOGGERS.rcu(|inner| { + let mut updated_inner = HashMap::new(); + updated_inner.clone_from(inner); + updated_inner.insert( + component_name.to_string(), + slog_scope::logger() + .new(slog::o!("component" => component.clone(), "subsystem" => component.clone())), + ); + updated_inner + }); +} + +pub fn register_subsystem_logger(component_name: &str, subsystem_name: &str) { + let subsystem = String::from(subsystem_name); + LOGGERS.rcu(|inner| { + let mut updated_inner = HashMap::new(); + updated_inner.clone_from(inner); + updated_inner.insert( + subsystem_name.to_string(), + // This will update the original `subsystem` field. + inner + .get(component_name) + .unwrap_or(&slog_scope::logger()) + .new(slog::o!("subsystem" => subsystem.clone())), + ); + updated_inner + }); +} + // Used to convert an slog::OwnedKVList into a hash map. #[derive(Debug)] struct HashSerializer { @@ -216,23 +279,19 @@ where } } -// A RuntimeLevelFilter will discard all log records whose log level is less than the level -// specified in the struct. -struct RuntimeLevelFilter { +// A RuntimeComponentLevelFilter will discard all log records whose log level is less than the level +// specified in the struct according to the component it belongs to. +struct RuntimeComponentLevelFilter { drain: D, - level: Mutex, } -impl RuntimeLevelFilter { - fn new(drain: D, level: slog::Level) -> Self { - RuntimeLevelFilter { - drain, - level: Mutex::new(level), - } +impl RuntimeComponentLevelFilter { + fn new(drain: D) -> Self { + RuntimeComponentLevelFilter { drain } } } -impl Drain for RuntimeLevelFilter +impl Drain for RuntimeComponentLevelFilter where D: Drain, { @@ -244,9 +303,34 @@ where record: &slog::Record, values: &slog::OwnedKVList, ) -> result::Result { - let log_level = self.level.lock().unwrap(); + let component_level_config = FILTER_RULE.load(); - if record.level().is_at_least(*log_level) { + let mut logger_serializer = HashSerializer::new(); + values + .serialize(record, &mut logger_serializer) + .expect("log values serialization failed"); + + let mut record_serializer = HashSerializer::new(); + record + .kv() + .serialize(record, &mut record_serializer) + .expect("log record serialization failed"); + + let mut component = None; + for (k, v) in record_serializer + .fields + .iter() + .chain(logger_serializer.fields.iter()) + { + if k == "component" { + component = Some(v.to_string()); + break; + } + } + let according_level = component_level_config + .get(&component.unwrap_or(DEFAULT_SUBSYSTEM.to_string())) + .unwrap_or(&slog::Level::Info); + if record.level().is_at_least(*according_level) { self.drain.log(record, values)?; } diff --git a/src/runtime-rs/Cargo.lock b/src/runtime-rs/Cargo.lock index 66540fdfad..3e0b303104 100644 --- a/src/runtime-rs/Cargo.lock +++ b/src/runtime-rs/Cargo.lock @@ -1460,6 +1460,7 @@ dependencies = [ "path-clean", "persist", "rand 0.8.5", + "regex", "rust-ini", "safe-path 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "seccompiler", @@ -1773,6 +1774,8 @@ dependencies = [ name = "logging" version = "0.1.0" dependencies = [ + "arc-swap", + "lazy_static", "serde_json", "slog", "slog-async", @@ -1803,9 +1806,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memoffset" @@ -2831,9 +2834,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.1" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" dependencies = [ "aho-corasick", "memchr", @@ -2843,9 +2846,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.3" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" dependencies = [ "aho-corasick", "memchr", @@ -2854,9 +2857,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.4" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "reqwest" diff --git a/src/runtime-rs/config/configuration-dragonball.toml.in b/src/runtime-rs/config/configuration-dragonball.toml.in index 9e5bf51621..4c057af5c4 100644 --- a/src/runtime-rs/config/configuration-dragonball.toml.in +++ b/src/runtime-rs/config/configuration-dragonball.toml.in @@ -111,6 +111,17 @@ block_device_driver = "@DEFBLOCKSTORAGEDRIVER_DB@" # Default false #enable_debug = true +# The log level will be applied to hypervisor. +# Possible values are: +# - trace +# - debug +# - info +# - warn +# - error +# - critical +# Default: info +#log_level = info + # Disable the customizations done in the runtime when it detects # that it is running on top a VMM. This will result in the runtime # behaving as it would when running on bare metal. @@ -189,6 +200,17 @@ container_pipe_size=@PIPESIZE@ # (default: disabled) #enable_debug = true +# The log level will be applied to agent. +# Possible values are: +# - trace +# - debug +# - info +# - warn +# - error +# - critical +# (default: info) +#log_level = info + # Enable agent tracing. # # If enabled, the agent will generate OpenTelemetry trace spans. @@ -220,6 +242,17 @@ dial_timeout = 45 # (default: disabled) #enable_debug = true +# The log level will be applied to runtimes. +# Possible values are: +# - trace +# - debug +# - info +# - warn +# - error +# - critical +# (default: info) +#log_level = info + # If enabled, enabled, it means that 1) if the runtime exits abnormally, # the cleanup process will be skipped, and 2) the runtime will not exit # even if the health check fails. diff --git a/src/runtime-rs/crates/hypervisor/Cargo.toml b/src/runtime-rs/crates/hypervisor/Cargo.toml index 27c68a321b..4c1c5f9249 100644 --- a/src/runtime-rs/crates/hypervisor/Cargo.toml +++ b/src/runtime-rs/crates/hypervisor/Cargo.toml @@ -16,6 +16,7 @@ go-flag = "0.1.0" libc = ">=0.2.39" nix = "0.24.2" persist = { path = "../persist" } +regex = "1.10.2" rust-ini = "0.18.0" seccompiler = "0.2.0" serde = { version = "1.0.138", features = ["derive"] } diff --git a/src/runtime-rs/crates/hypervisor/src/ch/inner_hypervisor.rs b/src/runtime-rs/crates/hypervisor/src/ch/inner_hypervisor.rs index 765d2da161..d3e94ed006 100644 --- a/src/runtime-rs/crates/hypervisor/src/ch/inner_hypervisor.rs +++ b/src/runtime-rs/crates/hypervisor/src/ch/inner_hypervisor.rs @@ -23,6 +23,7 @@ use kata_sys_util::protection::{available_guest_protection, GuestProtection}; use kata_types::capabilities::{Capabilities, CapabilityBits}; use kata_types::config::default::DEFAULT_CH_ROOTFS_TYPE; use lazy_static::lazy_static; +use regex::Regex; use serde::{Deserialize, Serialize}; use serde_json::Value; use std::convert::TryFrom; @@ -50,6 +51,12 @@ const CH_FEATURES_KEY: &str = "features"; // The name of the CH build-time feature for Intel TDX. const CH_FEATURE_TDX: &str = "tdx"; +const LOG_LEVEL_TRACE: &str = "TRCE"; +const LOG_LEVEL_DEBUG: &str = "DEBG"; +const LOG_LEVEL_INFO: &str = "INFO"; +const LOG_LEVEL_WARNING: &str = "WARN"; +const LOG_LEVEL_ERROR: &str = "ERRO"; + #[derive(Clone, Deserialize, Serialize)] pub struct VmmPingResponse { pub build_version: String, @@ -723,15 +730,25 @@ async fn cloud_hypervisor_log_output(mut child: Child, mut shutdown: Receiver { if let Ok(line) = stderr_line { let line = line.ok_or("missing stderr line").map_err(|e| anyhow!(e))?; - - info!(sl!(), "{:?}", line; "stream" => "stderr"); + match parse_ch_log_level(&line) { + LOG_LEVEL_TRACE => trace!(sl!(), "{:?}", line; "stream" => "stderr"), + LOG_LEVEL_DEBUG => debug!(sl!(), "{:?}", line; "stream" => "stderr"), + LOG_LEVEL_WARNING => warn!(sl!(), "{:?}", line; "stream" => "stderr"), + LOG_LEVEL_ERROR => error!(sl!(), "{:?}", line; "stream" => "stderr"), + _ => info!(sl!(), "{:?}", line; "stream" => "stderr"), + } } }, stdout_line = poll_fn(|cx| Pin::new(&mut stdout_lines).poll_next_line(cx)) => { if let Ok(line) = stdout_line { let line = line.ok_or("missing stdout line").map_err(|e| anyhow!(e))?; - - info!(sl!(), "{:?}", line; "stream" => "stdout"); + match parse_ch_log_level(&line) { + LOG_LEVEL_TRACE => trace!(sl!(), "{:?}", line; "stream" => "stdout"), + LOG_LEVEL_DEBUG => debug!(sl!(), "{:?}", line; "stream" => "stdout"), + LOG_LEVEL_WARNING => warn!(sl!(), "{:?}", line; "stream" => "stdout"), + LOG_LEVEL_ERROR => error!(sl!(), "{:?}", line; "stream" => "stdout"), + _ => info!(sl!(), "{:?}", line; "stream" => "stdout"), + } } }, }; @@ -743,6 +760,23 @@ async fn cloud_hypervisor_log_output(mut child: Child, mut shutdown: Receiver &str { + let re = Regex::new(r"cloud-hypervisor: [0-9]*[.][0-9]+ms: <\w+> (?\w+)").unwrap(); + let level = re + .captures(line) + .expect("There should be a match for level") + .name("level") + .expect("Level should be found in record") + .as_str(); + match level { + "TRACE" => LOG_LEVEL_TRACE, + "DEBUG" => LOG_LEVEL_DEBUG, + "WARN" => LOG_LEVEL_WARNING, + "ERROR" => LOG_LEVEL_ERROR, + _ => LOG_LEVEL_INFO, // info or other values will return info, + } +} + lazy_static! { // Store the fake guest protection value used by // get_fake_guest_protection() and set_fake_guest_protection(). diff --git a/src/runtime-rs/crates/resource/src/manager.rs b/src/runtime-rs/crates/resource/src/manager.rs index a96e16b8dd..25cd3301ff 100644 --- a/src/runtime-rs/crates/resource/src/manager.rs +++ b/src/runtime-rs/crates/resource/src/manager.rs @@ -48,6 +48,9 @@ impl ResourceManager { hypervisor: Arc, toml_config: Arc, ) -> Result { + // Regist resource logger for later use. + logging::register_subsystem_logger("runtimes", "resource"); + Ok(Self { inner: Arc::new(RwLock::new( ResourceManagerInner::new(sid, agent, hypervisor, toml_config).await?, diff --git a/src/runtime-rs/crates/resource/src/rootfs/mod.rs b/src/runtime-rs/crates/resource/src/rootfs/mod.rs index a924b021bd..75510ed027 100644 --- a/src/runtime-rs/crates/resource/src/rootfs/mod.rs +++ b/src/runtime-rs/crates/resource/src/rootfs/mod.rs @@ -12,6 +12,7 @@ use async_trait::async_trait; use kata_types::mount::Mount; mod block_rootfs; use hypervisor::{device::device_manager::DeviceManager, Hypervisor}; + use std::{sync::Arc, vec::Vec}; use tokio::sync::RwLock; diff --git a/src/runtime-rs/crates/runtimes/src/manager.rs b/src/runtime-rs/crates/runtimes/src/manager.rs index a5af2a3fdf..51b0985751 100644 --- a/src/runtime-rs/crates/runtimes/src/manager.rs +++ b/src/runtime-rs/crates/runtimes/src/manager.rs @@ -4,7 +4,7 @@ // SPDX-License-Identifier: Apache-2.0 // -use std::{path::PathBuf, str::from_utf8, sync::Arc}; +use std::{collections::HashMap, path::PathBuf, str::from_utf8, sync::Arc}; use anyhow::{anyhow, Context, Result}; use common::{ @@ -19,6 +19,7 @@ use kata_types::{ }; #[cfg(feature = "linux")] use linux_container::LinuxContainer; +use logging::FILTER_RULE; use netns_rs::NetNs; use persist::sandbox_persist::Persist; use resource::{ @@ -43,6 +44,18 @@ use crate::{ tracer::{KataTracer, ROOTSPAN}, }; +fn convert_string_to_slog_level(string_level: &str) -> slog::Level { + match string_level { + "trace" => slog::Level::Trace, + "debug" => slog::Level::Debug, + "info" => slog::Level::Info, + "warn" => slog::Level::Warning, + "error" => slog::Level::Error, + "critical" => slog::Level::Critical, + _ => slog::Level::Info, + } +} + struct RuntimeHandlerManagerInner { id: String, msg_sender: Sender, @@ -149,6 +162,8 @@ impl RuntimeHandlerManagerInner { let config = load_config(spec, options).context("load config")?; + update_component_log_level(&config); + let dan_path = dan_config_path(&config, &self.id); let mut network_created = false; // set netns to None if we want no network for the VM @@ -469,7 +484,11 @@ fn load_config(spec: &oci::Spec, option: &Option>) -> Result } else { String::from("") }; - info!(sl!(), "get config path {:?}", &config_path); + + // Clone a logger from global logger to ensure the logs in this function get flushed when drop + let logger = slog::Logger::clone(&slog_scope::logger()); + + info!(logger, "get config path {:?}", &config_path); let (mut toml_config, _) = TomlConfig::load_from_file(&config_path).context("load toml config")?; annotation.update_config_by_annotation(&mut toml_config)?; @@ -492,7 +511,7 @@ fn load_config(spec: &oci::Spec, option: &Option>) -> Result .setup_config(&mut toml_config) .context("failed to setup static resource mgmt config")?; - info!(sl!(), "get config content {:?}", &toml_config); + info!(logger, "get config content {:?}", &toml_config); Ok(toml_config) } @@ -512,3 +531,41 @@ fn update_agent_kernel_params(config: &mut TomlConfig) -> Result<()> { } Ok(()) } + +// this update the log_level of three component: agent, hypervisor, runtime +// according to the settings read from configuration file +fn update_component_log_level(config: &TomlConfig) { + // Retrieve the log-levels set in configuration file, modify the FILTER_RULE accordingly + let default_level = String::from("info"); + let agent_level = if let Some(agent_config) = config.agent.get(&config.runtime.agent_name) { + agent_config.log_level.clone() + } else { + default_level.clone() + }; + let hypervisor_level = + if let Some(hypervisor_config) = config.hypervisor.get(&config.runtime.hypervisor_name) { + hypervisor_config.debug_info.log_level.clone() + } else { + default_level.clone() + }; + let runtime_level = config.runtime.log_level.clone(); + + // Update FILTER_RULE to apply changes + FILTER_RULE.rcu(|inner| { + let mut updated_inner = HashMap::new(); + updated_inner.clone_from(inner); + updated_inner.insert( + "runtimes".to_string(), + convert_string_to_slog_level(&runtime_level), + ); + updated_inner.insert( + "agent".to_string(), + convert_string_to_slog_level(&agent_level), + ); + updated_inner.insert( + "hypervisor".to_string(), + convert_string_to_slog_level(&hypervisor_level), + ); + updated_inner + }); +} diff --git a/src/runtime-rs/crates/runtimes/virt_container/src/lib.rs b/src/runtime-rs/crates/runtimes/virt_container/src/lib.rs index 4999ee4f9e..295b64fe11 100644 --- a/src/runtime-rs/crates/runtimes/virt_container/src/lib.rs +++ b/src/runtime-rs/crates/runtimes/virt_container/src/lib.rs @@ -44,6 +44,9 @@ pub struct VirtContainer {} #[async_trait] impl RuntimeHandler for VirtContainer { fn init() -> Result<()> { + // Before start logging with virt-container, regist it + logging::register_subsystem_logger("runtimes", "virt-container"); + // register let dragonball_config = Arc::new(DragonballConfig::new()); register_hypervisor_plugin("dragonball", dragonball_config); diff --git a/src/runtime-rs/crates/service/src/manager.rs b/src/runtime-rs/crates/service/src/manager.rs index 2b16fe3f47..176ef9f538 100644 --- a/src/runtime-rs/crates/service/src/manager.rs +++ b/src/runtime-rs/crates/service/src/manager.rs @@ -62,6 +62,9 @@ impl ServiceManager { namespace: &str, task_server_fd: RawFd, ) -> Result { + // Regist service logger for later use. + logging::register_subsystem_logger("runtimes", "service"); + let (sender, receiver) = channel::(MESSAGE_BUFFER_SIZE); let rt_mgr = RuntimeHandlerManager::new(id, sender).context("new runtime handler")?; let handler = Arc::new(rt_mgr); diff --git a/src/runtime-rs/crates/shim/src/logger.rs b/src/runtime-rs/crates/shim/src/logger.rs index 50ba891fb3..b3231df2e2 100644 --- a/src/runtime-rs/crates/shim/src/logger.rs +++ b/src/runtime-rs/crates/shim/src/logger.rs @@ -37,5 +37,10 @@ pub(crate) fn set_logger(path: &str, sid: &str, is_debug: bool) -> Result