From 451e0feb24c427e950fcdc5d2706eb68d2b8cb5f Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Sun, 15 Jun 2025 15:52:23 +0200 Subject: [PATCH 01/11] =?UTF-8?q?[FRAME]=C2=A0Custom=20log=20level=20for?= =?UTF-8?q?=20the=20runtime=20benchmarks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oliver Tale-Yazdi --- Cargo.lock | 1 + polkadot/scripts/build-only-wasm.sh | 4 +- .../utils/frame/benchmarking-cli/Cargo.toml | 1 + .../benchmarking-cli/src/pallet/command.rs | 19 +++-- .../benchmarking-cli/src/pallet/logging.rs | 74 +++++++++++++++++++ .../frame/benchmarking-cli/src/pallet/mod.rs | 11 +++ 6 files changed, 100 insertions(+), 10 deletions(-) create mode 100644 substrate/utils/frame/benchmarking-cli/src/pallet/logging.rs diff --git a/Cargo.lock b/Cargo.lock index 3fe7bb2f3f251..59e70a7503c28 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6604,6 +6604,7 @@ dependencies = [ "sp-io 30.0.0", "sp-keystore 0.34.0", "sp-runtime 31.0.1", + "sp-runtime-interface 24.0.0", "sp-state-machine 0.35.0", "sp-storage 19.0.0", "sp-timestamp", diff --git a/polkadot/scripts/build-only-wasm.sh b/polkadot/scripts/build-only-wasm.sh index 50b786dab4101..9904951967f14 100755 --- a/polkadot/scripts/build-only-wasm.sh +++ b/polkadot/scripts/build-only-wasm.sh @@ -30,8 +30,8 @@ fi if [ -d $WASM_BUILDER_RUNNER ]; then export DEBUG=false export OUT_DIR="$PROJECT_ROOT/target/release/build" - fl_cargo run --release --manifest-path="$WASM_BUILDER_RUNNER/Cargo.toml" \ + fl_cargo run --release --manifest-path="$WASM_BUILDER_RUNNER/Cargo.toml" --features runtime-benchmarks \ | grep -vE "cargo:rerun-if-|Executing build command" else - fl_cargo build --release -p $1 + fl_cargo build --release -p $1 --features runtime-benchmarks fi diff --git a/substrate/utils/frame/benchmarking-cli/Cargo.toml b/substrate/utils/frame/benchmarking-cli/Cargo.toml index b903175a38149..e4207c9030122 100644 --- a/substrate/utils/frame/benchmarking-cli/Cargo.toml +++ b/substrate/utils/frame/benchmarking-cli/Cargo.toml @@ -58,6 +58,7 @@ sp-database = { workspace = true, default-features = true } sp-externalities = { workspace = true, default-features = true } sp-genesis-builder = { workspace = true, default-features = true } sp-inherents = { workspace = true, default-features = true } +sp-runtime-interface = { workspace = true, default-features = true } sp-io = { workspace = true, default-features = true } sp-keystore = { workspace = true, default-features = true } sp-runtime = { workspace = true, default-features = true } diff --git a/substrate/utils/frame/benchmarking-cli/src/pallet/command.rs b/substrate/utils/frame/benchmarking-cli/src/pallet/command.rs index 50d7432a634d6..a3b810066be09 100644 --- a/substrate/utils/frame/benchmarking-cli/src/pallet/command.rs +++ b/substrate/utils/frame/benchmarking-cli/src/pallet/command.rs @@ -17,7 +17,7 @@ use super::{ types::{ComponentRange, ComponentRangeMap}, - writer, ListOutput, PalletCmd, + writer, ListOutput, PalletCmd, LOG_TARGET, }; use crate::{ pallet::{types::FetchedCode, GenesisBuilderPolicy}, @@ -50,7 +50,7 @@ use sp_keystore::{testing::MemoryKeystore, KeystoreExt}; use sp_runtime::traits::Hash; use sp_state_machine::StateMachine; use sp_trie::{proof_size_extension::ProofSizeExt, recorder::Recorder}; -use sp_wasm_interface::HostFunctions; +use sp_wasm_interface::{ExtendedHostFunctions, HostFunctions}; use std::{ borrow::Cow, collections::{BTreeMap, BTreeSet, HashMap}, @@ -60,11 +60,13 @@ use std::{ time, }; -/// Logging target -const LOG_TARGET: &'static str = "polkadot_sdk_frame::benchmark::pallet"; - -type SubstrateAndExtraHF = - (sp_io::SubstrateHostFunctions, frame_benchmarking::benchmarking::HostFunctions, T); +type SubstrateAndExtraHF = ( + ExtendedHostFunctions< + (sp_io::SubstrateHostFunctions, frame_benchmarking::benchmarking::HostFunctions), + super::logging::logging::HostFunctions, + >, // Our special logging interface + T, +); /// How the PoV size of a storage item should be estimated. #[derive(clap::ValueEnum, Debug, Eq, PartialEq, Clone, Copy)] pub enum PovEstimationMode { @@ -252,6 +254,7 @@ impl PalletCmd { }; return self.output_from_results(&batches) } + super::logging::init(self.runtime_log); let state_handler = self.state_handler_from_cli::>(chain_spec)?; @@ -715,7 +718,7 @@ impl PalletCmd { state: &'a BenchmarkingState, ) -> Result, H>> { if let Some(runtime) = self.runtime.as_ref() { - log::info!(target: LOG_TARGET, "Loading WASM from file"); + log::debug!(target: LOG_TARGET, "Loading WASM from file {}", runtime.display()); let code = fs::read(runtime).map_err(|e| { format!( "Could not load runtime file from path: {}, error: {}", diff --git a/substrate/utils/frame/benchmarking-cli/src/pallet/logging.rs b/substrate/utils/frame/benchmarking-cli/src/pallet/logging.rs new file mode 100644 index 0000000000000..b52188bff96d1 --- /dev/null +++ b/substrate/utils/frame/benchmarking-cli/src/pallet/logging.rs @@ -0,0 +1,74 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +use super::LOG_TARGET; +use log::LevelFilter; +use sp_core::{LogLevelFilter, RuntimeInterfaceLogLevel}; +use sp_runtime_interface::{ + pass_by::{PassAs, PassFatPointerAndRead, ReturnAs}, + runtime_interface, +}; +use std::cell::OnceCell; + +thread_local! { + /// Log level that the runtime will use. + /// + /// Must be initialized by the host before invoking the runtime executor. + static RUNTIME_LOG_LEVEL: OnceCell = OnceCell::new(); +} + +/// Init runtime logger with the following priority (high to low): +/// - CLI argument +/// - Environment variable +/// - Default logger settings +pub fn init(arg: Option) { + let level = arg.unwrap_or_else(|| { + if let Ok(env) = std::env::var("RUNTIME_LOG") { + env.parse().expect("Invalid level for RUNTIME_LOG") + } else { + log::max_level() + } + }); + + RUNTIME_LOG_LEVEL.with(|cell| { + cell.set(level).expect("Can be set by host"); + log::info!(target: LOG_TARGET, "Initialized runtime log level to '{:?}'", level); + }); +} + +/// Alternative implementation to `sp_runtime_interface::logging::HostFunctions` for benchmarking. +#[runtime_interface] +pub trait Logging { + fn log( + level: PassAs, + target: PassFatPointerAndRead<&str>, + message: PassFatPointerAndRead<&[u8]>, + ) { + let Ok(message) = core::str::from_utf8(message) else { + log::error!(target: LOG_TARGET, "Runtime tried to log invalid UTF-8 data"); + return; + }; + + log::log!(target: target, log::Level::from(level), "{}", message) + } + + fn max_level() -> ReturnAs { + RUNTIME_LOG_LEVEL + .with(|level| *level.get().expect("Must be set by host")) + .into() + } +} diff --git a/substrate/utils/frame/benchmarking-cli/src/pallet/mod.rs b/substrate/utils/frame/benchmarking-cli/src/pallet/mod.rs index 5cb353059988c..fdb7eb8cfd912 100644 --- a/substrate/utils/frame/benchmarking-cli/src/pallet/mod.rs +++ b/substrate/utils/frame/benchmarking-cli/src/pallet/mod.rs @@ -16,6 +16,7 @@ // limitations under the License. mod command; +mod logging; mod types; mod writer; @@ -28,6 +29,9 @@ use sc_cli::{ }; use std::{fmt::Debug, path::PathBuf}; +/// Logging target +const LOG_TARGET: &'static str = "polkadot_sdk_frame::benchmark::pallet"; + // Add a more relaxed parsing for pallet names by allowing pallet directory names with `-` to be // used like crate names with `_` fn parse_pallet_name(pallet: &str) -> std::result::Result { @@ -187,6 +191,13 @@ pub struct PalletCmd { #[arg(long, conflicts_with = "chain", required_if_eq("genesis_builder", "runtime"))] pub runtime: Option, + /// Set the runtime log level. + /// + /// This will overwrite the `RUNTIME_LOG` environment variable. If neither is set, the CLI + /// default set by `RUST_LOG` setting is used. + #[arg(long)] + pub runtime_log: Option, + /// Do not fail if there are unknown but also unused host functions in the runtime. #[arg(long)] pub allow_missing_host_functions: bool, From e51fe3cdc6db8a13ebdc58123c375702374e309e Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Sun, 15 Jun 2025 15:54:20 +0200 Subject: [PATCH 02/11] undo wip changes Signed-off-by: Oliver Tale-Yazdi --- polkadot/scripts/build-only-wasm.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/polkadot/scripts/build-only-wasm.sh b/polkadot/scripts/build-only-wasm.sh index 9904951967f14..50b786dab4101 100755 --- a/polkadot/scripts/build-only-wasm.sh +++ b/polkadot/scripts/build-only-wasm.sh @@ -30,8 +30,8 @@ fi if [ -d $WASM_BUILDER_RUNNER ]; then export DEBUG=false export OUT_DIR="$PROJECT_ROOT/target/release/build" - fl_cargo run --release --manifest-path="$WASM_BUILDER_RUNNER/Cargo.toml" --features runtime-benchmarks \ + fl_cargo run --release --manifest-path="$WASM_BUILDER_RUNNER/Cargo.toml" \ | grep -vE "cargo:rerun-if-|Executing build command" else - fl_cargo build --release -p $1 --features runtime-benchmarks + fl_cargo build --release -p $1 fi From f53d6bd0cd7c4da2359052d7cd1bbce7f6b045d7 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Sun, 15 Jun 2025 16:14:15 +0200 Subject: [PATCH 03/11] Fix instance space in filename Signed-off-by: Oliver Tale-Yazdi --- substrate/utils/frame/benchmarking-cli/src/pallet/writer.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/substrate/utils/frame/benchmarking-cli/src/pallet/writer.rs b/substrate/utils/frame/benchmarking-cli/src/pallet/writer.rs index 28918dd4e6a39..e9312023611b9 100644 --- a/substrate/utils/frame/benchmarking-cli/src/pallet/writer.rs +++ b/substrate/utils/frame/benchmarking-cli/src/pallet/writer.rs @@ -467,7 +467,10 @@ pub(crate) fn write_results( file_name = format!("{}_{}", file_name, instance.to_snake_case()); } // "mod::pallet_name.rs" becomes "mod_pallet_name.rs". - file_path.push(file_name.replace("::", "_")); + file_name = file_name.replace("::", "_"); + // Some old runtimes have a bug with the pallet and instance name containing a space + file_name = file_name.replace(" ", ""); + file_path.push(file_name); file_path.set_extension("rs"); } From 9f9136e69a7b6737b5575e59856f47b4487ff7d5 Mon Sep 17 00:00:00 2001 From: "cmd[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 15 Jun 2025 14:17:46 +0000 Subject: [PATCH 04/11] Update from github-actions[bot] running command 'prdoc --audience runtime_dev --bump minor' --- prdoc/pr_8857.prdoc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 prdoc/pr_8857.prdoc diff --git a/prdoc/pr_8857.prdoc b/prdoc/pr_8857.prdoc new file mode 100644 index 0000000000000..1e220c18f2d8a --- /dev/null +++ b/prdoc/pr_8857.prdoc @@ -0,0 +1,16 @@ +title: "[FRAME]\_Custom log level for the runtime benchmarks" +doc: +- audience: Runtime Dev + description: |- + Changes: + - Add `--runtime-log` option to omni-bencher CLI + - Read env var `RUNTIME_LOG` as fallback to the `--runtime-log` option + - Set custom log level for runtime benchmarks that can be different form CLI level + - Fix issue where old runtimes have a space in the pallet or instance name from breaking change in `quote` macro + + Note: I saw that the genesis builder is not using the provided host functions, hence it still logs things during genesis config building. +crates: +- name: polkadot + bump: minor +- name: frame-benchmarking-cli + bump: minor From c66da5a2ed9f875c42387e517d7ecbec5ff914fc Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Sun, 15 Jun 2025 16:19:27 +0200 Subject: [PATCH 05/11] Beauty and clippy Signed-off-by: Oliver Tale-Yazdi --- .../frame/benchmarking-cli/src/pallet/command.rs | 2 +- .../frame/benchmarking-cli/src/pallet/logging.rs | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/substrate/utils/frame/benchmarking-cli/src/pallet/command.rs b/substrate/utils/frame/benchmarking-cli/src/pallet/command.rs index a3b810066be09..055deb0ae17eb 100644 --- a/substrate/utils/frame/benchmarking-cli/src/pallet/command.rs +++ b/substrate/utils/frame/benchmarking-cli/src/pallet/command.rs @@ -64,7 +64,7 @@ type SubstrateAndExtraHF = ( ExtendedHostFunctions< (sp_io::SubstrateHostFunctions, frame_benchmarking::benchmarking::HostFunctions), super::logging::logging::HostFunctions, - >, // Our special logging interface + >, T, ); /// How the PoV size of a storage item should be estimated. diff --git a/substrate/utils/frame/benchmarking-cli/src/pallet/logging.rs b/substrate/utils/frame/benchmarking-cli/src/pallet/logging.rs index b52188bff96d1..cd843d2b4689e 100644 --- a/substrate/utils/frame/benchmarking-cli/src/pallet/logging.rs +++ b/substrate/utils/frame/benchmarking-cli/src/pallet/logging.rs @@ -53,19 +53,20 @@ pub fn init(arg: Option) { /// Alternative implementation to `sp_runtime_interface::logging::HostFunctions` for benchmarking. #[runtime_interface] pub trait Logging { + #[allow(dead_code)] fn log( level: PassAs, target: PassFatPointerAndRead<&str>, message: PassFatPointerAndRead<&[u8]>, ) { - let Ok(message) = core::str::from_utf8(message) else { + if let Ok(message) = core::str::from_utf8(message) { + log::log!(target: target, log::Level::from(level), "{}", message); + } else { log::error!(target: LOG_TARGET, "Runtime tried to log invalid UTF-8 data"); - return; - }; - - log::log!(target: target, log::Level::from(level), "{}", message) + } } + #[allow(dead_code)] fn max_level() -> ReturnAs { RUNTIME_LOG_LEVEL .with(|level| *level.get().expect("Must be set by host")) From 0b1b3c8e8bb88f6bf2cb322dd4fb260dfd39538d Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Sun, 15 Jun 2025 16:25:48 +0200 Subject: [PATCH 06/11] PRdoc Signed-off-by: Oliver Tale-Yazdi --- prdoc/pr_8857.prdoc | 2 -- 1 file changed, 2 deletions(-) diff --git a/prdoc/pr_8857.prdoc b/prdoc/pr_8857.prdoc index 1e220c18f2d8a..5863428b05053 100644 --- a/prdoc/pr_8857.prdoc +++ b/prdoc/pr_8857.prdoc @@ -7,8 +7,6 @@ doc: - Read env var `RUNTIME_LOG` as fallback to the `--runtime-log` option - Set custom log level for runtime benchmarks that can be different form CLI level - Fix issue where old runtimes have a space in the pallet or instance name from breaking change in `quote` macro - - Note: I saw that the genesis builder is not using the provided host functions, hence it still logs things during genesis config building. crates: - name: polkadot bump: minor From e104a29b5558b2fdda0f64090db030af38e01c97 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Sun, 15 Jun 2025 16:27:58 +0200 Subject: [PATCH 07/11] prdoc Signed-off-by: Oliver Tale-Yazdi --- prdoc/pr_8857.prdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prdoc/pr_8857.prdoc b/prdoc/pr_8857.prdoc index 5863428b05053..62184c44ffcad 100644 --- a/prdoc/pr_8857.prdoc +++ b/prdoc/pr_8857.prdoc @@ -1,4 +1,4 @@ -title: "[FRAME]\_Custom log level for the runtime benchmarks" +title: "[FRAME] Custom log level for the runtime benchmarks" doc: - audience: Runtime Dev description: |- From fda8e36b93e582f3e1af972f15998684fcc9dcd7 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Sun, 15 Jun 2025 16:30:21 +0200 Subject: [PATCH 08/11] prdoc Signed-off-by: Oliver Tale-Yazdi --- prdoc/pr_8857.prdoc | 2 -- 1 file changed, 2 deletions(-) diff --git a/prdoc/pr_8857.prdoc b/prdoc/pr_8857.prdoc index 62184c44ffcad..b6f57c1cd2e8d 100644 --- a/prdoc/pr_8857.prdoc +++ b/prdoc/pr_8857.prdoc @@ -8,7 +8,5 @@ doc: - Set custom log level for runtime benchmarks that can be different form CLI level - Fix issue where old runtimes have a space in the pallet or instance name from breaking change in `quote` macro crates: -- name: polkadot - bump: minor - name: frame-benchmarking-cli bump: minor From 07057d73a092365a98d8f32c29036fc519e78fba Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Mon, 16 Jun 2025 14:47:22 +0200 Subject: [PATCH 09/11] Update substrate/utils/frame/benchmarking-cli/src/pallet/mod.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- substrate/utils/frame/benchmarking-cli/src/pallet/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substrate/utils/frame/benchmarking-cli/src/pallet/mod.rs b/substrate/utils/frame/benchmarking-cli/src/pallet/mod.rs index fdb7eb8cfd912..7297abca202d7 100644 --- a/substrate/utils/frame/benchmarking-cli/src/pallet/mod.rs +++ b/substrate/utils/frame/benchmarking-cli/src/pallet/mod.rs @@ -30,7 +30,7 @@ use sc_cli::{ use std::{fmt::Debug, path::PathBuf}; /// Logging target -const LOG_TARGET: &'static str = "polkadot_sdk_frame::benchmark::pallet"; +const LOG_TARGET: &'static str = "frame::benchmark::pallet"; // Add a more relaxed parsing for pallet names by allowing pallet directory names with `-` to be // used like crate names with `_` From a859efb9e564eada47cd45772adb9ae02ed78604 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Mon, 16 Jun 2025 15:31:15 +0200 Subject: [PATCH 10/11] Add Runtime log filtering Signed-off-by: Oliver Tale-Yazdi --- Cargo.lock | 5 +- Cargo.toml | 1 + .../utils/frame/benchmarking-cli/Cargo.toml | 1 + .../benchmarking-cli/src/pallet/command.rs | 2 +- .../benchmarking-cli/src/pallet/logging.rs | 46 ++++++++++++------- .../frame/benchmarking-cli/src/pallet/mod.rs | 2 +- 6 files changed, 37 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 59e70a7503c28..85dcefc8a5176 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5980,9 +5980,9 @@ dependencies = [ [[package]] name = "env_filter" -version = "0.1.0" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" +checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" dependencies = [ "log", "regex", @@ -6566,6 +6566,7 @@ dependencies = [ "cumulus-client-parachain-inherent", "cumulus-primitives-proof-size-hostfunction", "cumulus-test-runtime", + "env_filter", "frame-benchmarking", "frame-storage-access-test-runtime", "frame-support", diff --git a/Cargo.toml b/Cargo.toml index 414068a02ee62..a103f0e508b05 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -671,6 +671,7 @@ bitvec = { version = "1.0.1", default-features = false } blake2 = { version = "0.10.4", default-features = false } blake2b_simd = { version = "1.0.2", default-features = false } blake3 = { version = "1.5" } +env_filter = { version = "0.1.3" } bn = { package = "substrate-bn", version = "0.6", default-features = false } bounded-collections = { version = "0.2.3", default-features = false } bounded-vec = { version = "0.7" } diff --git a/substrate/utils/frame/benchmarking-cli/Cargo.toml b/substrate/utils/frame/benchmarking-cli/Cargo.toml index e4207c9030122..69dc9e1c5d283 100644 --- a/substrate/utils/frame/benchmarking-cli/Cargo.toml +++ b/substrate/utils/frame/benchmarking-cli/Cargo.toml @@ -73,6 +73,7 @@ subxt = { workspace = true, features = ["native"] } subxt-signer = { workspace = true, features = ["unstable-eth"] } thiserror = { workspace = true } thousands = { workspace = true } +env_filter = { workspace = true } [dev-dependencies] cumulus-test-runtime = { workspace = true, default-features = true } diff --git a/substrate/utils/frame/benchmarking-cli/src/pallet/command.rs b/substrate/utils/frame/benchmarking-cli/src/pallet/command.rs index 055deb0ae17eb..a0327ba69402e 100644 --- a/substrate/utils/frame/benchmarking-cli/src/pallet/command.rs +++ b/substrate/utils/frame/benchmarking-cli/src/pallet/command.rs @@ -254,7 +254,7 @@ impl PalletCmd { }; return self.output_from_results(&batches) } - super::logging::init(self.runtime_log); + super::logging::init(self.runtime_log.clone()); let state_handler = self.state_handler_from_cli::>(chain_spec)?; diff --git a/substrate/utils/frame/benchmarking-cli/src/pallet/logging.rs b/substrate/utils/frame/benchmarking-cli/src/pallet/logging.rs index cd843d2b4689e..f6a3c82d49dbb 100644 --- a/substrate/utils/frame/benchmarking-cli/src/pallet/logging.rs +++ b/substrate/utils/frame/benchmarking-cli/src/pallet/logging.rs @@ -16,7 +16,6 @@ // limitations under the License. use super::LOG_TARGET; -use log::LevelFilter; use sp_core::{LogLevelFilter, RuntimeInterfaceLogLevel}; use sp_runtime_interface::{ pass_by::{PassAs, PassFatPointerAndRead, ReturnAs}, @@ -25,28 +24,35 @@ use sp_runtime_interface::{ use std::cell::OnceCell; thread_local! { - /// Log level that the runtime will use. + /// Log level filter that the runtime will use. /// - /// Must be initialized by the host before invoking the runtime executor. - static RUNTIME_LOG_LEVEL: OnceCell = OnceCell::new(); + /// Must be initialized by the host before invoking the runtime executor. You may use `init` for + /// this or set it manually. The that can be set are either levels directly or filter like + // `warn,runtime=info`. + pub static RUNTIME_LOG: OnceCell = OnceCell::new(); } /// Init runtime logger with the following priority (high to low): /// - CLI argument /// - Environment variable /// - Default logger settings -pub fn init(arg: Option) { - let level = arg.unwrap_or_else(|| { +pub fn init(arg: Option) { + let filter_str = arg.unwrap_or_else(|| { if let Ok(env) = std::env::var("RUNTIME_LOG") { - env.parse().expect("Invalid level for RUNTIME_LOG") + env } else { - log::max_level() + log::max_level().to_string() } }); - RUNTIME_LOG_LEVEL.with(|cell| { - cell.set(level).expect("Can be set by host"); - log::info!(target: LOG_TARGET, "Initialized runtime log level to '{:?}'", level); + let filter = env_filter::Builder::new() + .try_parse(&filter_str) + .expect("Invalid runtime log filter") + .build(); + + RUNTIME_LOG.with(|cell| { + cell.set(filter).expect("Can be set by host"); + log::info!(target: LOG_TARGET, "Initialized runtime log filter to '{}'", filter_str); }); } @@ -59,17 +65,25 @@ pub trait Logging { target: PassFatPointerAndRead<&str>, message: PassFatPointerAndRead<&[u8]>, ) { - if let Ok(message) = core::str::from_utf8(message) { - log::log!(target: target, log::Level::from(level), "{}", message); - } else { + let Ok(message) = core::str::from_utf8(message) else { log::error!(target: LOG_TARGET, "Runtime tried to log invalid UTF-8 data"); + return; + }; + + let level = log::Level::from(level); + let metadata = log::MetadataBuilder::new().level(level).target(target).build(); + + if RUNTIME_LOG.with(|filter| filter.get().expect("Must be set by host").enabled(&metadata)) + { + log::log!(target: target, level, "{}", message); } } #[allow(dead_code)] fn max_level() -> ReturnAs { - RUNTIME_LOG_LEVEL - .with(|level| *level.get().expect("Must be set by host")) + RUNTIME_LOG + // .filter() gives us the max level of this filter + .with(|filter| filter.get().expect("Must be set by host").filter()) .into() } } diff --git a/substrate/utils/frame/benchmarking-cli/src/pallet/mod.rs b/substrate/utils/frame/benchmarking-cli/src/pallet/mod.rs index 7297abca202d7..7ac5c4436837a 100644 --- a/substrate/utils/frame/benchmarking-cli/src/pallet/mod.rs +++ b/substrate/utils/frame/benchmarking-cli/src/pallet/mod.rs @@ -196,7 +196,7 @@ pub struct PalletCmd { /// This will overwrite the `RUNTIME_LOG` environment variable. If neither is set, the CLI /// default set by `RUST_LOG` setting is used. #[arg(long)] - pub runtime_log: Option, + pub runtime_log: Option, /// Do not fail if there are unknown but also unused host functions in the runtime. #[arg(long)] From 581849ae258f37be0c1df64d1dcaea939819d691 Mon Sep 17 00:00:00 2001 From: "cmd[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 30 Jul 2025 12:33:15 +0000 Subject: [PATCH 11/11] Update from github-actions[bot] running command 'fmt' --- Cargo.toml | 2 +- substrate/utils/frame/benchmarking-cli/Cargo.toml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 96cfa23337602..ff4490ed4d5e7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -674,7 +674,6 @@ bitvec = { version = "1.0.1", default-features = false } blake2 = { version = "0.10.4", default-features = false } blake2b_simd = { version = "1.0.2", default-features = false } blake3 = { version = "1.5" } -env_filter = { version = "0.1.3" } bn = { package = "substrate-bn", version = "0.6", default-features = false } bounded-collections = { version = "0.3.2", default-features = false } bounded-vec = { version = "0.7" } @@ -788,6 +787,7 @@ either = { version = "1.8.1", default-features = false } emulated-integration-tests-common = { path = "cumulus/parachains/integration-tests/emulated/common", default-features = false } enumflags2 = { version = "0.7.11" } enumn = { version = "0.1.13" } +env_filter = { version = "0.1.3" } env_logger = { version = "0.11.2" } environmental = { version = "1.1.4", default-features = false } equivocation-detector = { path = "bridges/relays/equivocation" } diff --git a/substrate/utils/frame/benchmarking-cli/Cargo.toml b/substrate/utils/frame/benchmarking-cli/Cargo.toml index 69dc9e1c5d283..e58b403a03340 100644 --- a/substrate/utils/frame/benchmarking-cli/Cargo.toml +++ b/substrate/utils/frame/benchmarking-cli/Cargo.toml @@ -24,6 +24,7 @@ codec = { workspace = true, default-features = true } comfy-table = { workspace = true } cumulus-client-parachain-inherent = { workspace = true, default-features = true } cumulus-primitives-proof-size-hostfunction = { workspace = true, default-features = true } +env_filter = { workspace = true } frame-benchmarking = { workspace = true, default-features = true } frame-storage-access-test-runtime = { workspace = true, default-features = true } frame-support = { workspace = true, default-features = true } @@ -58,10 +59,10 @@ sp-database = { workspace = true, default-features = true } sp-externalities = { workspace = true, default-features = true } sp-genesis-builder = { workspace = true, default-features = true } sp-inherents = { workspace = true, default-features = true } -sp-runtime-interface = { workspace = true, default-features = true } sp-io = { workspace = true, default-features = true } sp-keystore = { workspace = true, default-features = true } sp-runtime = { workspace = true, default-features = true } +sp-runtime-interface = { workspace = true, default-features = true } sp-state-machine = { workspace = true, default-features = true } sp-storage = { workspace = true, default-features = true } sp-timestamp = { workspace = true, default-features = true } @@ -73,7 +74,6 @@ subxt = { workspace = true, features = ["native"] } subxt-signer = { workspace = true, features = ["unstable-eth"] } thiserror = { workspace = true } thousands = { workspace = true } -env_filter = { workspace = true } [dev-dependencies] cumulus-test-runtime = { workspace = true, default-features = true }