diff --git a/integration_tests/tests/indexer_ffi_state_consistency.rs b/integration_tests/tests/indexer_ffi_state_consistency.rs index f84a3790..0a41c68c 100644 --- a/integration_tests/tests/indexer_ffi_state_consistency.rs +++ b/integration_tests/tests/indexer_ffi_state_consistency.rs @@ -8,7 +8,6 @@ use std::time::Duration; use anyhow::{Context as _, Result}; -use indexer_ffi::Runtime; use indexer_service_protocol::Account; use integration_tests::{ L2_TO_L1_TIMEOUT, TIME_TO_WAIT_FOR_BLOCK_SECONDS, private_mention, public_mention, @@ -102,11 +101,8 @@ fn indexer_ffi_state_consistency() -> Result<()> { info!("Waiting for indexer to parse blocks"); std::thread::sleep(L2_TO_L1_TIMEOUT); - // Safety: ctx runtime is valid for the lifetime of the returned Runtime - let runtime = unsafe { Runtime::from_borrowed(ctx.runtime()) }; let acc1_ind_state_ffi = unsafe { indexer_ffi_helpers::query_account( - &raw const runtime, &raw const indexer_ffi, (&ctx.ctx().existing_public_accounts()[0]).into(), ) @@ -119,7 +115,6 @@ fn indexer_ffi_state_consistency() -> Result<()> { let acc2_ind_state_ffi = unsafe { indexer_ffi_helpers::query_account( - &raw const runtime, &raw const indexer_ffi, (&ctx.ctx().existing_public_accounts()[1]).into(), ) diff --git a/integration_tests/tests/indexer_ffi_state_consistency_with_labels.rs b/integration_tests/tests/indexer_ffi_state_consistency_with_labels.rs index 34d5a4d7..fbc0b422 100644 --- a/integration_tests/tests/indexer_ffi_state_consistency_with_labels.rs +++ b/integration_tests/tests/indexer_ffi_state_consistency_with_labels.rs @@ -8,7 +8,6 @@ use std::time::Duration; use anyhow::Result; -use indexer_ffi::Runtime; use indexer_service_protocol::Account; use integration_tests::{L2_TO_L1_TIMEOUT, TIME_TO_WAIT_FOR_BLOCK_SECONDS, public_mention}; use log::info; @@ -75,11 +74,8 @@ fn indexer_ffi_state_consistency_with_labels() -> Result<()> { info!("Waiting for indexer to parse blocks"); std::thread::sleep(L2_TO_L1_TIMEOUT); - // Safety: ctx runtime is valid for the lifetime of the returned Runtime - let runtime = unsafe { Runtime::from_borrowed(ctx.runtime()) }; let acc1_ind_state_ffi = unsafe { indexer_ffi_helpers::query_account( - &raw const runtime, &raw const indexer_ffi, (&ctx.ctx().existing_public_accounts()[0]).into(), ) diff --git a/lez/indexer/ffi/indexer_ffi.h b/lez/indexer/ffi/indexer_ffi.h index 06953e39..04d33b33 100644 --- a/lez/indexer/ffi/indexer_ffi.h +++ b/lez/indexer/ffi/indexer_ffi.h @@ -464,18 +464,18 @@ struct PointerResult_Runtime__OperationStatus new_runtime(void); enum OperationStatus stop_indexer(struct IndexerServiceFFI *indexer); /** - * Initializes the FFI's logger. + * Initializes logging for the indexer at `level`. * - * Wires up `env_logger`, so the library's `log::*` output is controlled by the - * `RUST_LOG` environment variable (e.g. `RUST_LOG=info`). Without this, the - * FFI's log calls go nowhere — and since failures are otherwise reported only - * as numeric [`OperationStatus`](crate::errors::OperationStatus) codes, there - * is no other way to see *why* a call failed. + * - `level` is a null-terminated string (`off`/`error`/`warn`/`info`/`debug`/ `trace`, + * case-insensitive); null or unparseable falls back to `info`. * - * Safe to call multiple times and from any consumer: if a global logger is - * already set, the call is a no-op. + * Only the `indexer_ffi` and `indexer_core` targets are enabled! + * + * # Safety + * - `level` must be a valid null-terminated C string, or null. + * - First call to this function wins; subsequent calls are no-ops. */ -void init_logger(void); +void init_logger(const char *level); /** * # Safety diff --git a/lez/indexer/ffi/src/api/logging.rs b/lez/indexer/ffi/src/api/logging.rs index 207d4b61..34bc5f76 100644 --- a/lez/indexer/ffi/src/api/logging.rs +++ b/lez/indexer/ffi/src/api/logging.rs @@ -1,14 +1,33 @@ -/// Initializes the FFI's logger. +use std::ffi::{CStr, c_char}; + +use log::LevelFilter; + +/// Initializes logging for the indexer at `level`. /// -/// Wires up `env_logger`, so the library's `log::*` output is controlled by the -/// `RUST_LOG` environment variable (e.g. `RUST_LOG=info`). Without this, the -/// FFI's log calls go nowhere — and since failures are otherwise reported only -/// as numeric [`OperationStatus`](crate::errors::OperationStatus) codes, there -/// is no other way to see *why* a call failed. +/// - `level` is a null-terminated string (`off`/`error`/`warn`/`info`/`debug`/ `trace`, +/// case-insensitive); null or unparseable falls back to `info`. /// -/// Safe to call multiple times and from any consumer: if a global logger is -/// already set, the call is a no-op. +/// Only the `indexer_ffi` and `indexer_core` targets are enabled! +/// +/// # Safety +/// - `level` must be a valid null-terminated C string, or null. +/// - First call to this function wins; subsequent calls are no-ops. #[unsafe(no_mangle)] -pub extern "C" fn init_logger() { - let _ignore_me = env_logger::try_init(); +pub unsafe extern "C" fn init_logger(level: *const c_char) { + let level = if level.is_null() { + LevelFilter::Info + } else { + unsafe { CStr::from_ptr(level) } + .to_str() + .ok() + .and_then(|s| s.parse().ok()) + .unwrap_or(LevelFilter::Info) + }; + + env_logger::Builder::new() + .filter_level(LevelFilter::Off) + .filter_module("indexer_ffi", level) + .filter_module("indexer_core", level) + .try_init() + .ok(); }