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
This commit is contained in:
oars
2025-07-09 16:26:50 +03:00
parent 7b07425b38
commit 4b739963c6
8 changed files with 106 additions and 85 deletions

View File

@@ -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());

View File

@@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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)
}

View File

@@ -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

View File

@@ -318,14 +318,17 @@ pub fn untar_source(tar_bytes: &[u8]) -> Result<Vec<ContractSourceFile>> {
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<ExplorerService> {
// 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")?;

View File

@@ -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))
}
}
}

View File

@@ -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<ContractMetaStore> {
// 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()?;

View File

@@ -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<MetricsStore> {
// 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 =

View File

@@ -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<Option<Arc<Explorerd>>> = 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<Explorerd> {
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");