Skip to main content

acta_wasm/
lib.rs

1#![deny(unsafe_code)]
2
3#[cfg(target_arch = "wasm32")]
4use acta::Logger as NativeLogger;
5#[cfg(target_arch = "wasm32")]
6use tracing::Level;
7#[cfg(target_arch = "wasm32")]
8use wasm_bindgen::prelude::*;
9
10#[cfg(target_arch = "wasm32")]
11#[wasm_bindgen]
12pub struct Logger {
13    inner: Option<NativeLogger>,
14    output: acta::BufferedWriter,
15}
16
17#[cfg(target_arch = "wasm32")]
18#[wasm_bindgen]
19impl Logger {
20    #[wasm_bindgen(constructor)]
21    pub fn new(config_json: &str, capacity: u32) -> Result<Logger, JsValue> {
22        let output = acta::BufferedWriter::new(capacity as usize);
23        let config = acta::Config::from_json_with_writer(config_json, output.clone())
24            .map_err(|error| JsValue::from_str(&error.to_string()))?;
25        let inner =
26            NativeLogger::new(config).map_err(|error| JsValue::from_str(&error.to_string()))?;
27        Ok(Self {
28            inner: Some(inner),
29            output,
30        })
31    }
32
33    pub fn log(&self, level: u32, message: &str) -> Result<(), JsValue> {
34        let level = match level {
35            0 => Level::ERROR,
36            1 => Level::WARN,
37            2 => Level::INFO,
38            3 => Level::DEBUG,
39            4 => Level::TRACE,
40            _ => return Err(JsValue::from_str(&format!("invalid log level: {level}"))),
41        };
42        self.logger()?.log(level, message);
43        Ok(())
44    }
45
46    pub fn drain(&self, max_bytes: u32) -> Result<Vec<u8>, JsValue> {
47        self.logger()?;
48        Ok(self.output.drain(max_bytes as usize))
49    }
50
51    pub fn event(&self, event_json: &str) -> Result<(), JsValue> {
52        let logger = self.logger()?;
53        let event = serde_json::from_str(event_json)
54            .map_err(|error| JsValue::from_str(&error.to_string()))?;
55        logger
56            .event(&event)
57            .map_err(|error| JsValue::from_str(&error.to_string()))
58    }
59
60    #[wasm_bindgen(js_name = createSpan)]
61    pub fn create_span(&self, event_json: &str) -> Result<u32, JsValue> {
62        let logger = self.logger()?;
63        let event = serde_json::from_str(event_json)
64            .map_err(|error| JsValue::from_str(&error.to_string()))?;
65        logger
66            .create_span(&event)
67            .map_err(|error| JsValue::from_str(&error.to_string()))
68    }
69
70    #[wasm_bindgen(js_name = recordSpan)]
71    pub fn record_span(&self, id: u32, fields_json: &str) -> Result<(), JsValue> {
72        let logger = self.logger()?;
73        let fields =
74            serde_json::from_str::<serde_json::Map<String, serde_json::Value>>(fields_json)
75                .map_err(|error| JsValue::from_str(&error.to_string()))?;
76        logger
77            .record_span(id, &fields)
78            .map_err(|error| JsValue::from_str(&error.to_string()))
79    }
80
81    #[wasm_bindgen(js_name = closeSpan)]
82    pub fn close_span(&self, id: u32) -> Result<(), JsValue> {
83        self.logger()?
84            .close_span(id)
85            .map_err(|error| JsValue::from_str(&error.to_string()))
86    }
87
88    pub fn dropped(&self) -> Result<u64, JsValue> {
89        self.logger()?;
90        Ok(self.output.dropped())
91    }
92
93    #[wasm_bindgen(js_name = setFilter)]
94    pub fn set_filter(&self, filter: &str) -> Result<(), JsValue> {
95        self.logger()?
96            .set_filter(
97                filter
98                    .parse()
99                    .map_err(|_| JsValue::from_str("invalid filter"))?,
100            )
101            .map_err(|error| JsValue::from_str(&error.to_string()))
102    }
103
104    pub fn close(&mut self) {
105        self.inner.take();
106    }
107}
108
109#[cfg(target_arch = "wasm32")]
110impl Logger {
111    fn logger(&self) -> Result<&NativeLogger, JsValue> {
112        self.inner
113            .as_ref()
114            .ok_or_else(|| JsValue::from_str("Logger is closed"))
115    }
116}