diff --git a/Cargo.lock b/Cargo.lock index 75217f52761..8186d0489f5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -854,6 +854,12 @@ dependencies = [ "serde", ] +[[package]] +name = "cap" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f125eb85b84a24c36b02ed1d22c9dd8632f53b3cde6e4d23512f94021030003" + [[package]] name = "capture-logger" version = "0.1.1" @@ -3622,6 +3628,7 @@ dependencies = [ "c8y-firmware-plugin", "c8y-remote-access-plugin", "camino", + "cap", "certificate", "clap", "doku", @@ -3668,6 +3675,7 @@ dependencies = [ "axum_tls", "bytes", "camino", + "cap", "clap", "flockfile", "futures", @@ -3779,6 +3787,7 @@ dependencies = [ "c8y_auth_proxy", "c8y_http_proxy", "c8y_mapper_ext", + "cap", "clap", "clock", "collectd_ext", diff --git a/Cargo.toml b/Cargo.toml index 4ced29ce063..d30871eb85c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,6 +56,7 @@ c8y_http_proxy = { path = "crates/extensions/c8y_http_proxy" } c8y_log_manager = { path = "crates/extensions/c8y_log_manager" } c8y_mapper_ext = { path = "crates/extensions/c8y_mapper_ext" } camino = "1.1" +cap = "0.1" capture-logger = "0.1" certificate = { path = "crates/common/certificate" } clap = { version = "4.4", features = ["cargo", "derive"] } diff --git a/crates/common/tedge_config/src/lib.rs b/crates/common/tedge_config/src/lib.rs index 8274cf945a0..d6b703bd082 100644 --- a/crates/common/tedge_config/src/lib.rs +++ b/crates/common/tedge_config/src/lib.rs @@ -19,3 +19,9 @@ pub fn get_new_tedge_config() -> Result { let tedge_config_location = TEdgeConfigLocation::default(); TEdgeConfigRepository::new(tedge_config_location).load() } + +/// loads the tedge config from a config directory +pub fn load_tedge_config(config_dir: &Path) -> Result { + let tedge_config_location = TEdgeConfigLocation::from_custom_root(config_dir); + TEdgeConfigRepository::new(tedge_config_location).load() +} diff --git a/crates/common/tedge_config/src/tedge_config_cli/tedge_config.rs b/crates/common/tedge_config/src/tedge_config_cli/tedge_config.rs index 642cee5cb53..a7b18609277 100644 --- a/crates/common/tedge_config/src/tedge_config_cli/tedge_config.rs +++ b/crates/common/tedge_config/src/tedge_config_cli/tedge_config.rs @@ -719,6 +719,10 @@ define_tedge_config! { /// Whether to create a lock file or not #[tedge_config(example = "true", default(value = true))] lock_files: bool, + + /// Interval at which the memory usage is logged (in seconds) + #[tedge_config(example = "60", default(value = 300_u64))] + log_memory_interval: Seconds, }, logs: { diff --git a/crates/core/tedge/Cargo.toml b/crates/core/tedge/Cargo.toml index d4eba71e4cc..dc6ea842c2e 100644 --- a/crates/core/tedge/Cargo.toml +++ b/crates/core/tedge/Cargo.toml @@ -17,6 +17,7 @@ base64 = { workspace = true } c8y-firmware-plugin = { workspace = true } c8y-remote-access-plugin = { workspace = true } camino = { workspace = true } +cap = { workspace = true } certificate = { workspace = true } clap = { workspace = true, features = [ "cargo", diff --git a/crates/core/tedge/src/main.rs b/crates/core/tedge/src/main.rs index 4ea9572dd21..1144e0b9b88 100644 --- a/crates/core/tedge/src/main.rs +++ b/crates/core/tedge/src/main.rs @@ -2,15 +2,22 @@ #![deny(clippy::mem_forget)] use anyhow::Context; +use cap::Cap; use clap::Parser; +use std::alloc; use std::future::Future; use std::path::PathBuf; +use std::time::Duration; use tedge::command::BuildCommand; use tedge::command::BuildContext; use tedge::Component; use tedge::TEdgeOptMulticall; use tedge_apt_plugin::AptCli; use tedge_config::system_services::set_log_level; +use tracing::log; + +#[global_allocator] +static ALLOCATOR: Cap = Cap::new(alloc::System, usize::MAX); fn main() -> anyhow::Result<()> { let executable_name = executable_name(); @@ -22,10 +29,20 @@ fn main() -> anyhow::Result<()> { let opt = parse_multicall_if_known(&executable_name); match opt { - TEdgeOptMulticall::Component(Component::TedgeMapper(mapper_opt)) => { - block_on(tedge_mapper::run(mapper_opt)) + TEdgeOptMulticall::Component(Component::TedgeMapper(opt)) => { + let tedge_config = tedge_config::load_tedge_config(&opt.config_dir)?; + block_on_with( + tedge_config.run.log_memory_interval.duration(), + tedge_mapper::run(opt), + ) + } + TEdgeOptMulticall::Component(Component::TedgeAgent(opt)) => { + let tedge_config = tedge_config::load_tedge_config(&opt.config_dir)?; + block_on_with( + tedge_config.run.log_memory_interval.duration(), + tedge_agent::run(opt), + ) } - TEdgeOptMulticall::Component(Component::TedgeAgent(opt)) => block_on(tedge_agent::run(opt)), TEdgeOptMulticall::Component(Component::C8yFirmwarePlugin(fp_opt)) => { block_on(c8y_firmware_plugin::run(fp_opt)) } @@ -63,6 +80,23 @@ fn block_on(future: impl Future) -> T { tokio::runtime::Runtime::new().unwrap().block_on(future) } +fn block_on_with(log_memory_interval: Duration, future: impl Future) -> T { + if log_memory_interval.is_zero() { + block_on(future) + } else { + block_on(async move { + tokio::spawn(async move { + loop { + log::info!("Allocated memory: {} Bytes", ALLOCATOR.allocated()); + tokio::time::sleep(log_memory_interval).await; + } + }); + + future.await + }) + } +} + fn executable_name() -> Option { Some( PathBuf::from(std::env::args_os().next()?) diff --git a/crates/core/tedge_agent/Cargo.toml b/crates/core/tedge_agent/Cargo.toml index 23122f72d56..fb5771b1fe5 100644 --- a/crates/core/tedge_agent/Cargo.toml +++ b/crates/core/tedge_agent/Cargo.toml @@ -16,6 +16,7 @@ axum = { workspace = true } axum-server = { workspace = true } axum_tls = { workspace = true } camino = { workspace = true } +cap = { workspace = true } clap = { workspace = true } flockfile = { workspace = true } futures = { workspace = true } diff --git a/crates/core/tedge_agent/src/main.rs b/crates/core/tedge_agent/src/main.rs index 0efbe96a006..b0a549132db 100644 --- a/crates/core/tedge_agent/src/main.rs +++ b/crates/core/tedge_agent/src/main.rs @@ -1,7 +1,23 @@ +use cap::Cap; use clap::Parser; +use std::alloc; + +#[global_allocator] +static ALLOCATOR: Cap = Cap::new(alloc::System, usize::MAX); #[tokio::main] -async fn main() -> Result<(), anyhow::Error> { +async fn main() -> anyhow::Result<()> { let agent_opt = tedge_agent::AgentOpt::parse(); + let tedge_config = tedge_config::load_tedge_config(&agent_opt.config_dir)?; + let log_memory_interval = tedge_config.run.log_memory_interval.duration(); + if !log_memory_interval.is_zero() { + tokio::spawn(async move { + loop { + log::info!("Allocated memory: {} Bytes", ALLOCATOR.allocated()); + tokio::time::sleep(log_memory_interval).await; + } + }); + } + tedge_agent::run(agent_opt).await } diff --git a/crates/core/tedge_mapper/Cargo.toml b/crates/core/tedge_mapper/Cargo.toml index c039f563364..d56cef835bd 100644 --- a/crates/core/tedge_mapper/Cargo.toml +++ b/crates/core/tedge_mapper/Cargo.toml @@ -19,6 +19,7 @@ c8y_api = { workspace = true } c8y_auth_proxy = { workspace = true } c8y_http_proxy = { workspace = true } c8y_mapper_ext = { workspace = true } +cap = { workspace = true } clap = { workspace = true } clock = { workspace = true } collectd_ext = { workspace = true } diff --git a/crates/core/tedge_mapper/src/lib.rs b/crates/core/tedge_mapper/src/lib.rs index 995ee6cbc8d..50dbe72d1ed 100644 --- a/crates/core/tedge_mapper/src/lib.rs +++ b/crates/core/tedge_mapper/src/lib.rs @@ -6,9 +6,9 @@ use crate::core::component::TEdgeComponent; use clap::Parser; use flockfile::check_another_instance_is_not_running; use std::fmt; -use std::path::PathBuf; use tedge_config::system_services::get_log_level; use tedge_config::system_services::set_log_level; +use tedge_config::PathBuf; use tedge_config::DEFAULT_TEDGE_CONFIG_PATH; use tracing::log::warn; @@ -111,6 +111,8 @@ pub async fn run(mapper_opt: MapperOpt) -> anyhow::Result<()> { warn!("This --clear option has been deprecated and will be removed in a future release"); Ok(()) } else { - component.start(config, &mapper_opt.config_dir).await + component + .start(config, mapper_opt.config_dir.as_ref()) + .await } } diff --git a/crates/core/tedge_mapper/src/main.rs b/crates/core/tedge_mapper/src/main.rs index a1ccaa45a55..6d1dabeadaf 100644 --- a/crates/core/tedge_mapper/src/main.rs +++ b/crates/core/tedge_mapper/src/main.rs @@ -1,7 +1,24 @@ +use cap::Cap; use clap::Parser; +use std::alloc; +use tracing::log; + +#[global_allocator] +static ALLOCATOR: Cap = Cap::new(alloc::System, usize::MAX); #[tokio::main] async fn main() -> anyhow::Result<()> { let mapper_opt = tedge_mapper::MapperOpt::parse(); + let tedge_config = tedge_config::load_tedge_config(&mapper_opt.config_dir)?; + let log_memory_interval = tedge_config.run.log_memory_interval.duration(); + if !log_memory_interval.is_zero() { + tokio::spawn(async move { + loop { + log::info!("Allocated memory: {} Bytes", ALLOCATOR.allocated()); + tokio::time::sleep(log_memory_interval).await; + } + }); + } + tedge_mapper::run(mapper_opt).await }