From 221b882c596463e14cb3fdb2a6ffea0d28f26428 Mon Sep 17 00:00:00 2001 From: Andrzej Ressel Date: Thu, 7 Mar 2024 02:26:05 +0100 Subject: [PATCH] Save --- .gitignore | 2 +- Cargo.lock | 86 +++------ Cargo.toml | 23 +-- logdy.txt | 95 ++++++++++ pulumi_rust/Cargo.toml | 11 +- pulumi_rust/src/grpc.rs | 1 + pulumi_rust/src/pulumi.rs | 51 ++++- pulumi_wasm/Cargo.toml | 2 + pulumi_wasm/src/bindings.rs | 296 ++++++++++++++++++++++++++--- pulumi_wasm/src/lib.rs | 27 ++- pulumi_wasm_main/Cargo.toml | 2 + pulumi_wasm_main/src/bindings.rs | 274 ++++++++++++++++++++++++++- pulumi_wasm_main/src/lib.rs | 11 +- run.bat | 1 + src/main.rs | 20 +- wasm_common/Cargo.toml | 18 ++ wasm_common/src/bindings.rs | 313 +++++++++++++++++++++++++++++++ wasm_common/src/lib.rs | 19 ++ wasm_common/src/logger.rs | 76 ++++++++ wits/world.wit | 25 ++- 20 files changed, 1200 insertions(+), 153 deletions(-) create mode 100644 logdy.txt create mode 100644 wasm_common/Cargo.toml create mode 100644 wasm_common/src/bindings.rs create mode 100644 wasm_common/src/lib.rs create mode 100644 wasm_common/src/logger.rs diff --git a/.gitignore b/.gitignore index b5ad9aa29..a02e380a1 100644 --- a/.gitignore +++ b/.gitignore @@ -20,7 +20,7 @@ devenv.local.nix /composed1.wat /composed2.wat /my-file -/pulumi-language-wasm/language-host.exe +/pulumi-language-wasm/pulumi-language-wasm.exe .idea/ diff --git a/Cargo.lock b/Cargo.lock index 0e6f1eb5c..0094cfa89 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -61,9 +61,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.12" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b09b5178381e0874812a9b157f7fe84982617e48f71f4e3235482775e5b540" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" dependencies = [ "anstyle", "anstyle-parse", @@ -391,9 +391,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.1" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c918d541ef2913577a0f9566e9ce27cb35b6df072075769e0b26cb5a554520da" +checksum = "b230ab84b0ffdf890d5a10abdbc8b83ae1c4918275daea1ab8801f71536b2651" dependencies = [ "clap_builder", "clap_derive", @@ -401,9 +401,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.1" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f3e7391dad68afb0c2ede1bf619f579a3dc9c2ec67f089baa397123a2f3d1eb" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" dependencies = [ "anstream", "anstyle", @@ -632,17 +632,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "derive_more" -version = "0.99.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "destructure_traitobject" version = "0.2.0" @@ -760,16 +749,6 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" -[[package]] -name = "flate2" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - [[package]] name = "fnv" version = "1.0.7" @@ -1430,11 +1409,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ "crc32fast", - "flate2", "hashbrown 0.14.3", "indexmap 2.1.0", "memchr", - "ruzstd", ] [[package]] @@ -1635,10 +1612,8 @@ version = "0.1.0" dependencies = [ "anyhow", "clap", - "futures", "log", "log4rs", - "object", "prost-types", "pulumi_rust", "tokio", @@ -1655,6 +1630,7 @@ dependencies = [ "log", "prost", "prost-types", + "regex", "rmp-serde", "serde", "serde_json", @@ -1690,6 +1666,7 @@ dependencies = [ "bitflags 2.4.2", "futures", "lazy_static", + "log", "once_cell", "prost", "prost-types", @@ -1701,6 +1678,7 @@ dependencies = [ "tonic", "tonic-build", "uuid", + "wasm_common", "wasmtime", "wasmtime-wasi", "wit-bindgen-rt", @@ -1714,6 +1692,7 @@ dependencies = [ "bitflags 2.4.2", "futures", "lazy_static", + "log", "once_cell", "prost", "prost-types", @@ -1725,6 +1704,7 @@ dependencies = [ "serde_json", "tonic", "uuid", + "wasm_common", "wasmtime", "wasmtime-wasi", "wit-bindgen-rt", @@ -1847,9 +1827,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.2" +version = "1.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick", "memchr", @@ -1859,9 +1839,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", @@ -1939,17 +1919,6 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" -[[package]] -name = "ruzstd" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58c4eb8a81997cf040a091d1f7e1938aeab6749d3a0dfa73af43cdc32393483d" -dependencies = [ - "byteorder", - "derive_more", - "twox-hash", -] - [[package]] name = "ryu" version = "1.0.16" @@ -2094,12 +2063,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "strsim" version = "0.11.0" @@ -2469,16 +2432,6 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" -[[package]] -name = "twox-hash" -version = "1.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" -dependencies = [ - "cfg-if", - "static_assertions", -] - [[package]] name = "typemap-ors" version = "1.0.0" @@ -2685,6 +2638,15 @@ dependencies = [ "leb128", ] +[[package]] +name = "wasm_common" +version = "0.1.0" +dependencies = [ + "log", + "uuid", + "wit-bindgen-rt", +] + [[package]] name = "wasmparser" version = "0.121.0" diff --git a/Cargo.toml b/Cargo.toml index 26f09580b..36ea5f216 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,24 +7,22 @@ edition = "2021" [dependencies] pulumi_rust = { path = "pulumi_rust" } -tokio = { version = "1.36.0", features = ["sync", "macros", "io-util", "rt", "time"] } -futures = "0.3.30" -log = "0.4" -anyhow = "1.0.79" -tonic = "0.11.0" -object = "0.32.2" -prost-types = "0.12.3" -clap = { version = "4.5.1", features = ["derive"] } +tokio.workspace = true +log.workspace = true +anyhow.workspace = true +tonic = { workspace = true, default-features = true } +prost-types.workspace = true +clap.workspace = true log4rs.workspace = true [workspace] - members = [ "pulumi_rust", "pulumi_wasm", "pulumi_wasm_random", "pulumi_wasm_main", "pulumi_rust_wasm", + "wasm_common" ] [workspace.dependencies] @@ -48,6 +46,9 @@ wasmtime-wasi = "18.0.2" tonic-build = "0.11.0" async-trait = "0.1.77" tonic-web = "0.11.0" -log = { version = "0.4.21", features = [] } +log = { version = "0.4.21", features = ["kv"] } tracing-subscriber = "0.3.18" -log4rs = "1.3.0" \ No newline at end of file +log4rs = "1.3.0" +tokio = { version = "1.36.0", features = ["sync", "macros", "io-util", "rt", "time"] } +clap = { version = "4.5.1", features = ["derive"] } +regex = "1.10.3" diff --git a/logdy.txt b/logdy.txt new file mode 100644 index 000000000..f629efc2c --- /dev/null +++ b/logdy.txt @@ -0,0 +1,95 @@ +{ + "name": "main", + "columns": [ + { + "id": "727320", + "name": "raw", + "handlerTsCode": "(line: Message): CellHandler => {\n return { text: line.content || \"-\"}\n }", + "idx": 0, + "width": 150, + "hidden": true + }, + { + "id": "988595", + "name": "time", + "handlerTsCode": "(line: Message): CellHandler => {\n return { text: line.json_content['time'] }\n}", + "idx": 1, + "width": 150 + }, + { + "id": "113882", + "name": "level", + "handlerTsCode": "(line: Message): CellHandler => {\n return { text: line.json_content['level'] }\n}", + "idx": 2, + "width": 57 + }, + { + "id": "895087", + "name": "module_path", + "handlerTsCode": "(line: Message): CellHandler => {\n return { text: line.json_content['module_path'] }\n}", + "idx": 4, + "width": 150 + }, + { + "id": "517706", + "name": "file", + "handlerTsCode": "(line: Message): CellHandler => {\n return { text: line.json_content['file'] }\n}", + "idx": 5, + "width": 141, + "faceted": false + }, + { + "id": "913995", + "name": "line", + "handlerTsCode": "(line: Message): CellHandler => {\n return { text: line.json_content['line'] }\n}", + "idx": 6, + "width": 48, + "faceted": false + }, + { + "id": "050721", + "name": "message", + "handlerTsCode": "(line: Message): CellHandler => {\n return { text: line.json_content['message'] }\n}", + "idx": 3, + "width": 257 + }, + { + "id": "992824", + "name": "target", + "handlerTsCode": "(line: Message): CellHandler => {\n return { text: line.json_content['target'] }\n}", + "idx": 7, + "width": 150, + "hidden": true + }, + { + "id": "094904", + "name": "thread", + "handlerTsCode": "(line: Message): CellHandler => {\n return { text: line.json_content['thread'] }\n}", + "idx": 8, + "width": 150, + "hidden": true + }, + { + "id": "110491", + "name": "thread_id", + "handlerTsCode": "(line: Message): CellHandler => {\n return { text: line.json_content['thread_id'] }\n}", + "idx": 9, + "width": 150, + "hidden": true + }, + { + "id": "408132", + "name": "mdc", + "handlerTsCode": "(line: Message): CellHandler => {\n return { text: line.json_content['mdc'] }\n}", + "idx": 10, + "width": 150, + "hidden": true, + "faceted": false + } + ], + "settings": { + "leftColWidth": 300, + "maxMessages": 1000, + "middlewares": [] + } +} \ No newline at end of file diff --git a/pulumi_rust/Cargo.toml b/pulumi_rust/Cargo.toml index 6b483a32b..6a675c1df 100644 --- a/pulumi_rust/Cargo.toml +++ b/pulumi_rust/Cargo.toml @@ -9,7 +9,7 @@ edition = "2021" tonic-web.workspace = true prost.workspace = true prost-types.workspace = true -tonic.workspace = true +tonic = { workspace = true, default-features = true } log.workspace = true uuid.workspace = true tracing-subscriber.workspace = true @@ -21,14 +21,7 @@ rmp-serde.workspace = true serde_json.workspace = true futures.workspace = true async-trait.workspace = true +regex.workspace = true [build-dependencies] tonic-build.workspace = true - -# -#[package.metadata.component] -#package = "component:pulumi-wasm" -# -#[package.metadata.component.target] -#path = "../wits/world.wit" -#world = "pulumi-wasm" \ No newline at end of file diff --git a/pulumi_rust/src/grpc.rs b/pulumi_rust/src/grpc.rs index 8a3d273f8..329ddf4b9 100644 --- a/pulumi_rust/src/grpc.rs +++ b/pulumi_rust/src/grpc.rs @@ -1 +1,2 @@ +use tonic::*; tonic::include_proto!("pulumirpc"); diff --git a/pulumi_rust/src/pulumi.rs b/pulumi_rust/src/pulumi.rs index b1c916f79..52edebc7d 100644 --- a/pulumi_rust/src/pulumi.rs +++ b/pulumi_rust/src/pulumi.rs @@ -8,11 +8,13 @@ use std::collections::HashMap; use std::fs::OpenOptions; use std::ops::DerefMut; use std::rc::Rc; -use tonic::async_trait; use wasmtime::component::{Component, Instance, Linker, ResourceTable}; use wasmtime::Store; use wasmtime_wasi::preview2::{WasiCtx, WasiCtxBuilder, WasiView}; use std::io::prelude::*; +use async_trait::async_trait; +use log::Log; +use regex::Regex; pub struct Pulumi { plugin: Main, @@ -50,18 +52,35 @@ impl server::component::pulumi_wasm::external_world::Host for MyState { } } +fn extract_file_name(path: &String) -> String { + let file_name_regex: Regex = Regex::new(r"^.*src\\(.*)").unwrap(); + file_name_regex.captures(path).unwrap().get(1).unwrap().as_str().to_string() +} + #[async_trait] impl crate::pulumi::server::component::pulumi_wasm::log::Host for MyState { - async fn log(&mut self, message: String) -> wasmtime::Result<()> { - let mut file = OpenOptions::new() - .create(true) - .write(true) - .append(true) - .open("my-file") - .unwrap(); + async fn log(&mut self, content: crate::pulumi::server::component::pulumi_wasm::log::Content) -> wasmtime::Result<()> { + let normalized_file_name = content.file.map(|s| extract_file_name(&s)); + + log::logger().log(&log::Record::builder() + .metadata(log::Metadata::builder() + .level(match content.level { + crate::pulumi::server::component::pulumi_wasm::log::Level::Trace => log::Level::Trace, + crate::pulumi::server::component::pulumi_wasm::log::Level::Debug => log::Level::Debug, + crate::pulumi::server::component::pulumi_wasm::log::Level::Info => log::Level::Info, + crate::pulumi::server::component::pulumi_wasm::log::Level::Error => log::Level::Error, + crate::pulumi::server::component::pulumi_wasm::log::Level::Warn => log::Level::Warn, + }) + .target(&content.target) + .build() + ) + .args(format_args!("{}", content.args)) + .module_path(content.module_path.as_deref()) + .file(normalized_file_name.as_deref()) + .line(content.line) + .key_values(&content.key_values.iter().map(|(k, v)| (k.as_str(), v.as_str())).collect::>()) + .build()); - writeln!(file, "{:?}", message)?; - // println!("{}", message); Ok(()) } } @@ -169,3 +188,15 @@ impl Pulumi { Ok(()) } } + +#[cfg(test)] +mod test { + use crate::pulumi::extract_file_name; + + #[test] + fn should_extract_file_name() { + assert_eq!(extract_file_name(&"src\\main.rs".to_string()), "main.rs"); + assert_eq!(extract_file_name(&"pulumi_wasm\\src\\lib.rs".to_string()), "lib.rs"); + } + +} \ No newline at end of file diff --git a/pulumi_wasm/Cargo.toml b/pulumi_wasm/Cargo.toml index bfe791b59..cbea27853 100644 --- a/pulumi_wasm/Cargo.toml +++ b/pulumi_wasm/Cargo.toml @@ -24,6 +24,8 @@ rmpv.workspace = true serde.workspace = true tonic.workspace = true serde_json.workspace = true +wasm_common = { path = "../wasm_common" } +log.workspace = true [build-dependencies] tonic-build.workspace = true diff --git a/pulumi_wasm/src/bindings.rs b/pulumi_wasm/src/bindings.rs index 60cb879a9..b49c1e148 100644 --- a/pulumi_wasm/src/bindings.rs +++ b/pulumi_wasm/src/bindings.rs @@ -10,25 +10,206 @@ pub mod component { #[cfg(target_arch = "wasm32")] static __FORCE_SECTION_REF: fn() = super::super::super::__link_custom_section_describing_imports; + use super::super::super::_rt; + #[repr(u8)] + #[derive(Clone, Copy, Eq, PartialEq)] + pub enum Level { + Trace, + Debug, + Info, + Warn, + Error, + } + impl ::core::fmt::Debug for Level { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + match self { + Level::Trace => f.debug_tuple("Level::Trace").finish(), + Level::Debug => f.debug_tuple("Level::Debug").finish(), + Level::Info => f.debug_tuple("Level::Info").finish(), + Level::Warn => f.debug_tuple("Level::Warn").finish(), + Level::Error => f.debug_tuple("Level::Error").finish(), + } + } + } + + impl Level { + pub(crate) unsafe fn _lift(val: u8) -> Level { + if !cfg!(debug_assertions) { + return ::core::mem::transmute(val); + } + + match val { + 0 => Level::Trace, + 1 => Level::Debug, + 2 => Level::Info, + 3 => Level::Warn, + 4 => Level::Error, + + _ => panic!("invalid enum discriminant"), + } + } + } + + #[derive(Clone)] + pub struct Content { + pub level: Level, + pub target: _rt::String, + pub args: _rt::String, + pub module_path: Option<_rt::String>, + pub file: Option<_rt::String>, + pub line: Option, + pub key_values: _rt::Vec<(_rt::String, _rt::String)>, + } + impl ::core::fmt::Debug for Content { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("Content") + .field("level", &self.level) + .field("target", &self.target) + .field("args", &self.args) + .field("module-path", &self.module_path) + .field("file", &self.file) + .field("line", &self.line) + .field("key-values", &self.key_values) + .finish() + } + } #[allow(unused_unsafe, clippy::all)] - pub fn log(message: &str) { + pub fn log(content: &Content) { unsafe { - let vec0 = message; - let ptr0 = vec0.as_ptr().cast::(); - let len0 = vec0.len(); + let Content { + level: level0, + target: target0, + args: args0, + module_path: module_path0, + file: file0, + line: line0, + key_values: key_values0, + } = content; + let vec1 = target0; + let ptr1 = vec1.as_ptr().cast::(); + let len1 = vec1.len(); + let vec2 = args0; + let ptr2 = vec2.as_ptr().cast::(); + let len2 = vec2.len(); + let (result4_0, result4_1, result4_2) = match module_path0 { + Some(e) => { + let vec3 = e; + let ptr3 = vec3.as_ptr().cast::(); + let len3 = vec3.len(); + + (1i32, ptr3.cast_mut(), len3) + } + None => (0i32, ::core::ptr::null_mut(), 0usize), + }; + let (result6_0, result6_1, result6_2) = match file0 { + Some(e) => { + let vec5 = e; + let ptr5 = vec5.as_ptr().cast::(); + let len5 = vec5.len(); + + (1i32, ptr5.cast_mut(), len5) + } + None => (0i32, ::core::ptr::null_mut(), 0usize), + }; + let (result7_0, result7_1) = match line0 { + Some(e) => (1i32, _rt::as_i32(e)), + None => (0i32, 0i32), + }; + let vec11 = key_values0; + let len11 = vec11.len(); + let layout11 = + _rt::alloc::Layout::from_size_align_unchecked(vec11.len() * 16, 4); + let result11 = if layout11.size() != 0 { + let ptr = _rt::alloc::alloc(layout11).cast::(); + if ptr.is_null() { + _rt::alloc::handle_alloc_error(layout11); + } + ptr + } else { + { + ::core::ptr::null_mut() + } + }; + for (i, e) in vec11.into_iter().enumerate() { + let base = result11.add(i * 16); + { + let (t8_0, t8_1) = e; + let vec9 = t8_0; + let ptr9 = vec9.as_ptr().cast::(); + let len9 = vec9.len(); + *base.add(4).cast::() = len9; + *base.add(0).cast::<*mut u8>() = ptr9.cast_mut(); + let vec10 = t8_1; + let ptr10 = vec10.as_ptr().cast::(); + let len10 = vec10.len(); + *base.add(12).cast::() = len10; + *base.add(8).cast::<*mut u8>() = ptr10.cast_mut(); + } + } #[cfg(target_arch = "wasm32")] #[link(wasm_import_module = "component:pulumi-wasm/log@0.1.0")] extern "C" { #[link_name = "log"] - fn wit_import(_: *mut u8, _: usize); + fn wit_import( + _: i32, + _: *mut u8, + _: usize, + _: *mut u8, + _: usize, + _: i32, + _: *mut u8, + _: usize, + _: i32, + _: *mut u8, + _: usize, + _: i32, + _: i32, + _: *mut u8, + _: usize, + ); } #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: *mut u8, _: usize) { + fn wit_import( + _: i32, + _: *mut u8, + _: usize, + _: *mut u8, + _: usize, + _: i32, + _: *mut u8, + _: usize, + _: i32, + _: *mut u8, + _: usize, + _: i32, + _: i32, + _: *mut u8, + _: usize, + ) { unreachable!() } - wit_import(ptr0.cast_mut(), len0); + wit_import( + level0.clone() as i32, + ptr1.cast_mut(), + len1, + ptr2.cast_mut(), + len2, + result4_0, + result4_1, + result4_2, + result6_0, + result6_1, + result6_2, + result7_0, + result7_1, + result11, + len11, + ); + if layout11.size() != 0 { + _rt::alloc::dealloc(result11.cast(), layout11); + } } } } @@ -796,6 +977,79 @@ pub mod exports { } } mod _rt { + pub use alloc_crate::string::String; + pub use alloc_crate::vec::Vec; + + pub fn as_i32(t: T) -> i32 { + t.as_i32() + } + + pub trait AsI32 { + fn as_i32(self) -> i32; + } + + impl<'a, T: Copy + AsI32> AsI32 for &'a T { + fn as_i32(self) -> i32 { + (*self).as_i32() + } + } + + impl AsI32 for i32 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + + impl AsI32 for u32 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + + impl AsI32 for i16 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + + impl AsI32 for u16 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + + impl AsI32 for i8 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + + impl AsI32 for u8 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + + impl AsI32 for char { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + + impl AsI32 for usize { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + pub use alloc_crate::alloc; pub unsafe fn bool_lift(val: u8) -> bool { if cfg!(debug_assertions) { match val { @@ -807,7 +1061,6 @@ mod _rt { ::core::mem::transmute::(val) } } - pub use alloc_crate::vec::Vec; use core::fmt; use core::marker; @@ -910,7 +1163,6 @@ mod _rt { let layout = alloc::Layout::from_size_align_unchecked(size, align); alloc::dealloc(ptr as *mut u8, layout); } - pub use alloc_crate::string::String; pub unsafe fn string_lift(bytes: Vec) -> String { if cfg!(debug_assertions) { String::from_utf8(bytes).unwrap() @@ -918,7 +1170,6 @@ mod _rt { String::from_utf8_unchecked(bytes) } } - pub use alloc_crate::alloc; extern crate alloc as alloc_crate; } @@ -955,17 +1206,20 @@ pub(crate) use __export_pulumi_wasm_impl as export; #[cfg(target_arch = "wasm32")] #[link_section = "component-type:wit-bindgen:0.20.0:pulumi-wasm:encoded world"] #[doc(hidden)] -pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 1212] = *b"\ -\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07\xba\x08\x01A\x02\x01\ -A\x0b\x01B\x02\x01@\x01\x07messages\x01\0\x04\0\x03log\x01\0\x03\x01\x1fcomponen\ -t:pulumi-wasm/log@0.1.0\x05\0\x01B\x05\x01@\0\0\x7f\x04\0\x0dis-in-preview\x01\0\ -\x01p}\x01@\x01\x07request\x01\0\x01\x04\0\x11register-resource\x01\x02\x03\x01*\ -component:pulumi-wasm/external-world@0.1.0\x05\x01\x01B\x16\x04\0\x06output\x03\x01\ -\x01p}\x01i\0\x01@\x01\x05value\x01\0\x02\x04\0\x13[constructor]output\x01\x03\x01\ -h\0\x01@\x02\x04self\x04\x0dfunction-names\0\x02\x04\0\x12[method]output.map\x01\ -\x05\x01k\x01\x01@\x01\x04self\x04\0\x06\x04\0\x12[method]output.get\x01\x07\x01\ -@\x02\x04self\x04\x05fields\0\x02\x04\0\x18[method]output.get-field\x01\x08\x01@\ -\x01\x04self\x04\0s\x04\0\x17[method]output.get-type\x01\x09\x01@\x01\x04self\x04\ +pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 1342] = *b"\ +\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07\xbc\x09\x01A\x02\x01\ +A\x0b\x01B\x0a\x01m\x05\x05TRACE\x05DEBUG\x04INFO\x04WARN\x05ERROR\x04\0\x05leve\ +l\x03\0\0\x01ks\x01ky\x01o\x02ss\x01p\x04\x01r\x07\x05level\x01\x06targets\x04ar\ +gss\x0bmodule-path\x02\x04file\x02\x04line\x03\x0akey-values\x05\x04\0\x07conten\ +t\x03\0\x06\x01@\x01\x07content\x07\x01\0\x04\0\x03log\x01\x08\x03\x01\x1fcompon\ +ent:pulumi-wasm/log@0.1.0\x05\0\x01B\x05\x01@\0\0\x7f\x04\0\x0dis-in-preview\x01\ +\0\x01p}\x01@\x01\x07request\x01\0\x01\x04\0\x11register-resource\x01\x02\x03\x01\ +*component:pulumi-wasm/external-world@0.1.0\x05\x01\x01B\x16\x04\0\x06output\x03\ +\x01\x01p}\x01i\0\x01@\x01\x05value\x01\0\x02\x04\0\x13[constructor]output\x01\x03\ +\x01h\0\x01@\x02\x04self\x04\x0dfunction-names\0\x02\x04\0\x12[method]output.map\ +\x01\x05\x01k\x01\x01@\x01\x04self\x04\0\x06\x04\0\x12[method]output.get\x01\x07\ +\x01@\x02\x04self\x04\x05fields\0\x02\x04\0\x18[method]output.get-field\x01\x08\x01\ +@\x01\x04self\x04\0s\x04\0\x17[method]output.get-type\x01\x09\x01@\x01\x04self\x04\ \0\x02\x04\0\x18[method]output.duplicate\x01\x0a\x01@\0\0s\x04\0\x10describe-out\ puts\x01\x0b\x01@\0\0\x7f\x04\0\x0fnon-done-exists\x01\x0c\x04\0\x0fcombine-outp\ uts\x01\x0c\x04\x01,component:pulumi-wasm/output-interface@0.1.0\x05\x02\x02\x03\ diff --git a/pulumi_wasm/src/lib.rs b/pulumi_wasm/src/lib.rs index d16f2068b..5e6685722 100644 --- a/pulumi_wasm/src/lib.rs +++ b/pulumi_wasm/src/lib.rs @@ -4,6 +4,7 @@ use std::fmt::Formatter; use std::ops::Deref; use futures::SinkExt; use lazy_static::lazy_static; +use log::{info, log}; use prost::Message; use prost_types::value::Kind; use rmpv::{Utf8String, Value}; @@ -35,6 +36,7 @@ impl output_interface::Guest for Component { type Output = Output; fn describe_outputs() -> String { + wasm_common::setup_logger(); let outputs = access_map() .iter() .map(|o| { @@ -49,6 +51,7 @@ impl output_interface::Guest for Component { } fn non_done_exists() -> bool { + wasm_common::setup_logger(); for o in access_map() { let ref_cell = o.borrow(); let content = ref_cell.deref(); @@ -63,6 +66,7 @@ impl output_interface::Guest for Component { } fn combine_outputs() -> bool { + wasm_common::setup_logger(); let outputs = access_map(); let mut changed = false; @@ -72,7 +76,7 @@ impl output_interface::Guest for Component { let new_value = match content { OutputContent::Func(refcells, f) => { - log("Found func"); + info!("Found func"); let data = refcells.iter().flat_map(|r| { let ref_cell = r.borrow(); let content = ref_cell.deref(); @@ -85,10 +89,10 @@ impl output_interface::Guest for Component { }).collect::>(); if (data.len() == refcells.len()) { - log("Map"); + info!("Map"); Some(f(data)) } else { - log("Cannot map"); + info!("Cannot map"); None } } @@ -125,12 +129,14 @@ impl Debug for Output { impl GuestOutput for Output { fn new(value: Vec) -> Self { + wasm_common::setup_logger(); let value = rmpv::decode::read_value(&mut value.as_slice()).unwrap(); let cell = output::create_new(value); Output { output: cell, tags: vec![] } } fn map(&self, function_name: String) -> WasmOutput { + wasm_common::setup_logger(); let function_id = FunctionId::from_string(&function_name); let function_source = FunctionSource::from_str("source"); let output = output::map_external(function_id, function_source, self.output.clone()); @@ -138,6 +144,7 @@ impl GuestOutput for Output { } fn get(&self) -> Option> { + wasm_common::setup_logger(); let ref_cell = self.output.borrow(); let content = ref_cell.deref(); @@ -154,6 +161,7 @@ impl GuestOutput for Output { } fn get_field(&self, field: String) -> WasmOutput { + wasm_common::setup_logger(); let o = output::map_internal(vec![self.output.clone()], move |v| { let v = v[0].clone(); @@ -184,6 +192,7 @@ impl GuestOutput for Output { } fn get_type(&self) -> String { + wasm_common::setup_logger(); let ref_cell = self.output.borrow(); let content = ref_cell.deref(); match content { @@ -195,6 +204,7 @@ impl GuestOutput for Output { } fn duplicate(&self) -> WasmOutput { + wasm_common::setup_logger(); WasmOutput::new(Output { output: self.output.clone(), tags: self.tags.clone(), @@ -204,6 +214,7 @@ impl GuestOutput for Output { impl function_reverse_callback::Guest for Component { fn get_functions(source: String) -> Vec { + wasm_common::setup_logger(); let function_source = &FunctionSource::from_string(&source); access_map() .iter() @@ -212,10 +223,10 @@ impl function_reverse_callback::Guest for Component { match f1 { OutputContent::Mapped(id, s, prev) if s == function_source => { - log("Found mapped"); + info!("Found mapped"); match &*prev.borrow() { OutputContent::Done(v) => { - log("Found value"); + info!("Found value"); let mut vec = vec![]; rmpv::encode::write_value(&mut vec, v).unwrap(); Some(FunctionInvocationRequest { @@ -227,7 +238,7 @@ impl function_reverse_callback::Guest for Component { OutputContent::Mapped(_, _, _) | OutputContent::Func(_, _) | OutputContent::Nothing => { - log("Value not found"); + info!("Value not found"); None }, } @@ -242,6 +253,7 @@ impl function_reverse_callback::Guest for Component { } fn set_functions(results: Vec) { + wasm_common::setup_logger(); for x in results { let value = rmpv::decode::read_value(&mut x.value.as_slice()).unwrap(); let borrowed = &x.id.get::().output; @@ -264,6 +276,7 @@ fn messagepack_to_protoc(v: &Value) -> prost_types::Value { impl register_interface::Guest for Component { fn register(request: RegisterResourceRequest) -> WasmOutput { + wasm_common::setup_logger(); let values = request.object.iter().map(|o| o.value.get::().output.clone()).collect::>(); let names = request.object.iter().map(|o| o.name.clone()).collect::>(); @@ -321,7 +334,7 @@ impl register_interface::Guest for Component { let result = grpc::RegisterResourceResponse::decode(&mut result_vec.as_slice()).unwrap(); - log(format!("Result: {:?}", result).as_str()); + info!("Result: {result:?}"); let result = if (!is_in_preview()) { let result = result.object.unwrap().fields.get("result").unwrap().clone().kind.unwrap(); diff --git a/pulumi_wasm_main/Cargo.toml b/pulumi_wasm_main/Cargo.toml index 91ad797fd..f6a9d418c 100644 --- a/pulumi_wasm_main/Cargo.toml +++ b/pulumi_wasm_main/Cargo.toml @@ -25,6 +25,8 @@ serde.workspace = true tonic.workspace = true serde_json.workspace = true pulumi_rust_wasm = { path = "../pulumi_rust_wasm" } +log.workspace = true +wasm_common = { path = "../wasm_common" } [dev-dependencies] wasmtime.workspace = true diff --git a/pulumi_wasm_main/src/bindings.rs b/pulumi_wasm_main/src/bindings.rs index 4a7cd3492..17f2c975a 100644 --- a/pulumi_wasm_main/src/bindings.rs +++ b/pulumi_wasm_main/src/bindings.rs @@ -509,25 +509,206 @@ pub mod component { #[cfg(target_arch = "wasm32")] static __FORCE_SECTION_REF: fn() = super::super::super::__link_custom_section_describing_imports; + use super::super::super::_rt; + #[repr(u8)] + #[derive(Clone, Copy, Eq, PartialEq)] + pub enum Level { + Trace, + Debug, + Info, + Warn, + Error, + } + impl ::core::fmt::Debug for Level { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + match self { + Level::Trace => f.debug_tuple("Level::Trace").finish(), + Level::Debug => f.debug_tuple("Level::Debug").finish(), + Level::Info => f.debug_tuple("Level::Info").finish(), + Level::Warn => f.debug_tuple("Level::Warn").finish(), + Level::Error => f.debug_tuple("Level::Error").finish(), + } + } + } + + impl Level { + pub(crate) unsafe fn _lift(val: u8) -> Level { + if !cfg!(debug_assertions) { + return ::core::mem::transmute(val); + } + + match val { + 0 => Level::Trace, + 1 => Level::Debug, + 2 => Level::Info, + 3 => Level::Warn, + 4 => Level::Error, + + _ => panic!("invalid enum discriminant"), + } + } + } + + #[derive(Clone)] + pub struct Content { + pub level: Level, + pub target: _rt::String, + pub args: _rt::String, + pub module_path: Option<_rt::String>, + pub file: Option<_rt::String>, + pub line: Option, + pub key_values: _rt::Vec<(_rt::String, _rt::String)>, + } + impl ::core::fmt::Debug for Content { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("Content") + .field("level", &self.level) + .field("target", &self.target) + .field("args", &self.args) + .field("module-path", &self.module_path) + .field("file", &self.file) + .field("line", &self.line) + .field("key-values", &self.key_values) + .finish() + } + } #[allow(unused_unsafe, clippy::all)] - pub fn log(message: &str) { + pub fn log(content: &Content) { unsafe { - let vec0 = message; - let ptr0 = vec0.as_ptr().cast::(); - let len0 = vec0.len(); + let Content { + level: level0, + target: target0, + args: args0, + module_path: module_path0, + file: file0, + line: line0, + key_values: key_values0, + } = content; + let vec1 = target0; + let ptr1 = vec1.as_ptr().cast::(); + let len1 = vec1.len(); + let vec2 = args0; + let ptr2 = vec2.as_ptr().cast::(); + let len2 = vec2.len(); + let (result4_0, result4_1, result4_2) = match module_path0 { + Some(e) => { + let vec3 = e; + let ptr3 = vec3.as_ptr().cast::(); + let len3 = vec3.len(); + + (1i32, ptr3.cast_mut(), len3) + } + None => (0i32, ::core::ptr::null_mut(), 0usize), + }; + let (result6_0, result6_1, result6_2) = match file0 { + Some(e) => { + let vec5 = e; + let ptr5 = vec5.as_ptr().cast::(); + let len5 = vec5.len(); + + (1i32, ptr5.cast_mut(), len5) + } + None => (0i32, ::core::ptr::null_mut(), 0usize), + }; + let (result7_0, result7_1) = match line0 { + Some(e) => (1i32, _rt::as_i32(e)), + None => (0i32, 0i32), + }; + let vec11 = key_values0; + let len11 = vec11.len(); + let layout11 = + _rt::alloc::Layout::from_size_align_unchecked(vec11.len() * 16, 4); + let result11 = if layout11.size() != 0 { + let ptr = _rt::alloc::alloc(layout11).cast::(); + if ptr.is_null() { + _rt::alloc::handle_alloc_error(layout11); + } + ptr + } else { + { + ::core::ptr::null_mut() + } + }; + for (i, e) in vec11.into_iter().enumerate() { + let base = result11.add(i * 16); + { + let (t8_0, t8_1) = e; + let vec9 = t8_0; + let ptr9 = vec9.as_ptr().cast::(); + let len9 = vec9.len(); + *base.add(4).cast::() = len9; + *base.add(0).cast::<*mut u8>() = ptr9.cast_mut(); + let vec10 = t8_1; + let ptr10 = vec10.as_ptr().cast::(); + let len10 = vec10.len(); + *base.add(12).cast::() = len10; + *base.add(8).cast::<*mut u8>() = ptr10.cast_mut(); + } + } #[cfg(target_arch = "wasm32")] #[link(wasm_import_module = "component:pulumi-wasm/log@0.1.0")] extern "C" { #[link_name = "log"] - fn wit_import(_: *mut u8, _: usize); + fn wit_import( + _: i32, + _: *mut u8, + _: usize, + _: *mut u8, + _: usize, + _: i32, + _: *mut u8, + _: usize, + _: i32, + _: *mut u8, + _: usize, + _: i32, + _: i32, + _: *mut u8, + _: usize, + ); } #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: *mut u8, _: usize) { + fn wit_import( + _: i32, + _: *mut u8, + _: usize, + _: *mut u8, + _: usize, + _: i32, + _: *mut u8, + _: usize, + _: i32, + _: *mut u8, + _: usize, + _: i32, + _: i32, + _: *mut u8, + _: usize, + ) { unreachable!() } - wit_import(ptr0.cast_mut(), len0); + wit_import( + level0.clone() as i32, + ptr1.cast_mut(), + len1, + ptr2.cast_mut(), + len2, + result4_0, + result4_1, + result4_2, + result6_0, + result6_1, + result6_2, + result7_0, + result7_1, + result11, + len11, + ); + if layout11.size() != 0 { + _rt::alloc::dealloc(result11.cast(), layout11); + } } } } @@ -701,6 +882,76 @@ mod _rt { alloc::dealloc(ptr as *mut u8, layout); } pub use alloc_crate::alloc; + + pub fn as_i32(t: T) -> i32 { + t.as_i32() + } + + pub trait AsI32 { + fn as_i32(self) -> i32; + } + + impl<'a, T: Copy + AsI32> AsI32 for &'a T { + fn as_i32(self) -> i32 { + (*self).as_i32() + } + } + + impl AsI32 for i32 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + + impl AsI32 for u32 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + + impl AsI32 for i16 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + + impl AsI32 for u16 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + + impl AsI32 for i8 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + + impl AsI32 for u8 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + + impl AsI32 for char { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + + impl AsI32 for usize { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } extern crate alloc as alloc_crate; } @@ -735,8 +986,8 @@ pub(crate) use __export_new_main_impl as export; #[cfg(target_arch = "wasm32")] #[link_section = "component-type:wit-bindgen:0.20.0:new-main:encoded world"] #[doc(hidden)] -pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 1234] = *b"\ -\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07\xd3\x08\x01A\x02\x01\ +pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 1364] = *b"\ +\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07\xd5\x09\x01A\x02\x01\ A\x0b\x01B\x16\x04\0\x06output\x03\x01\x01p}\x01i\0\x01@\x01\x05value\x01\0\x02\x04\ \0\x13[constructor]output\x01\x03\x01h\0\x01@\x02\x04self\x04\x0dfunction-names\0\ \x02\x04\0\x12[method]output.map\x01\x05\x01k\x01\x01@\x01\x04self\x04\0\x06\x04\ @@ -757,7 +1008,10 @@ m/pulumi-provider-random-interface@0.1.0\x05\x02\x01B\x0f\x02\x03\x02\x01\x01\x0 alue\x03\x04\0\x1afunction-invocation-result\x03\0\x07\x01p\x05\x01@\x01\x06sour\ ces\0\x09\x04\0\x0dget-functions\x01\x0a\x01p\x08\x01@\x01\x07results\x0b\x01\0\x04\ \0\x0dset-functions\x01\x0c\x03\x015component:pulumi-wasm/function-reverse-callb\ -ack@0.1.0\x05\x03\x01B\x02\x01@\x01\x07messages\x01\0\x04\0\x03log\x01\0\x03\x01\ +ack@0.1.0\x05\x03\x01B\x0a\x01m\x05\x05TRACE\x05DEBUG\x04INFO\x04WARN\x05ERROR\x04\ +\0\x05level\x03\0\0\x01ks\x01ky\x01o\x02ss\x01p\x04\x01r\x07\x05level\x01\x06tar\ +gets\x04argss\x0bmodule-path\x02\x04file\x02\x04line\x03\x0akey-values\x05\x04\0\ +\x07content\x03\0\x06\x01@\x01\x07content\x07\x01\0\x04\0\x03log\x01\x08\x03\x01\ \x1fcomponent:pulumi-wasm/log@0.1.0\x05\x04\x01B\x02\x01@\0\x01\0\x04\0\x04main\x01\ \0\x04\x01'component:pulumi-wasm/pulumi-main@0.1.0\x05\x05\x04\x01$component:pul\ umi-wasm/new-main@0.1.0\x04\0\x0b\x0e\x01\0\x08new-main\x03\0\0\0G\x09producers\x01\ diff --git a/pulumi_wasm_main/src/lib.rs b/pulumi_wasm_main/src/lib.rs index a0f554c25..78b659117 100644 --- a/pulumi_wasm_main/src/lib.rs +++ b/pulumi_wasm_main/src/lib.rs @@ -1,10 +1,11 @@ +use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use anyhow::Error; +use log::info; use pulumi_rust_wasm::HASHMAP; use crate::bindings::exports::component::pulumi_wasm::pulumi_main::Guest; use pulumi_rust_wasm::output::Output; use crate::bindings::component::pulumi_wasm::function_reverse_callback::{FunctionInvocationRequest, FunctionInvocationResult, get_functions, set_functions}; -use crate::bindings::component::pulumi_wasm::log::log; use crate::bindings::component::pulumi_wasm::output_interface::{combine_outputs, describe_outputs, non_done_exists}; use crate::random::*; @@ -17,6 +18,8 @@ struct Component {} impl Guest for Component { fn main() { + wasm_common::setup_logger(); + let length: Output = Output::new(&4).map(|i: i32| i * 2); let v = create_random_string(RandomStringArgs { @@ -33,7 +36,7 @@ impl Guest for Component { run_loop().unwrap(); - log(describe_outputs().as_str()); + info!("{}", describe_outputs()); if non_done_exists() { eprintln!("Non done exists"); @@ -59,11 +62,11 @@ fn run_all_function( let functions = get_functions("source"); if functions.is_empty() { - log("Functions are empty"); + info!("Functions are empty"); return Ok(false) } - log("Functions are not empty"); + info!("Functions are not empty"); let mut functions_map = HASHMAP.lock().unwrap(); diff --git a/run.bat b/run.bat index 68ea1ea6a..ce86b1ecb 100644 --- a/run.bat +++ b/run.bat @@ -1,3 +1,4 @@ +cargo component build -p wasm_common || exit /b 1 cargo component build -p pulumi_wasm || exit /b 1 cargo component build -p pulumi_wasm_random || exit /b 1 cargo component build -p pulumi_rust_wasm || exit /b 1 diff --git a/src/main.rs b/src/main.rs index ef348baf9..5ceb009cc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,7 @@ use clap::{arg, Args, Parser, Subcommand}; use log4rs::append::file::FileAppender; use log4rs::Config; use log4rs::config::{Appender, Root}; +use log4rs::encode::json::JsonEncoder; #[derive(Parser, Debug)] #[command(version, about, long_about = None)] @@ -38,6 +39,8 @@ async fn main() -> Result<(), Error> { println!("Hello, world!"); let logfile = FileAppender::builder() + // .encoder(Box::new(log4rs::encode::pattern::PatternEncoder::new("{h({d(%Y-%m-%d %H:%M:%S)} - [{l}] [{M}] [{f}:{L}] {m}{n})}"))) + .encoder(Box::new(JsonEncoder::new())) .build("output.log") .unwrap(); @@ -56,27 +59,10 @@ async fn main() -> Result<(), Error> { let _pulumi_engine_url = std::env::var("PULUMI_ENGINE")?; let pulumi_monitor_url = std::env::var("PULUMI_MONITOR")?; - // println!("{pulumi_engine_url}"); - // simple_logger::SimpleLogger::new().env().init().unwrap(); - - - // Result::Err(Error::msg(format!("{:?}", std::env::vars().collect::>())))?; - - // let pulumi_logger = PulumiLogger { - // engine_url: pulumi_engine_url.clone(), - // }; - - // pulumi_logger.init()?; - - // debug!("Hello, world!"); info!("INFO LOG"); warn!("WARN LOG"); error!("ERROR LOG"); - // info!("Hello, world!"); - // info!("Hello, world!"); - - // Err(anyhow::Error::msg("TEST"))?; match &args.command { Command::Run => { diff --git a/wasm_common/Cargo.toml b/wasm_common/Cargo.toml new file mode 100644 index 000000000..3b76e802e --- /dev/null +++ b/wasm_common/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "wasm_common" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +log.workspace = true +uuid.workspace = true +wit-bindgen-rt.workspace = true + +[package.metadata.component] +package = "component:logger" + +[package.metadata.component.target] +path = "../wits/world.wit" +world = "logger" diff --git a/wasm_common/src/bindings.rs b/wasm_common/src/bindings.rs new file mode 100644 index 000000000..790982488 --- /dev/null +++ b/wasm_common/src/bindings.rs @@ -0,0 +1,313 @@ +// Generated by `wit-bindgen` 0.20.0. DO NOT EDIT! +// Options used: +pub mod component { + pub mod pulumi_wasm { + + #[allow(clippy::all)] + pub mod log { + #[used] + #[doc(hidden)] + #[cfg(target_arch = "wasm32")] + static __FORCE_SECTION_REF: fn() = + super::super::super::__link_custom_section_describing_imports; + use super::super::super::_rt; + #[repr(u8)] + #[derive(Clone, Copy, Eq, PartialEq)] + pub enum Level { + Trace, + Debug, + Info, + Warn, + Error, + } + impl ::core::fmt::Debug for Level { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + match self { + Level::Trace => f.debug_tuple("Level::Trace").finish(), + Level::Debug => f.debug_tuple("Level::Debug").finish(), + Level::Info => f.debug_tuple("Level::Info").finish(), + Level::Warn => f.debug_tuple("Level::Warn").finish(), + Level::Error => f.debug_tuple("Level::Error").finish(), + } + } + } + + impl Level { + pub(crate) unsafe fn _lift(val: u8) -> Level { + if !cfg!(debug_assertions) { + return ::core::mem::transmute(val); + } + + match val { + 0 => Level::Trace, + 1 => Level::Debug, + 2 => Level::Info, + 3 => Level::Warn, + 4 => Level::Error, + + _ => panic!("invalid enum discriminant"), + } + } + } + + #[derive(Clone)] + pub struct Content { + pub level: Level, + pub target: _rt::String, + pub args: _rt::String, + pub module_path: Option<_rt::String>, + pub file: Option<_rt::String>, + pub line: Option, + pub key_values: _rt::Vec<(_rt::String, _rt::String)>, + } + impl ::core::fmt::Debug for Content { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("Content") + .field("level", &self.level) + .field("target", &self.target) + .field("args", &self.args) + .field("module-path", &self.module_path) + .field("file", &self.file) + .field("line", &self.line) + .field("key-values", &self.key_values) + .finish() + } + } + #[allow(unused_unsafe, clippy::all)] + pub fn log(content: &Content) { + unsafe { + let Content { + level: level0, + target: target0, + args: args0, + module_path: module_path0, + file: file0, + line: line0, + key_values: key_values0, + } = content; + let vec1 = target0; + let ptr1 = vec1.as_ptr().cast::(); + let len1 = vec1.len(); + let vec2 = args0; + let ptr2 = vec2.as_ptr().cast::(); + let len2 = vec2.len(); + let (result4_0, result4_1, result4_2) = match module_path0 { + Some(e) => { + let vec3 = e; + let ptr3 = vec3.as_ptr().cast::(); + let len3 = vec3.len(); + + (1i32, ptr3.cast_mut(), len3) + } + None => (0i32, ::core::ptr::null_mut(), 0usize), + }; + let (result6_0, result6_1, result6_2) = match file0 { + Some(e) => { + let vec5 = e; + let ptr5 = vec5.as_ptr().cast::(); + let len5 = vec5.len(); + + (1i32, ptr5.cast_mut(), len5) + } + None => (0i32, ::core::ptr::null_mut(), 0usize), + }; + let (result7_0, result7_1) = match line0 { + Some(e) => (1i32, _rt::as_i32(e)), + None => (0i32, 0i32), + }; + let vec11 = key_values0; + let len11 = vec11.len(); + let layout11 = + _rt::alloc::Layout::from_size_align_unchecked(vec11.len() * 16, 4); + let result11 = if layout11.size() != 0 { + let ptr = _rt::alloc::alloc(layout11).cast::(); + if ptr.is_null() { + _rt::alloc::handle_alloc_error(layout11); + } + ptr + } else { + { + ::core::ptr::null_mut() + } + }; + for (i, e) in vec11.into_iter().enumerate() { + let base = result11.add(i * 16); + { + let (t8_0, t8_1) = e; + let vec9 = t8_0; + let ptr9 = vec9.as_ptr().cast::(); + let len9 = vec9.len(); + *base.add(4).cast::() = len9; + *base.add(0).cast::<*mut u8>() = ptr9.cast_mut(); + let vec10 = t8_1; + let ptr10 = vec10.as_ptr().cast::(); + let len10 = vec10.len(); + *base.add(12).cast::() = len10; + *base.add(8).cast::<*mut u8>() = ptr10.cast_mut(); + } + } + + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "component:pulumi-wasm/log@0.1.0")] + extern "C" { + #[link_name = "log"] + fn wit_import( + _: i32, + _: *mut u8, + _: usize, + _: *mut u8, + _: usize, + _: i32, + _: *mut u8, + _: usize, + _: i32, + _: *mut u8, + _: usize, + _: i32, + _: i32, + _: *mut u8, + _: usize, + ); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import( + _: i32, + _: *mut u8, + _: usize, + _: *mut u8, + _: usize, + _: i32, + _: *mut u8, + _: usize, + _: i32, + _: *mut u8, + _: usize, + _: i32, + _: i32, + _: *mut u8, + _: usize, + ) { + unreachable!() + } + wit_import( + level0.clone() as i32, + ptr1.cast_mut(), + len1, + ptr2.cast_mut(), + len2, + result4_0, + result4_1, + result4_2, + result6_0, + result6_1, + result6_2, + result7_0, + result7_1, + result11, + len11, + ); + if layout11.size() != 0 { + _rt::alloc::dealloc(result11.cast(), layout11); + } + } + } + } + } +} +mod _rt { + pub use alloc_crate::string::String; + pub use alloc_crate::vec::Vec; + + pub fn as_i32(t: T) -> i32 { + t.as_i32() + } + + pub trait AsI32 { + fn as_i32(self) -> i32; + } + + impl<'a, T: Copy + AsI32> AsI32 for &'a T { + fn as_i32(self) -> i32 { + (*self).as_i32() + } + } + + impl AsI32 for i32 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + + impl AsI32 for u32 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + + impl AsI32 for i16 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + + impl AsI32 for u16 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + + impl AsI32 for i8 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + + impl AsI32 for u8 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + + impl AsI32 for char { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + + impl AsI32 for usize { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + pub use alloc_crate::alloc; + extern crate alloc as alloc_crate; +} + +#[cfg(target_arch = "wasm32")] +#[link_section = "component-type:wit-bindgen:0.20.0:logger:encoded world"] +#[doc(hidden)] +pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 361] = *b"\ +\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07\xec\x01\x01A\x02\x01\ +A\x02\x01B\x0a\x01m\x05\x05TRACE\x05DEBUG\x04INFO\x04WARN\x05ERROR\x04\0\x05leve\ +l\x03\0\0\x01ks\x01ky\x01o\x02ss\x01p\x04\x01r\x07\x05level\x01\x06targets\x04ar\ +gss\x0bmodule-path\x02\x04file\x02\x04line\x03\x0akey-values\x05\x04\0\x07conten\ +t\x03\0\x06\x01@\x01\x07content\x07\x01\0\x04\0\x03log\x01\x08\x03\x01\x1fcompon\ +ent:pulumi-wasm/log@0.1.0\x05\0\x04\x01\"component:pulumi-wasm/logger@0.1.0\x04\0\ +\x0b\x0c\x01\0\x06logger\x03\0\0\0G\x09producers\x01\x0cprocessed-by\x02\x0dwit-\ +component\x070.201.0\x10wit-bindgen-rust\x060.20.0"; + +#[inline(never)] +#[doc(hidden)] +#[cfg(target_arch = "wasm32")] +pub fn __link_custom_section_describing_imports() { + wit_bindgen_rt::maybe_link_cabi_realloc(); +} diff --git a/wasm_common/src/lib.rs b/wasm_common/src/lib.rs new file mode 100644 index 000000000..f46f300fd --- /dev/null +++ b/wasm_common/src/lib.rs @@ -0,0 +1,19 @@ +use std::sync::atomic::Ordering::Relaxed; + +use crate::logger::Logger; +use log::kv::{Source, VisitSource}; +use log::Log; + +mod bindings; +mod logger; + +static IS_SET : std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false); +static LOGGER: Logger = logger::Logger {}; + +pub fn setup_logger() { + if IS_SET.swap(true, Relaxed) { + return; + } + log::set_logger(&LOGGER).unwrap(); + log::set_max_level(log::LevelFilter::Trace); +} \ No newline at end of file diff --git a/wasm_common/src/logger.rs b/wasm_common/src/logger.rs new file mode 100644 index 000000000..a79e8b977 --- /dev/null +++ b/wasm_common/src/logger.rs @@ -0,0 +1,76 @@ +use std::collections::HashMap; +use log::{Level, Log, Metadata, Record}; +use log::kv::{Source, VisitSource}; +use bindings::component::pulumi_wasm; +use crate::bindings; +use crate::bindings::component::pulumi_wasm::log::Content; + +pub(crate) struct Logger {} + +impl Log for Logger { + fn enabled(&self, _metadata: &Metadata) -> bool { + true + } + + fn log(&self, record: &Record) { + if self.enabled(record.metadata()) { + let level = record.metadata().level(); + let target = record.metadata().target(); + let args = record.args().to_string(); + let module_path = record.module_path(); + let file = record.file(); + let line = record.line(); + let key_values = source_to_map(record.key_values()); + + let content = Content { + level: match level { + Level::Error => pulumi_wasm::log::Level::Error, + Level::Warn => pulumi_wasm::log::Level::Warn, + Level::Info => pulumi_wasm::log::Level::Info, + Level::Debug => pulumi_wasm::log::Level::Debug, + Level::Trace => pulumi_wasm::log::Level::Trace, + }, + target: target.to_string(), + args, + module_path: module_path.map(|s| s.to_string()), + file: file.map(|s| s.to_string()), + line, + key_values: key_values.into_iter().collect(), + }; + + pulumi_wasm::log::log(&content); + } + } + + fn flush(&self) { + todo!() + } +} + + +struct HashMapPrinter { + map: HashMap, +} + +impl HashMapPrinter { + fn new() -> Self { + Self { + map: HashMap::new(), + } + } +} + +impl<'kvs> VisitSource<'kvs> for HashMapPrinter { + fn visit_pair(&mut self, key: log::kv::Key<'kvs>, value: log::kv::Value<'kvs>) -> Result<(), log::kv::Error> { + self.map.insert(key.to_string(), value.to_string()); + Ok(()) + } +} + +fn source_to_map(s: &dyn Source) -> HashMap { + let mut printer = HashMapPrinter::new(); + + s.visit(&mut printer).unwrap(); + + printer.map +} diff --git a/wits/world.wit b/wits/world.wit index 7e6710070..f74c81124 100644 --- a/wits/world.wit +++ b/wits/world.wit @@ -30,12 +30,35 @@ world pulumi-provider-random { export pulumi-provider-random-interface; } +world logger { + import log; +} + world pulumi-rust { import output-interface; } interface log { - log: func(message: string); + + enum level { + TRACE, + DEBUG, + INFO, + WARN, + ERROR + } + + record content { + level: level, + target: string, + args: string, + module-path: option, + file: option, + line: option, + key-values: list> + } + + log: func(content: content); } interface output-interface {