Skip to content

Commit

Permalink
add ref doc for logging practices in FRAME (#4768)
Browse files Browse the repository at this point in the history
  • Loading branch information
kianenigma authored Jun 17, 2024
1 parent ae0b3bf commit 2f64381
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 2 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions docs/sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ pallet-babe = { path = "../../substrate/frame/babe" }

# Primitives
sp-io = { path = "../../substrate/primitives/io" }
sp-std = { path = "../../substrate/primitives/std" }
sp-tracing = { path = "../../substrate/primitives/tracing" }
sp-runtime-interface = { path = "../../substrate/primitives/runtime-interface" }
sp-api = { path = "../../substrate/primitives/api" }
sp-core = { path = "../../substrate/primitives/core" }
Expand Down
116 changes: 116 additions & 0 deletions docs/sdk/src/reference_docs/frame_logging.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
//! # FRAME Logging
//!
//! This reference docs briefly explores how to do logging and printing runtimes, mainly
//! FRAME-based.
//!
//! ## Using `println!`
//!
//! To recap, as with standard Rust, you can use `println!` _in your tests_, but it will only print
//! out if executed with `--nocapture`, or if the test panics.
//!
//! ```
//! fn it_print() {
//! println!("Hello, world!");
//! }
//! ```
//!
//! within the pallet, if you want to use the standard `println!`, it needs to be wrapped in
//! [`sp_std::if_std`]. Of course, this means that this print code is only available to you in the
//! `std` compiler flag, and never present in a wasm build.
//!
//! ```
//! // somewhere in your pallet. This is not a real pallet code.
//! mod pallet {
//! struct Pallet;
//! impl Pallet {
//! fn print() {
//! sp_std::if_std! {
//! println!("Hello, world!");
//! }
//! }
//! }
//! }
//! ```
//!
//! ## Using `log`
//!
//! First, ensure you are familiar with the `log` crate. In short, each log statement has:
//!
//! 1. `log-level`, signifying how important it is
//! 2. `log-target`, signifying to which component it belongs.
//!
//! Add log statements to your pallet as such:
//!
//! You can add the log crate to the `Cargo.toml` of the pallet.
//!
//! ```text
//! #[dependencies]
//! log = { version = "x.y.z", default-features = false }
//!
//! #[features]
//! std = [
//! // snip -- other pallets
//! "log/std"
//! ]
//! ```
//!
//! More conveniently, the `frame` umbrella crate re-exports the log crate as [`frame::log`].
//!
//! Then, the pallet can use this crate to emit log statements. In this statement, we use the info
//! level, and the target is `pallet-example`.
//!
//! ```
//! mod pallet {
//! struct Pallet;
//!
//! impl Pallet {
//! fn logs() {
//! frame::log::info!(target: "pallet-example", "Hello, world!");
//! }
//! }
//! }
//! ```
//!
//! This will in itself just emit the log messages, **but unless if captured by a logger, they will
//! not go anywhere**. [`sp_api`] provides a handy function to enable the runtime logging:
//!
//! ```
//! // in your test
//! fn it_also_prints() {
//! sp_api::init_runtime_logger();
//! // call into your pallet, and now it will print `log` statements.
//! }
//! ```
//!
//! Alternatively, you can use [`sp_tracing::try_init_simple`].
//!
//! `info`, `error` and `warn` logs are printed by default, but if you want lower level logs to also
//! be printed, you must to add the following compiler flag:
//!
//! ```text
//! RUST_LOG=pallet-example=trace cargo test
//! ```
//!
//! ## Enabling Logs in Production
//!
//! All logs from the runtime are emitted by default, but there is a feature flag in [`sp_api`],
//! called `disable-logging`, that can be used to disable all logs in the runtime. This is useful
//! for production chains to reduce the size and overhead of the wasm runtime.
#![doc = docify::embed!("../../substrate/primitives/api/src/lib.rs", init_runtime_logger)]
//!
//! Similar to the above, the proper `RUST_LOG` must also be passed to your compiler flag when
//! compiling the runtime.
//!
//! ## Log Target Prefixing
//!
//! Many [`crate::polkadot_sdk::frame_runtime`] pallets emit logs with log target `runtime::<name of
//! pallet>`, for example `runtime::system`. This then allows one to run a node with a wasm blob
//! compiled with `LOG_TARGET=runtime=debug`, which enables the log target of all pallets who's log
//! target starts with `runtime`.
//!
//! ## Low Level Primitives
//!
//! Under the hood, logging is another instance of host functions under the hood (as defined in
//! [`crate::reference_docs::wasm_meta_protocol`]). The runtime uses a set of host functions under
//! [`sp_io::logging`] and [`sp_io::misc`] to emit all logs and prints. You typically do not need to
//! use these APIs directly.
3 changes: 3 additions & 0 deletions docs/sdk/src/reference_docs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ pub mod frame_offchain_workers;
/// together.
pub mod frame_pallet_coupling;

/// Learn about how to do logging in FRAME-based runtimes.
pub mod frame_logging;

/// Learn about the Polkadot Umbrella crate that re-exports all other crates.
pub mod umbrella_crate;

Expand Down
5 changes: 3 additions & 2 deletions docs/sdk/src/reference_docs/umbrella_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@
//! `node` feature. For docs.rs the manifest contains specific configuration to make it show up
//! all re-exports.
//!
//! There is a specific `zepter` check in place to ensure that the features of the umbrella are
//! correctly configured. This check is run in CI and locally when running `zepter`.
//! There is a specific [`zepter`](https://github.com/ggwpez/zepter) check in place to ensure that
//! the features of the umbrella are correctly configured. This check is run in CI and locally when
//! running `zepter`.
//!
//! ## Generation
//!
Expand Down
1 change: 1 addition & 0 deletions substrate/primitives/api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ scale-info = { version = "2.11.1", default-features = false, features = [
] }
sp-metadata-ir = { path = "../metadata-ir", default-features = false, optional = true }
log = { workspace = true }
docify = { version = "0.2.1" }

[dev-dependencies]
sp-test-primitives = { path = "../test-primitives" }
Expand Down
1 change: 1 addition & 0 deletions substrate/primitives/api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,7 @@ pub trait ConstructRuntimeApi<Block: BlockT, C: CallApiAt<Block>> {
fn construct_runtime_api(call: &C) -> ApiRef<Self::RuntimeApi>;
}

#[docify::export]
/// Init the [`RuntimeLogger`](sp_runtime::runtime_logger::RuntimeLogger).
pub fn init_runtime_logger() {
#[cfg(not(feature = "disable-logging"))]
Expand Down

0 comments on commit 2f64381

Please sign in to comment.