Skip to main content

bitwarden_wasm_internal/
init.rs

1use std::num::NonZeroUsize;
2
3use bitwarden_logging::{FlightRecorderConfig, init_flight_recorder};
4use tracing::Level;
5use tracing_subscriber::{EnvFilter, layer::SubscriberExt as _, util::SubscriberInitExt as _};
6use tracing_web::MakeWebConsoleWriter;
7use wasm_bindgen::prelude::*;
8
9#[wasm_bindgen]
10pub enum LogLevel {
11    Trace,
12    Debug,
13    Info,
14    Warn,
15    Error,
16}
17
18fn convert_level(level: LogLevel) -> Level {
19    match level {
20        LogLevel::Trace => Level::TRACE,
21        LogLevel::Debug => Level::DEBUG,
22        LogLevel::Info => Level::INFO,
23        LogLevel::Warn => Level::WARN,
24        LogLevel::Error => Level::ERROR,
25    }
26}
27
28/// Initialize the SDK. Must be called before using any other API.
29/// Only the first invocation has effect; subsequent calls are ignored.
30///
31/// - `log_level`: Minimum level for console output. Defaults to `Info`.
32/// - `flight_recorder_level`: Minimum level for the flight recorder. Defaults to `Info`.
33/// - `flight_recorder_buffer_size`: Ring-buffer capacity for the flight recorder. Defaults to 1000.
34///   Pass `0` to disable the flight recorder entirely.
35#[wasm_bindgen]
36pub fn init_sdk(
37    log_level: Option<LogLevel>,
38    flight_recorder_level: Option<LogLevel>,
39    flight_recorder_buffer_size: Option<usize>,
40) {
41    console_error_panic_hook::set_once();
42
43    let log_level = convert_level(log_level.unwrap_or(LogLevel::Info));
44    let flight_recorder_level = convert_level(flight_recorder_level.unwrap_or(LogLevel::Info));
45    let flight_recorder_buffer_size =
46        NonZeroUsize::new(flight_recorder_buffer_size.unwrap_or(1000));
47
48    // If the flight recorder buffer size we get is zero, we disable the flight recorder entirely.
49    let flight_recorder_layer = flight_recorder_buffer_size.map(|size| {
50        let config = FlightRecorderConfig::new(size, flight_recorder_level);
51        init_flight_recorder(config)
52    });
53
54    let fmt = tracing_subscriber::fmt::layer()
55        .with_ansi(false) // only partially supported across browsers
56        .without_time() // time is not supported in wasm
57        .with_writer(MakeWebConsoleWriter::new()); // write events to the console
58
59    let filter = EnvFilter::builder()
60        .with_default_directive(log_level.into())
61        .from_env_lossy();
62
63    let perf_layer = cfg!(feature = "performance-tracing").then(|| {
64        tracing_web::performance_layer()
65            .with_details_from_fields(tracing_subscriber::fmt::format::Pretty::default())
66    });
67
68    let _ = tracing_subscriber::registry()
69        .with(flight_recorder_layer)
70        .with(fmt)
71        .with(filter)
72        .with(perf_layer)
73        .try_init();
74
75    #[cfg(feature = "dangerous-crypto-debug")]
76    tracing::warn!(
77        "Dangerous crypto debug features are enabled. THIS MUST NOT BE USED IN PRODUCTION BUILDS!!"
78    );
79}