From 4b739963c64b384d5d4db4a5b13daa317638688b Mon Sep 17 00:00:00 2001 From: oars Date: Wed, 9 Jul 2025 16:26:50 +0300 Subject: [PATCH] bin/explorer/explorerd: replace simplelog with tracing-subscriber for setting up logger for tests - replaced dynamic targets with static targets since tracing crate only supports setting static targets in the logger macros --- bin/explorer/explorerd/src/config.rs | 18 +++++-- bin/explorer/explorerd/src/error.rs | 11 +--- bin/explorer/explorerd/src/rpc/mod.rs | 11 ++-- .../explorerd/src/service/contracts.rs | 24 +++++++-- bin/explorer/explorerd/src/service/sync.rs | 35 +++++-------- .../explorerd/src/store/contract_metadata.rs | 19 +++++-- bin/explorer/explorerd/src/store/metrics.rs | 22 ++++++-- bin/explorer/explorerd/src/test_utils/mod.rs | 51 +++++++------------ 8 files changed, 106 insertions(+), 85 deletions(-) diff --git a/bin/explorer/explorerd/src/config.rs b/bin/explorer/explorerd/src/config.rs index ac0751c19..cdef889c9 100644 --- a/bin/explorer/explorerd/src/config.rs +++ b/bin/explorer/explorerd/src/config.rs @@ -221,9 +221,10 @@ impl FromStr for ExplorerNetworkConfig { mod tests { use std::path::Path; - use super::*; + use darkfi::util::logger::{setup_test_logger, Level}; + use tracing::warn; - use crate::test_utils::init_logger; + use super::*; /// Validates the functionality of initializing and interacting with `ExplorerConfig` /// loaded from a TOML file, ensuring correctness of the network-specific configurations. @@ -254,7 +255,18 @@ mod tests { ), ]; - init_logger(simplelog::LevelFilter::Info, vec!["sled", "runtime", "net"]); + if setup_test_logger( + &["sled", "runtime", "net"], + false, + Level::Info, + //Level::Verbose, + //Level::Debug, + //Level::Trace, + ) + .is_err() + { + warn!("Logger already initialized"); + } // Ensure the configuration file exists assert!(Path::new(CONFIG_PATH).exists()); diff --git a/bin/explorer/explorerd/src/error.rs b/bin/explorer/explorerd/src/error.rs index 5740233b2..d9d3cd788 100644 --- a/bin/explorer/explorerd/src/error.rs +++ b/bin/explorer/explorerd/src/error.rs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -use std::{fmt, sync::Arc}; +use std::sync::Arc; use tracing::error; @@ -82,12 +82,3 @@ pub fn server_error(e: &ExplorerdError, id: u16, msg: Option<&str>) -> JsonError JsonError::new(ErrorCode::ServerError(code), Some(message), id) } - -/// Logs and converts a database error into a [`DatabaseError`]. -/// This function ensures the error is logged contextually before being returned. -pub fn handle_database_error(target: &str, message: &str, error: impl fmt::Debug) -> Error { - let error_message = format!("{message}: {error:?}"); - let formatted_target = format!("explorerd::{target}"); - error!(target: &formatted_target, "{error_message}"); - Error::DatabaseError(error_message) -} diff --git a/bin/explorer/explorerd/src/rpc/mod.rs b/bin/explorer/explorerd/src/rpc/mod.rs index 08f1df0bc..291b590bf 100644 --- a/bin/explorer/explorerd/src/rpc/mod.rs +++ b/bin/explorer/explorerd/src/rpc/mod.rs @@ -314,13 +314,10 @@ impl Explorerd { } /// Auxiliary function that logs RPC request failures by generating a structured log message -/// containing the provided `req_method`, `params`, and `error` details. Constructs a log target -/// specific to the request method, formats the error message by stringifying the JSON parameters -/// and error, and performs the log operation without returning a value. +/// containing the provided `req_method`, `params`, and `error` details. +/// Formats the error message by stringifying the JSON parameters and error, +/// and performs the log operation without returning a value. fn log_request_failure(req_method: &str, params: &JsonValue, error: &JsonError) { - // Generate the log target based on request - let log_target = format!("explorerd::rpc::handle_request::{req_method}"); - // Stringify the params let params_stringified = match params.stringify() { Ok(params) => params, @@ -337,7 +334,7 @@ fn log_request_failure(req_method: &str, params: &JsonValue, error: &JsonError) let error_message = format!("RPC Request Failure: method: {req_method}, params: {params_stringified}, error: {error_stringified}"); // Log the error - error!(target: &log_target, "{error_message}"); + error!(target: "explorerd::rpc::handle_request", "{error_message}"); } /// Test module for validating API functions within this `mod.rs` file. It ensures that the core API diff --git a/bin/explorer/explorerd/src/service/contracts.rs b/bin/explorer/explorerd/src/service/contracts.rs index 174444c6d..b63d16ce0 100644 --- a/bin/explorer/explorerd/src/service/contracts.rs +++ b/bin/explorer/explorerd/src/service/contracts.rs @@ -318,14 +318,17 @@ pub fn untar_source(tar_bytes: &[u8]) -> Result> { mod tests { use std::{fs::File, io::Read, path::Path, sync::Arc}; + use darkfi::{ + util::logger::{setup_test_logger, Level}, + Error::Custom, + }; + use darkfi_sdk::crypto::MONEY_CONTRACT_ID; use tar::Archive; use tempdir::TempDir; - - use darkfi::Error::Custom; - use darkfi_sdk::crypto::MONEY_CONTRACT_ID; + use tracing::warn; use super::*; - use crate::{rpc::DarkfidRpcClient, test_utils::init_logger}; + use crate::rpc::DarkfidRpcClient; /// Tests the adding of [`ContractMetaData`] to the store by adding /// metadata, and verifying the inserted data matches the expected results. @@ -460,7 +463,18 @@ mod tests { /// and returning an initialized [`ExplorerService`]. fn setup() -> Result { // Initialize logger to show execution output - init_logger(simplelog::LevelFilter::Off, vec!["sled", "runtime", "net"]); + if setup_test_logger( + &["sled", "runtime", "net"], + false, + Level::Info, + //Level::Verbose, + //Level::Debug, + //Level::Trace, + ) + .is_err() + { + warn!("Logger already initialized"); + } // Create a temporary directory for sled DB let temp_dir = TempDir::new("test")?; diff --git a/bin/explorer/explorerd/src/service/sync.rs b/bin/explorer/explorerd/src/service/sync.rs index 59bb6882b..9bc5ed9a7 100644 --- a/bin/explorer/explorerd/src/service/sync.rs +++ b/bin/explorer/explorerd/src/service/sync.rs @@ -54,7 +54,7 @@ use darkfi::{ }; use darkfi_serial::deserialize_async; -use crate::{error::handle_database_error, service::ExplorerService, Explorerd}; +use crate::{service::ExplorerService, Explorerd}; impl ExplorerService { /// Synchronizes blocks between the explorer and a Darkfi blockchain node, ensuring @@ -70,11 +70,9 @@ impl ExplorerService { pub async fn sync_blocks(&self, reset: bool) -> darkfi::Result<()> { // Grab last synced block height from the explorer's database. let last_synced_block = self.last_block().map_err(|e| { - handle_database_error( - "rpc_blocks::sync_blocks", - "[sync_blocks] Retrieving last synced block failed", - e, - ) + let error_message = format!("[sync_blocks] Retrieving last synced block failed: {e:?}"); + error!(target: "explorerd::rpc_blocks::sync_blocks", "{}", error_message); + Error::DatabaseError(error_message) })?; // Grab the last confirmed block height and hash from the darkfi node @@ -136,21 +134,17 @@ impl ExplorerService { let block = match self.darkfid_client.get_block_by_height(current_height).await { Ok(r) => r, Err(e) => { - return Err(handle_database_error( - "rpc_blocks::sync_blocks", - "[sync_blocks] RPC client request failed", - e, - )) + let error_message = format!("[sync_blocks] RPC client request failed: {e:?}"); + error!(target: "explorerd::rpc_blocks::sync_blocks", "{}", error_message); + return Err(Error::DatabaseError(error_message)) } }; // Store the retrieved block in the explorer's database if let Err(e) = self.put_block(&block).await { - return Err(handle_database_error( - "rpc_blocks::sync_blocks", - "[sync_blocks] Put block failed", - e, - )); + let error_message = format!("[sync_blocks] Put block failed: {e:?}"); + error!(target: "explorerd::rpc_blocks::sync_blocks", "{}", error_message); + return Err(Error::DatabaseError(error_message)) }; debug!( @@ -233,11 +227,10 @@ impl ExplorerService { // Continue searching for blocks that do not exist on darkfi nodes Err(Error::JsonRpcError((-32121, _))) => (), Err(e) => { - return Err(handle_database_error( - "rpc_blocks::process_sync_blocks_reorg", - "[process_sync_blocks_reorg] RPC client request failed", - e, - )) + let error_message = + format!("[process_sync_blocks_reorg] RPC client request failed: {e:?}"); + error!(target: "explorerd::rpc_blocks::process_sync_blocks_reorg", "{}", error_message); + return Err(Error::DatabaseError(error_message)) } } } diff --git a/bin/explorer/explorerd/src/store/contract_metadata.rs b/bin/explorer/explorerd/src/store/contract_metadata.rs index 8a856421f..0b171d42d 100644 --- a/bin/explorer/explorerd/src/store/contract_metadata.rs +++ b/bin/explorer/explorerd/src/store/contract_metadata.rs @@ -309,10 +309,12 @@ impl ContractMetadataStoreOverlay { #[cfg(test)] /// This test module verifies the correct insertion and retrieval of contract metadata and source code. mod tests { - use super::*; - use crate::test_utils::init_logger; + use darkfi::util::logger::{setup_test_logger, Level}; use darkfi_sdk::crypto::MONEY_CONTRACT_ID; use sled_overlay::sled::Config; + use tracing::warn; + + use super::*; // Test source paths data const TEST_SOURCE_PATHS: &[&str] = &["test/source1.rs", "test/source2.rs"]; @@ -411,7 +413,18 @@ mod tests { /// and returning an initialized [`ContractMetaStore`]. fn setup() -> Result { // Initialize logger to show execution output - init_logger(simplelog::LevelFilter::Off, vec!["sled", "runtime", "net"]); + if setup_test_logger( + &["sled", "runtime", "net"], + false, + Level::Info, + //Level::Verbose, + //Level::Debug, + //Level::Trace + ) + .is_err() + { + warn!("Logger already initialized"); + } // Initialize an in-memory sled db instance let db = Config::new().temporary(true).open()?; diff --git a/bin/explorer/explorerd/src/store/metrics.rs b/bin/explorer/explorerd/src/store/metrics.rs index 90a0d9d2d..a71409bd9 100644 --- a/bin/explorer/explorerd/src/store/metrics.rs +++ b/bin/explorer/explorerd/src/store/metrics.rs @@ -863,16 +863,19 @@ impl GasMetricsKeySource for &str { /// This test module verifies the correct insertion, retrieval, and reset of metrics in the store. /// It covers adding metrics, searching metrics by time and transaction hash, and resetting metrics with specified heights. mod tests { - - use darkfi::util::time::DateTime; use std::{ str::FromStr, time::{Duration, SystemTime, UNIX_EPOCH}, }; + + use darkfi::util::{ + logger::{setup_test_logger, Level}, + time::DateTime, + }; use structopt::lazy_static::lazy_static; + use tracing::warn; use super::*; - use crate::test_utils::init_logger; /// Number of heights to simulate. const HEIGHT: u32 = 10; @@ -1202,7 +1205,18 @@ mod tests { /// creating a temporary database, and returning an initialized metrics store. fn setup() -> Result { // Initialize logger to show execution output - init_logger(simplelog::LevelFilter::Off, vec!["sled", "runtime", "net"]); + if setup_test_logger( + &["sled", "runtime", "net"], + false, + Level::Info, + //Level::Verbose, + //Level::Debug, + //Level::Trace, + ) + .is_err() + { + warn!("Logger already initialized"); + } // Create a temporary directory for the sled database let db = diff --git a/bin/explorer/explorerd/src/test_utils/mod.rs b/bin/explorer/explorerd/src/test_utils/mod.rs index 8d8cf62d2..ebf14136d 100644 --- a/bin/explorer/explorerd/src/test_utils/mod.rs +++ b/bin/explorer/explorerd/src/test_utils/mod.rs @@ -22,11 +22,15 @@ use lazy_static::lazy_static; use smol::Executor; use tempdir::TempDir; use tinyjson::JsonValue; +use tracing::warn; use url::Url; -use darkfi::rpc::{ - jsonrpc::{ErrorCode, JsonRequest, JsonResult}, - server::RequestHandler, +use darkfi::{ + rpc::{ + jsonrpc::{ErrorCode, JsonRequest, JsonResult}, + server::RequestHandler, + }, + util::logger::{setup_test_logger, Level}, }; use crate::Explorerd; @@ -36,34 +40,6 @@ lazy_static! { static ref EXPLORERD_INSTANCE: Mutex>> = Mutex::new(None); } -/// Initializes logging for test cases, which is useful for debugging issues encountered during testing. -/// The logger is configured based on the provided list of targets to ignore and the desired log level. -#[cfg(test)] -pub fn init_logger(log_level: simplelog::LevelFilter, ignore_targets: Vec<&str>) { - let mut cfg = simplelog::ConfigBuilder::new(); - - // Add targets to ignore - for target in ignore_targets { - cfg.add_filter_ignore(target.to_string()); - } - - // Set log level - cfg.set_target_level(log_level); - - // initialize the logger - if simplelog::TermLogger::init( - log_level, - cfg.build(), - simplelog::TerminalMode::Mixed, - simplelog::ColorChoice::Auto, - ) - .is_err() - { - // Print an error message if logger failed to initialize - eprintln!("Logger failed to initialize"); - } -} - #[cfg(test)] /// Sets up the `Explorerd` instance for testing, ensuring a single instance is initialized only /// once and shared among subsequent setup calls. @@ -72,7 +48,18 @@ pub fn setup() -> Arc { if instance.is_none() { // Initialize logger for the first time - init_logger(simplelog::LevelFilter::Off, vec!["sled", "runtime", "net"]); + if setup_test_logger( + &["sled", "runtime", "net"], + false, + Level::Info, + //Level::Verbose, + //Level::Debug, + //Level::Trace + ) + .is_err() + { + warn!("Logger already initialized"); + } // Prepare parameters for Explorerd::new let temp_dir = TempDir::new("explorerd").expect("Failed to create temp dir");