# log.rs - source
Source of the Rust file `crates/wasm/src/log.rs`.

Skip to main content

#
tlsn_wasm/
log.rs

    1//! WASM-specific logging initialization.
    2//!
    3//! Provides tsify-annotated types for the wasm_bindgen API surface and
    4//! delegates filtering to [`tlsn_sdk_core::logging`]. Console output is
    5//! handled by [`wasm_tracing::WASMLayer`] (no `web-sys` dependency).
    6
    7use serde::Deserialize;
    8use tracing::Level;
    9use tracing_subscriber::{filter::FilterFn, layer::SubscriberExt, util::SubscriberInitExt};
    10use tsify_next::Tsify;
    11use wasm_tracing::{WASMLayer, WASMLayerConfigBuilder};
    12
    13// ---------------------------------------------------------------------------
    14// Tsify wrapper types (wasm_bindgen API surface)
    15// ---------------------------------------------------------------------------
    16
    17#[derive(Debug, Default, Clone, Copy, Tsify, Deserialize)]
    18#[tsify(from_wasm_abi)]
    19pub enum LoggingLevel {
    20    Off,
    21    Trace,
    22    Debug,
    23    #[default]
    24    Info,
    25    Warn,
    26    Error,
    27}
    28
    29#[derive(Debug, Clone, Copy, Tsify, Deserialize)]
    30#[tsify(from_wasm_abi)]
    31pub enum SpanEvent {
    32    New,
    33    Close,
    34    Active,
    35}
    36
    37#[derive(Debug, Default, Clone, Tsify, Deserialize)]
    38#[tsify(from_wasm_abi)]
    39pub struct LoggingConfig {
    40    pub level: Option<LoggingLevel>,
    41    pub crate_filters: Option<Vec<CrateLogFilter>>,
    42    pub span_events: Option<Vec<SpanEvent>>,
    43}
    44
    45#[derive(Debug, Clone, Tsify, Deserialize)]
    46#[tsify(from_wasm_abi)]
    47pub struct CrateLogFilter {
    48    pub level: LoggingLevel,
    49    pub name: String,
    50}
    51
    52// ---------------------------------------------------------------------------
    53// Conversions to sdk-core types
    54// ---------------------------------------------------------------------------
    55
    56impl From<LoggingLevel> for tlsn_sdk_core::logging::LoggingLevel {
    57    fn from(val: LoggingLevel) -> Self {
    58        match val {
    59            LoggingLevel::Off => Self::Off,
    60            LoggingLevel::Trace => Self::Trace,
    61            LoggingLevel::Debug => Self::Debug,
    62            LoggingLevel::Info => Self::Info,
    63            LoggingLevel::Warn => Self::Warn,
    64            LoggingLevel::Error => Self::Error,
    65        }
    66    }
    67}
    68
    69impl From<SpanEvent> for tlsn_sdk_core::logging::SpanEvent {
    70    fn from(val: SpanEvent) -> Self {
    71        match val {
    72            SpanEvent::New => Self::New,
    73            SpanEvent::Close => Self::Close,
    74            SpanEvent::Active => Self::Active,
    75        }
    76    }
    77}
    78
    79impl From<CrateLogFilter> for tlsn_sdk_core::logging::CrateLogFilter {
    80    fn from(val: CrateLogFilter) -> Self {
    81        Self {
    82            level: val.level.into(),
    83            name: val.name,
    84        }
    85    }
    86}
    87
    88impl From<LoggingConfig> for tlsn_sdk_core::logging::LoggingConfig {
    89    fn from(val: LoggingConfig) -> Self {
    90        Self {
    91            level: val.level.map(Into::into),
    92            crate_filters: val
    93                .crate_filters
    94                .map(|v| v.into_iter().map(Into::into).collect()),
    95            span_events: val
    96                .span_events
    97                .map(|v| v.into_iter().map(Into::into).collect()),
    98        }
    99    }
    100}
    101
    102// ---------------------------------------------------------------------------
    103// Initialization
    104// ---------------------------------------------------------------------------
    105
    106pub(crate) fn init_logging(config: Option<LoggingConfig>) {
    107    // Convert to platform-agnostic config and build the filter.
    108    let core_config: tlsn_sdk_core::logging::LoggingConfig = config.unwrap_or_default().into();
    109
    110    let wasm_layer_config = WASMLayerConfigBuilder::new()
    111        .set_report_logs_in_timings(false) // avoid performance.mark (Node.js compat)
    112        .set_max_level(Level::TRACE) // let FilterFn handle actual filtering
    113        .build();
    114
    115    tracing_subscriber::registry()
    116        .with(FilterFn::new(tlsn_sdk_core::logging::filter(core_config)))
    117        .with(WASMLayer::new(wasm_layer_config))
    118        .init();
    119
    120    // WASM-specific panic hook.
    121    std::panic::set_hook(Box::new(|info| {
    122        tracing::error!("panic occurred: {:?}", info);
    123        console_error_panic_hook::hook(info);
    124    }));
    125}