diff --git a/Cargo.lock b/Cargo.lock index 4f6ccbf..edb5733 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,18 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy 0.7.35", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -138,12 +150,41 @@ dependencies = [ "syn", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "aws-lc-rs" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b756939cb2f8dc900aa6dcd505e6e2428e9cae7ff7b028c49e3946efa70878" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.28.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa9b6986f250236c27e5a204062434a773a13243d2ffc2955f37bdba4c5c6a1" +dependencies = [ + "bindgen", + "cc", + "cmake", + "dunce", + "fs_extra", +] + [[package]] name = "backtrace" version = "0.3.74" @@ -159,6 +200,35 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bindgen" +version = "0.69.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" +dependencies = [ + "bitflags 2.9.0", + "cexpr", + "clang-sys", + "itertools 0.12.1", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash 1.1.0", + "shlex", + "syn", + "which", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -283,6 +353,15 @@ dependencies = [ "shlex", ] +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -336,6 +415,17 @@ dependencies = [ "half", ] +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "clap" version = "4.5.36" @@ -363,6 +453,15 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +[[package]] +name = "cmake" +version = "0.1.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" +dependencies = [ + "cc", +] + [[package]] name = "cobs" version = "0.2.3" @@ -381,6 +480,16 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" +[[package]] +name = "core-foundation" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -450,7 +559,7 @@ dependencies = [ "log", "pulley-interpreter", "regalloc2", - "rustc-hash", + "rustc-hash 2.1.1", "serde", "smallvec", "target-lexicon", @@ -681,6 +790,12 @@ dependencies = [ "syn", ] +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "either" version = "1.13.0" @@ -708,6 +823,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + [[package]] name = "equivalent" version = "1.0.1" @@ -774,6 +895,51 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -831,6 +997,12 @@ dependencies = [ "url", ] +[[package]] +name = "glob" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" + [[package]] name = "globset" version = "0.4.15" @@ -855,6 +1027,25 @@ dependencies = [ "scroll", ] +[[package]] +name = "h2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75249d144030531f8dee69fe9cea04d3edf809a017ae445e2abdff6629e86633" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "half" version = "2.4.1" @@ -893,6 +1084,120 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "home" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "http" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" +dependencies = [ + "futures-util", + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-native-certs", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "libc", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + [[package]] name = "hyperlight-common" version = "0.2.0" @@ -969,13 +1274,13 @@ dependencies = [ "examples_common", "goblin", "hyperlight-host", - "lazy_static", "libc", "log", + "metrics", + "metrics-exporter-prometheus", + "metrics-util", "once_cell", "page_size", - "prometheus", - "strum", "toml", "tracing", "windows 0.61.1", @@ -1169,6 +1474,12 @@ dependencies = [ "serde", ] +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + [[package]] name = "is-terminal" version = "0.4.15" @@ -1256,6 +1567,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + [[package]] name = "leb128" version = "0.2.5" @@ -1280,6 +1597,16 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "libloading" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" +dependencies = [ + "cfg-if", + "windows-targets 0.52.6", +] + [[package]] name = "libm" version = "0.2.11" @@ -1366,6 +1693,63 @@ dependencies = [ "rustix 0.38.44", ] +[[package]] +name = "metrics" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25dea7ac8057892855ec285c440160265225438c3c45072613c25a4b26e98ef5" +dependencies = [ + "ahash", + "portable-atomic", +] + +[[package]] +name = "metrics-exporter-prometheus" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df88858cd28baaaf2cfc894e37789ed4184be0e1351157aec7bf3c2266c793fd" +dependencies = [ + "base64", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "indexmap", + "ipnet", + "metrics", + "metrics-util", + "quanta", + "thiserror 2.0.12", + "tokio", + "tracing", +] + +[[package]] +name = "metrics-util" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8496cc523d1f94c1385dd8f0f0c2c480b2b8aeccb5b7e4485ad6365523ae376" +dependencies = [ + "aho-corasick", + "crossbeam-epoch", + "crossbeam-utils", + "hashbrown", + "indexmap", + "metrics", + "ordered-float", + "quanta", + "radix_trie", + "rand", + "rand_xoshiro", + "sketches-ddsketch", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.8.4" @@ -1375,6 +1759,17 @@ dependencies = [ "adler2", ] +[[package]] +name = "mio" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +dependencies = [ + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.52.0", +] + [[package]] name = "mshv-bindings" version = "0.2.1" @@ -1423,6 +1818,25 @@ dependencies = [ "vmm-sys-util", ] +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -1476,12 +1890,27 @@ version = "11.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + [[package]] name = "option-ext" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "ordered-float" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951" +dependencies = [ + "num-traits", +] + [[package]] name = "page_size" version = "0.6.0" @@ -1533,6 +1962,12 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "pkg-config" version = "0.3.31" @@ -1573,6 +2008,12 @@ dependencies = [ "plotters-backend", ] +[[package]] +name = "portable-atomic" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" + [[package]] name = "postcard" version = "1.1.1" @@ -1594,6 +2035,16 @@ dependencies = [ "zerocopy 0.7.35", ] +[[package]] +name = "prettyplease" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "664ec5419c51e34154eec046ebcba56312d5a2fc3b09a06da188e1ad21afadf6" +dependencies = [ + "proc-macro2", + "syn", +] + [[package]] name = "proc-macro2" version = "1.0.93" @@ -1644,6 +2095,21 @@ dependencies = [ "wasmtime-math", ] +[[package]] +name = "quanta" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bd1fe6824cea6538803de3ff1bc0cf3949024db3d43c9643024bfb33a807c0e" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi 0.11.0+wasi-snapshot-preview1", + "web-sys", + "winapi", +] + [[package]] name = "quote" version = "1.0.38" @@ -1653,6 +2119,16 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + [[package]] name = "rand" version = "0.9.0" @@ -1684,6 +2160,24 @@ dependencies = [ "zerocopy 0.8.17", ] +[[package]] +name = "rand_xoshiro" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f703f4665700daf5512dcca5f43afa6af89f09db47fb56be587f80636bda2d41" +dependencies = [ + "rand_core", +] + +[[package]] +name = "raw-cpuid" +version = "11.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6df7ab838ed27997ba19a4664507e6f82b41fe6e20be42929332156e5e85146" +dependencies = [ + "bitflags 2.9.0", +] + [[package]] name = "rayon" version = "1.10.0" @@ -1734,7 +2228,7 @@ dependencies = [ "bumpalo", "hashbrown", "log", - "rustc-hash", + "rustc-hash 2.1.1", "smallvec", ] @@ -1767,6 +2261,20 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.15", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + [[package]] name = "rust-embed" version = "8.6.0" @@ -1809,6 +2317,12 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustc-hash" version = "2.1.1" @@ -1850,6 +2364,50 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "rustls" +version = "0.23.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df51b5869f3a441595eac5e8ff14d486ff285f7b8c0df8770e49c3b56351f0f0" +dependencies = [ + "aws-lc-rs", + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pki-types" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" + +[[package]] +name = "rustls-webpki" +version = "0.103.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03" +dependencies = [ + "aws-lc-rs", + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.19" @@ -1871,6 +2429,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schannel" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +dependencies = [ + "windows-sys 0.59.0", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -1906,6 +2473,29 @@ dependencies = [ "libc", ] +[[package]] +name = "security-framework" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" +dependencies = [ + "bitflags 2.9.0", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "semver" version = "1.0.25" @@ -2008,6 +2598,21 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "sketches-ddsketch" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + [[package]] name = "smallvec" version = "1.13.2" @@ -2017,6 +2622,16 @@ dependencies = [ "serde", ] +[[package]] +name = "socket2" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "spin" version = "0.9.8" @@ -2066,6 +2681,12 @@ dependencies = [ "syn", ] +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "2.0.98" @@ -2184,7 +2805,34 @@ checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" dependencies = [ "backtrace", "bytes", + "libc", + "mio", "pin-project-lite", + "socket2", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", ] [[package]] @@ -2221,6 +2869,12 @@ dependencies = [ "winnow", ] +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + [[package]] name = "tracing" version = "0.1.41" @@ -2265,6 +2919,12 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "typenum" version = "1.17.0" @@ -2289,6 +2949,12 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.5.4" @@ -2356,6 +3022,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -2683,6 +3358,18 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix 0.38.44", +] + [[package]] name = "winapi" version = "0.3.9" @@ -2926,6 +3613,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.59.0" @@ -3263,6 +3959,12 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + [[package]] name = "zerovec" version = "0.10.4" diff --git a/Justfile b/Justfile index 594f15e..7e1ad3b 100644 --- a/Justfile +++ b/Justfile @@ -58,7 +58,6 @@ clippy target=default-target: (check target) test target=default-target features="": (test-inprocess target) (test-seccomp target features) cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F " + features } }} --profile={{ if target == "debug" {"dev"} else { target } }} cargo test test_metrics {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F " + features } }} --profile={{ if target == "debug" {"dev"} else { target } }} -- --ignored - cargo test test_gather_metrics {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F " + features } }} --profile={{ if target == "debug" {"dev"} else { target } }} -- --ignored test-inprocess target=default-target: {{ if target == "debug" { "cargo test --features='inprocess'; cargo test test_metrics --features='inprocess' -- --ignored; cargo test test_gather_metrics --features='inprocess' -- --ignored" } else {"echo 'inprocess tests are not run for release builds'" } }} @@ -83,4 +82,4 @@ bench target=default-target features="": bench-download os hypervisor tag="": gh release download {{ tag }} -D ./src/hyperlight_wasm/target/ -p benchmarks_{{ os }}_{{ hypervisor }}.tar.gz mkdir {{ mkdir-arg }} ./src/hyperlight_wasm/target/criterion - tar -zxvf ./src/hyperlight_wasm/target/benchmarks_{{ os }}_{{ hypervisor }}.tar.gz -C ./src/hyperlight_wasm/target/criterion/ --strip-components=1 \ No newline at end of file + tar -zxvf ./src/hyperlight_wasm/target/benchmarks_{{ os }}_{{ hypervisor }}.tar.gz -C ./src/hyperlight_wasm/target/criterion/ --strip-components=1 diff --git a/docs/observability.md b/docs/observability.md index 64be1d3..bbea5ae 100644 --- a/docs/observability.md +++ b/docs/observability.md @@ -2,42 +2,31 @@ hyperlight-wasm provides the following observability features: -* [Metrics](#metrics) metrics are provided using Prometheus. +* [Metrics](#metrics) metrics are provided using `metrics` crate. ## Metrics -Hyperlight-wasm provides metrics using Prometheus. The metrics are registered using either the [default_registry](https://docs.rs/prometheus/latest/prometheus/fn.default_registry.html) or a registry instance provided by the host application. -To provide a registry to hyperlight_wasm, use the `set_metrics_registry` function and pass a reference to a registry with `static` lifetime: +The following metrics are provided and are enabled by default: -```rust -use hyperlight_wasm::set_metrics_registry; -use prometheus::Registry; -use lazy_static::lazy_static; +* `active_proto_wasm_sandboxes` - A gauge indicating the number of currently active proto wasm sandboxes +* `active_wasm_sandboxes` - A gauge indicating the number of currently active wasm sandboxes +* `active_loaded_wasm_sandboxes` - A gauge indicating the number of currently loaded wasm sandboxes +* `proto_wasm_sandboxes_total` - A counter indicating the total number of proto wasm sandboxes created during the lifetime of the process +* `wasm_sandboxes_total` - A counter indicating the total number of wasm sandboxes created during the lifetime of the process +* `loaded_wasm_sandboxes_total` - A counter indicating the total number of loaded wasm sandboxes created during the lifetime of the process +* `sandbox_loads_total` - A counter indicating how many times a wasm sandbox has been loaded into a loaded wasm sandbox during the lifetime of the process +* `sandbox_unloads_total` - A counter indicating how many times a loaded wasm sandbox has been unloaded into a wasm sandbox during the lifetime of the process -lazy_static! { - static ref REGISTRY: Registry = Registry::new(); -} -set_metrics_registry(®ISTRY); -``` +In addition, regular Hyperlight provides the following metrics: -The following metrics are provided and are enabled by default: +* `guest_errors_total` - A counter indicating how many times a guest error has occurred +* `guest_cancellations_total` - The number of times guest execution has timed out + +If cargo feature `function_call_metrics` is enabled: -* `hyperlight_guest_error_count` - a vector of counters that tracks the number of guest errors by code and message. -* `hyperlight_number_of_cancelled_guest_execution` - a counter that tracks the number of guest executions that have been cancelled because the execution time exceeded the time allowed. -* `current_number_of_wasm_sandboxes` - a gauge that tracks the current number of wasm sandboxes in this process. -* `current_number_of_loaded_wasm_sandboxes` - a gauge that tracks the current number of loaded wasm sandboxes in this process. -* `number_of_unloads_of_loaded_wasm_sandboxes` - a counter that tracks the number of times that unload_module has been called on a LoadedWasmSandbox. -* `number_of_loads_of_wasm_sandboxes` - a counter that tracks the number of times that load_module has been called on a WasmSandbox. -* `current_number_of_proto_wasm_sandboxes` - a gauge that tracks the current number of proto wasm sandboxes in this process. -* `total_number_of_wasm_sandboxes` - a counter that tracks the total number of wasm sandboxes that have been created by this process. -* `total_number_of_loaded_wasm_sandboxes` - a counter that tracks the total number of loaded wasm sandboxes that have been created by this process. -* `total_number_of_proto_wasm_sandboxes` - a counter that tracks the total number of proto wasm sandboxes that have been created by this process. - -The following metrics are provided and are enabled by default using the feature `function_call_metrics` but can be disabled: - -* `hyperlight_guest_function_call_duration_microseconds` - a vector of histograms that tracks the execution time of guest functions in microseconds by function name. The histogram also tracks the number of calls to each function. -* `hyperlight_host_function_calls_duration_microseconds` - a vector of histograms that tracks the execution time of host functions in microseconds by function name. The histogram also tracks the number of calls to each function. +* `guest_call_duration_seconds` - Histogram for the execution time of guest function calls +* `host_call_duration_seconds` - Histogram for the execution time of host function calls There is an example of how to gather metrics in the [examples/metrics](../src/hyperlight_wasm/examples/metrics) directory. diff --git a/src/hyperlight_wasm/Cargo.toml b/src/hyperlight_wasm/Cargo.toml index 28eef45..e35e599 100644 --- a/src/hyperlight_wasm/Cargo.toml +++ b/src/hyperlight_wasm/Cargo.toml @@ -34,25 +34,23 @@ test = true hyperlight-host = { workspace = true } libc = { version = "0.2.172" } once_cell = "1.21.3" -strum = "0.27" tracing = "0.1.27" log = "0.4.27" cfg-if = { version = "1" } +metrics = "0.24.2" [target.'cfg(windows)'.dependencies] -windows = { version = "0.61", features = [ - "Win32_System_Threading", -] } +windows = { version = "0.61", features = ["Win32_System_Threading"] } page_size = "0.6.0" [dev-dependencies] examples_common = { path = "../examples_common" } criterion = { version = "0.5.1", features = ["html_reports"] } -lazy_static = "1.4.0" -prometheus = "0.13.3" crossbeam-queue = "0.3" blake3 = "1.8" toml = "0.8.19" +metrics-util = "0.19.1" +metrics-exporter-prometheus = "0.17" [build-dependencies] chrono = "0.4" diff --git a/src/hyperlight_wasm/examples/metrics/main.rs b/src/hyperlight_wasm/examples/metrics/main.rs index 361013b..667b473 100644 --- a/src/hyperlight_wasm/examples/metrics/main.rs +++ b/src/hyperlight_wasm/examples/metrics/main.rs @@ -14,326 +14,51 @@ See the License for the specific language governing permissions and limitations under the License. */ -use std::sync::{Arc, Mutex}; -use std::thread::{spawn, JoinHandle}; - use examples_common::get_wasm_module_path; -use hyperlight_host::HyperlightError; -use hyperlight_wasm::{ - set_metrics_registry, LoadedWasmSandbox, ParameterValue, Result, ReturnType, ReturnValue, - SandboxBuilder, -}; -use lazy_static::lazy_static; -use prometheus::Registry; - -lazy_static! { - static ref HOST_REGISTRY: Registry = Registry::new(); -} -fn fn_writer(msg: String) -> Result { - Ok(msg.len() as i32) -} - -fn get_time_since_boot_microsecond() -> Result { - let res = std::time::SystemTime::now() - .duration_since(std::time::SystemTime::UNIX_EPOCH)? - .as_micros(); - i64::try_from(res).map_err(HyperlightError::IntConversionFailure) -} +use hyperlight_wasm::{ParameterValue, Result, ReturnType, SandboxBuilder}; +use std::sync::{Arc, Mutex}; fn main() -> Result<()> { - // If this is not called then the default registry `prometheus::default_registry` will be used. - set_metrics_registry(&HOST_REGISTRY)?; - - let mut join_handles: Vec>> = vec![]; - - for _ in 0..20 { - let writer_func = Arc::new(Mutex::new(fn_writer)); - let get_time_since_boot_microsecond_func = - Arc::new(Mutex::new(get_time_since_boot_microsecond)); - let handle = spawn(move || -> Result<()> { - // Create a new WASM sandbox. - let mut sandbox = SandboxBuilder::new() - .with_host_print_fn(&writer_func) - .build()?; - sandbox - .register_host_func_0( - "GetTimeSinceBootMicrosecond", - &get_time_since_boot_microsecond_func, - ) - .unwrap(); - - let mut wasm_sandbox = sandbox.load_runtime()?; - - // Load a WASM Module into the sandbox. - - let mut loaded_wasm_sandbox = - wasm_sandbox.load_module(get_wasm_module_path("RunWasm.aot")?)?; - - // Call guest functions 50 times to generate some metrics. - - loaded_wasm_sandbox = call_funcs(loaded_wasm_sandbox, 50); - - wasm_sandbox = loaded_wasm_sandbox.unload_module()?; - - loaded_wasm_sandbox = - wasm_sandbox.load_module(get_wasm_module_path("RunWasm.wasm")?)?; - - // Call guest functions 50 times to generate some more metrics. - - call_funcs(loaded_wasm_sandbox, 50); - - Ok(()) - }); - - join_handles.push(handle); - } - - // Generate some metrics for cancelled calls. - - for i in 0..10 { - let wasm_sandbox = SandboxBuilder::new() + // Install prometheus metrics exporter. + // We only install the metrics recorder here, but you can also use the + // `metrics_exporter_prometheus::PrometheusBuilder::new().install()` method + // to install a HTTP listener that serves the metrics. + let prometheus_handle = metrics_exporter_prometheus::PrometheusBuilder::new() + .install_recorder() + .expect("Failed to install Prometheus exporter"); + + for _ in 0..10 { + let host_func = Arc::new(Mutex::new(|a: i32| -> Result { + println!("host_func called with {}", a); + Ok(a + 1) + })); + + let mut wasm_sandbox = SandboxBuilder::new() .with_guest_function_call_max_cancel_wait_millis(100) - .build()? - .load_runtime()?; + .with_guest_input_buffer_size(1000000) + .build()?; - let mut loaded_wasm_sandbox = - wasm_sandbox.load_module(get_wasm_module_path("RunWasm.aot")?)?; - - match loaded_wasm_sandbox.call_guest_function( - "CalcFib", - Some(vec![ParameterValue::Int(400)]), - ReturnType::Int, - ) { - Ok(ReturnValue::Int(result)) => { - println!( - "Got result: {:?} from the host function! iteration {}", - result, i, - ); - } - Ok(_) => { - println!("Failed to get result from CalcFib iteration {}", i) - } - Err(e) => { - println!("Error calling CalcFib: {:?}", e) - } - } - } - - for join_handle in join_handles { - let result = join_handle.join(); - assert!(result.is_ok()); - } + wasm_sandbox.register_host_func_1("TestHostFunc", &host_func)?; - get_metrics(); + let wasm_sandbox = wasm_sandbox.load_runtime()?; - Ok(()) -} - -fn get_metrics() { - // Get the metrics from the registry. - - let metrics = HOST_REGISTRY.gather(); - - // Print the metrics. - - print!("\nMETRICS:\n"); - - for metric in metrics.iter() { - match metric.get_field_type() { - prometheus::proto::MetricType::COUNTER => { - println!("Counter: {:?}", metric.get_help()); - metric.get_metric().iter().for_each(|metric| { - let pair = metric.get_label(); - for pair in pair.iter() { - println!("Label: {:?} Name: {:?}", pair.get_name(), pair.get_value()); - } - println!("Value: {:?}", metric.get_counter().get_value()); - }); - } - prometheus::proto::MetricType::GAUGE => { - println!("Gauge: {:?}", metric.get_help()); - metric.get_metric().iter().for_each(|metric| { - let pair = metric.get_label(); - for pair in pair.iter() { - println!("Label: {:?} Name: {:?}", pair.get_name(), pair.get_value()); - } - println!("Value: {:?}", metric.get_gauge().get_value()); - }); - } - prometheus::proto::MetricType::UNTYPED => { - println!("Metric: {:?}", metric.get_help()); - } - prometheus::proto::MetricType::HISTOGRAM => { - println!("Histogram: {:?}", metric.get_help()); - for metric in metric.get_metric() { - let pair = metric.get_label(); - for pair in pair.iter() { - println!("Label: {:?} Name: {:?}", pair.get_name(), pair.get_value()); - } - let count = metric.get_histogram().get_sample_count(); - println!("Number of observations: {:?}", count); - let sm = metric.get_histogram().get_sample_sum(); - println!("Sum of observations: {:?}", sm); - metric - .get_histogram() - .get_bucket() - .iter() - .for_each(|bucket| { - println!( - "Bucket: {:?} Count: {:?}", - bucket.get_upper_bound(), - bucket.get_cumulative_count() - ) - }); - } - } - prometheus::proto::MetricType::SUMMARY => { - println!("Summary: {:?}", metric.get_help()); - } - } - } -} - -fn call_funcs(mut loaded_wasm_sandbox: LoadedWasmSandbox, iterations: i32) -> LoadedWasmSandbox { - // Call a guest function that returns an int + let mut loaded_wasm_sandbox = + wasm_sandbox.load_module(get_wasm_module_path("rust_wasm_samples.wasm")?)?; - for i in 0..iterations { - let ReturnValue::Int(result) = loaded_wasm_sandbox + loaded_wasm_sandbox .call_guest_function( - "CalcFib", - Some(vec![ParameterValue::Int(4)]), + "add", + Some(vec![ParameterValue::Int(5), ParameterValue::Int(10)]), ReturnType::Int, ) - .unwrap() - else { - panic!( - "Failed to get result from call_guest_function iteration {}", - i - ) - }; - - println!( - "Got result: {:?} from the host function! iteration {}", - result, i, - ); + .unwrap(); } - // Call a guest function that returns a string - - for i in 0..iterations { - let ReturnValue::String(result) = loaded_wasm_sandbox - .call_guest_function( - "Echo", - Some(vec![ParameterValue::String( - "Message from Rust Example to Wasm Function".to_string(), - )]), - ReturnType::String, - ) - .unwrap() - else { - panic!( - "Failed to get result from call_guest_function iteration {}", - i - ) - }; - - println!( - "Got result: {:?} from the host function! iteration {}", - result, i, - ); - } + // Render out the metrics in prometheus exposition format. + // At this point, we should have created 10 of each sandbox, but 0 would be active + // since they were dropped in above for-loop + let payload = prometheus_handle.render(); + println!("Prometheus metrics:\n{}", payload); - for i in 0..iterations { - let ReturnValue::String(result) = loaded_wasm_sandbox - .call_guest_function( - "ToUpper", - Some(vec![ParameterValue::String( - "Message from Rust Example to WASM Function".to_string(), - )]), - ReturnType::String, - ) - .unwrap() - else { - panic!( - "Failed to get result from call_guest_function iteration {}", - i - ) - }; - - println!( - "Got result: {:?} from the host function! iteration {}", - result, i, - ); - - assert_eq!( - result, - "MESSAGE FROM RUST EXAMPLE TO WASM FUNCTION".to_string() - ); - } - - // Call a guest function that returns a size prefixed buffer - - for i in 0..iterations { - let ReturnValue::VecBytes(result) = loaded_wasm_sandbox - .call_guest_function( - "ReceiveByteArray", - Some(vec![ - ParameterValue::VecBytes(vec![0x01, 0x02, 0x03]), - ParameterValue::Int(3), - ]), - ReturnType::VecBytes, - ) - .unwrap() - else { - panic!( - "Failed to get result from call_guest_function iteration {}", - i - ) - }; - - println!( - "Got result: {:?} from the host function! iteration {}", - result, i, - ); - } - - // Call a guest function that Prints a string using HostPrint Host function - - for i in 0..iterations { - let ReturnValue::Void = loaded_wasm_sandbox - .call_guest_function( - "Print", - Some(vec![ParameterValue::String( - "Message from Rust Example to Wasm Function\n".to_string(), - )]), - ReturnType::Void, - ) - .unwrap() - else { - panic!( - "Failed to get result from call_guest_function iteration {}", - i - ) - }; - - println!("Called the host function! iteration {}", i,); - } - - // Call a guest function that calls prints a string constant using printf - - for i in 0..iterations { - let ReturnValue::Void = loaded_wasm_sandbox - .call_guest_function("PrintHelloWorld", None, ReturnType::Void) - .unwrap() - else { - panic!( - "Failed to get result from call_guest_function iteration {}", - i - ) - }; - - println!("Called the host function! iteration {}", i,); - } - - loaded_wasm_sandbox + Ok(()) } diff --git a/src/hyperlight_wasm/src/sandbox/loaded_wasm_sandbox.rs b/src/hyperlight_wasm/src/sandbox/loaded_wasm_sandbox.rs index d89d5b4..f1cd0d0 100644 --- a/src/hyperlight_wasm/src/sandbox/loaded_wasm_sandbox.rs +++ b/src/hyperlight_wasm/src/sandbox/loaded_wasm_sandbox.rs @@ -17,15 +17,11 @@ limitations under the License. use hyperlight_host::sandbox::Callable; use hyperlight_host::sandbox_state::sandbox::{DevolvableSandbox, Sandbox}; use hyperlight_host::sandbox_state::transition::Noop; -use hyperlight_host::{ - int_counter_inc, int_gauge_dec, int_gauge_inc, log_then_return, MultiUseSandbox, Result, -}; +use hyperlight_host::{log_then_return, MultiUseSandbox, Result}; +use super::metrics::METRIC_TOTAL_LOADED_WASM_SANDBOXES; use super::wasm_sandbox::WasmSandbox; -use crate::sandbox::metrics::SandboxMetric::{ - CurrentNumberOfLoadedWasmSandboxes, CurrentNumberOfWasmSandboxes, - NumberOfUnloadsOfLoadedWasmSandboxes, TotalNumberOfLoadedWasmSandboxes, -}; +use crate::sandbox::metrics::{METRIC_ACTIVE_LOADED_WASM_SANDBOXES, METRIC_SANDBOX_UNLOADS}; use crate::{ParameterValue, ReturnType, ReturnValue}; /// A sandbox that has both a Wasm engine and an arbitrary Wasm module @@ -67,13 +63,14 @@ impl LoadedWasmSandbox { } /// unload the wasm module and return a `WasmSandbox` that can be used to load another module pub fn unload_module(self) -> Result { - int_counter_inc!(&NumberOfUnloadsOfLoadedWasmSandboxes); - self.devolve(Noop::default()) + self.devolve(Noop::default()).inspect(|_| { + metrics::counter!(METRIC_SANDBOX_UNLOADS).increment(1); + }) } pub(super) fn new(inner: MultiUseSandbox) -> Result { - int_gauge_inc!(&CurrentNumberOfLoadedWasmSandboxes); - int_counter_inc!(&TotalNumberOfLoadedWasmSandboxes); + metrics::gauge!(METRIC_ACTIVE_LOADED_WASM_SANDBOXES).increment(1); + metrics::counter!(METRIC_TOTAL_LOADED_WASM_SANDBOXES).increment(1); Ok(LoadedWasmSandbox { inner: Some(inner) }) } } @@ -99,16 +96,13 @@ impl DevolvableSandbox inner.devolve(Noop::default())?, None => log_then_return!("No inner MultiUseSandbox to devolve"), }; - int_gauge_inc!(&CurrentNumberOfWasmSandboxes); - Ok(WasmSandbox { - inner: Some(new_inner), - }) + Ok(WasmSandbox::new(new_inner)) } } impl Drop for LoadedWasmSandbox { fn drop(&mut self) { - int_gauge_dec!(&CurrentNumberOfLoadedWasmSandboxes); + metrics::gauge!(METRIC_ACTIVE_LOADED_WASM_SANDBOXES).decrement(1); } } diff --git a/src/hyperlight_wasm/src/sandbox/metrics.rs b/src/hyperlight_wasm/src/sandbox/metrics.rs index 8772cd5..595e686 100644 --- a/src/hyperlight_wasm/src/sandbox/metrics.rs +++ b/src/hyperlight_wasm/src/sandbox/metrics.rs @@ -17,232 +17,46 @@ limitations under the License. /*! This module contains the definitions and implementations of the metrics used by the sandbox module */ -use std::collections::HashMap; -use std::sync::Once; -use hyperlight_host::metrics::{ - HyperlightMetric, HyperlightMetricDefinition, HyperlightMetricEnum, HyperlightMetricType, -}; -use once_cell::sync::OnceCell; -use strum::{EnumIter, IntoStaticStr, VariantNames}; -use tracing::{instrument, Span}; +// Gauges, active sandboxes +pub(crate) static METRIC_ACTIVE_PROTO_WASM_SANDBOXES: &str = "active_proto_wasm_sandboxes"; +pub(crate) static METRIC_ACTIVE_WASM_SANDBOXES: &str = "active_wasm_sandboxes"; +pub(crate) static METRIC_ACTIVE_LOADED_WASM_SANDBOXES: &str = "active_loaded_wasm_sandboxes"; -// This is required to ensure that the metrics are only initialized once -static INIT_METRICS: Once = Once::new(); -// This contains a hashmap of all the metrics using metric names defined below as keys -static METRICS: OnceCell> = OnceCell::new(); +// Counters, total sandboxes created during the lifetime of the process +pub(crate) static METRIC_TOTAL_PROTO_WASM_SANDBOXES: &str = "proto_wasm_sandboxes_total"; +pub(crate) static METRIC_TOTAL_WASM_SANDBOXES: &str = "wasm_sandboxes_total"; +pub(crate) static METRIC_TOTAL_LOADED_WASM_SANDBOXES: &str = "loaded_wasm_sandboxes_total"; -// This is the definition of all the metrics used by the sandbox module -static WASM_SANDBOX_METRIC_DEFINITIONS: &[HyperlightMetricDefinition] = &[ - HyperlightMetricDefinition { - name: "current_number_of_wasm_sandboxes", - help: "Current number of wasm sandboxes in this host process", - metric_type: HyperlightMetricType::IntGauge, - labels: &[], - buckets: &[], - }, - HyperlightMetricDefinition { - name: "current_number_of_loaded_wasm_sandboxes", - help: "Current number of loaded wasm sandboxes in this host process", - metric_type: HyperlightMetricType::IntGauge, - labels: &[], - buckets: &[], - }, - HyperlightMetricDefinition { - name: "number_of_unloads_of_loaded_wasm_sandboxes", - help: "The number of times that unload_module has been called on a LoadedWasmSandbox", - metric_type: HyperlightMetricType::IntCounter, - labels: &[], - buckets: &[], - }, - HyperlightMetricDefinition { - name: "number_of_loads_of_wasm_sandboxes", - help: "The number of times that load_module has been called on a WasmSandbox", - metric_type: HyperlightMetricType::IntCounter, - labels: &[], - buckets: &[], - }, - HyperlightMetricDefinition { - name: "current_number_of_proto_wasm_sandboxes", - help: "Current number of proto wasm sandboxes in this host process", - metric_type: HyperlightMetricType::IntGauge, - labels: &[], - buckets: &[], - }, - HyperlightMetricDefinition { - name: "total_number_of_wasm_sandboxes", - help: "The total number of wasm sandboxes that have been created by this process", - metric_type: HyperlightMetricType::IntCounter, - labels: &[], - buckets: &[], - }, - HyperlightMetricDefinition { - name: "total_number_of_loaded_wasm_sandboxes", - help: "The total number of loaded wasm sandboxes that have been created by this process", - metric_type: HyperlightMetricType::IntCounter, - labels: &[], - buckets: &[], - }, - HyperlightMetricDefinition { - name: "total_number_of_proto_wasm_sandboxes", - help: "The total number of proto wasm sandboxes that have been created by this process", - metric_type: HyperlightMetricType::IntCounter, - labels: &[], - buckets: &[], - }, -]; - -/// There is an enum variant for each error metric in the module -/// the names of the variant take the form of CamelCase, but the metric names are snake_case -/// so for example, the enum variant CurrentNumberOfMultiUseSandboxes corresponds to the -/// metric name current_number_of_multi_use_sandboxes. -/// At runtime we locate the correct metric by looking up the enum variant name in the hashmap and -/// the conversion of the enum variant name to the metric name is done by the IntoStaticStr derive macro -/// along with the strum(serialize_all = "snake_case") attribute. -/// This enum contains all the metrics used by the sandbox module -/// -/// The enum is required to derive from EnumIter, IntoStaticStr -/// and strum(serialize_all = "snake_case") performs the name conversion from CamelCase to snake_case -/// when the enum variant is serialized to a string -#[derive(Debug, EnumIter, VariantNames, IntoStaticStr)] -#[strum(serialize_all = "snake_case")] -#[allow(clippy::enum_variant_names)] -pub(crate) enum SandboxMetric { - CurrentNumberOfWasmSandboxes, - CurrentNumberOfLoadedWasmSandboxes, - CurrentNumberOfProtoWasmSandboxes, - TotalNumberOfWasmSandboxes, - TotalNumberOfLoadedWasmSandboxes, - TotalNumberOfProtoWasmSandboxes, - NumberOfUnloadsOfLoadedWasmSandboxes, - NumberOfLoadsOfWasmSandboxes, -} - -// It is required for the enum to implement HyperlightMetricEnum -impl HyperlightMetricEnum for SandboxMetric { - #[instrument(skip_all, parent = Span::current(), level= "Trace")] - fn get_init_metrics() -> &'static Once { - &INIT_METRICS - } - #[instrument(skip_all, parent = Span::current(), level= "Trace")] - fn get_metrics() -> &'static OnceCell> { - &METRICS - } - #[instrument(skip_all, parent = Span::current(), level= "Trace")] - fn get_metric_definitions() -> &'static [HyperlightMetricDefinition] { - WASM_SANDBOX_METRIC_DEFINITIONS - } -} +// Counters, total number of times loaded sandboxes have been loaded/unloaded during the lifetime of the process +pub(crate) static METRIC_SANDBOX_LOADS: &str = "sandbox_loads_total"; +pub(crate) static METRIC_SANDBOX_UNLOADS: &str = "sandbox_unloads_total"; #[cfg(test)] mod tests { - use hyperlight_host::metrics::get_metrics_registry; - use hyperlight_host::metrics::tests::HyperlightMetricEnumTest; - use hyperlight_host::{ - int_counter_get, int_counter_inc, int_counter_inc_by, int_counter_reset, int_gauge_add, - int_gauge_dec, int_gauge_get, int_gauge_inc, int_gauge_set, int_gauge_sub, - }; - use lazy_static::lazy_static; - use prometheus::Registry; - use strum::{IntoEnumIterator, VariantNames}; + use examples_common::get_wasm_module_path; - use super::*; + use crate::{LoadedWasmSandbox, ProtoWasmSandbox}; - impl HyperlightMetricEnumTest for SandboxMetric { - fn get_enum_variant_names() -> &'static [&'static str] { - SandboxMetric::VARIANTS - } - } - - #[test] - fn test_enum_has_variant_for_all_metrics() { - >::enum_has_variant_for_all_metrics(); - } #[test] - fn test_metric_definitions() { - >::check_metric_definitions( - ); - } - #[test] - #[ignore] - /// This test is ignored because as it uses real counters if it runs at the same time as other tests it may fail. - /// - /// Marking this test as ignored means that running `cargo test` will not - /// run it. This feature will allow a developer who runs that command - /// from their workstation to be successful without needing to know about - /// test interdependencies. This test will, however, be run explicitly as a - /// part of the CI pipeline. + #[ignore = "Needs to run separately to not get influenced by other tests"] fn test_metrics() { - let iter: SandboxMetricIter = SandboxMetric::iter(); - for sandbox_metric in iter { - match sandbox_metric.get_hyperlight_metric() { - Ok(hyperlight_metric) => match hyperlight_metric { - HyperlightMetric::IntGauge(int_gauge) => { - let gauge = >::get_intguage_metric(int_gauge.name); - assert!(gauge.is_ok()); - let gauge = gauge.unwrap(); - int_gauge_set!(&sandbox_metric, 0); - assert_eq!(gauge.get(), 0); - int_gauge_inc!(&sandbox_metric); - assert_eq!(gauge.get(), 1); - int_gauge_dec!(&sandbox_metric); - assert_eq!(gauge.get(), 0); - int_gauge_add!(&sandbox_metric, 5); - assert_eq!(gauge.get(), 5); - int_gauge_sub!(&sandbox_metric, 2); - assert_eq!(gauge.get(), 3); - int_gauge_set!(&sandbox_metric, 10); - assert_eq!(gauge.get(), 10); - let val = int_gauge_get!(&sandbox_metric); - assert_eq!(val, 10); - } - HyperlightMetric::IntCounter(int_counter) => { - let counter = >::get_intcounter_metric( - int_counter.name - ); - assert!(counter.is_ok()); - let counter = counter.unwrap(); - int_counter_reset!(&sandbox_metric); - assert_eq!(counter.get(), 0); - int_counter_inc!(&sandbox_metric); - assert_eq!(counter.get(), 1); - int_counter_inc_by!(&sandbox_metric, 5); - assert_eq!(counter.get(), 6); - int_counter_reset!(&sandbox_metric); - assert_eq!(counter.get(), 0); - let result = int_counter_get!(&sandbox_metric); - assert_eq!(result, 0); - } - _ => { - panic!("metric is not an IntGauge or IntCounter"); - } - }, - Err(e) => { - panic!("error getting metric: {}", e); - } - } - } - } - #[test] - #[ignore] - /// This test is ignored because it is requires that metrics and registry have not been set or initialised yet. - /// - /// Marking this test as ignored means that running `cargo test` will not - /// run it. This feature will allow a developer who runs that command - /// from their workstation to be successful without needing to know about - /// test interdependencies. This test will, however, be run explicitly as a - /// part of the CI pipeline. - fn test_gather_metrics() { - lazy_static! { - static ref REGISTRY: Registry = Registry::default(); - } - test_metrics(); - let registry = get_metrics_registry(); - let result = registry.gather(); - assert_eq!(result.len(), 8); + let recorder = metrics_util::debugging::DebuggingRecorder::new(); + let snapshotter = recorder.snapshotter(); + recorder.install().unwrap(); + + let snapshot = { + let sandbox = ProtoWasmSandbox::default(); + + let wasm_sandbox = sandbox.load_runtime().unwrap(); + let loaded_wasm_sandbox: LoadedWasmSandbox = { + let mod_path = get_wasm_module_path("RunWasm.wasm").unwrap(); + wasm_sandbox.load_module(mod_path).unwrap() + }; + loaded_wasm_sandbox.unload_module().unwrap(); + snapshotter.snapshot() + }; + let snapshot = snapshot.into_vec(); + assert_eq!(snapshot.len(), 8); } } diff --git a/src/hyperlight_wasm/src/sandbox/proto_wasm_sandbox.rs b/src/hyperlight_wasm/src/sandbox/proto_wasm_sandbox.rs index f6ec4d8..7e20011 100644 --- a/src/hyperlight_wasm/src/sandbox/proto_wasm_sandbox.rs +++ b/src/hyperlight_wasm/src/sandbox/proto_wasm_sandbox.rs @@ -27,16 +27,13 @@ use hyperlight_host::sandbox::ExtraAllowedSyscall; use hyperlight_host::sandbox_state::sandbox::{EvolvableSandbox, Sandbox}; use hyperlight_host::sandbox_state::transition::{MultiUseContextCallback, Noop}; use hyperlight_host::{ - int_counter_inc, int_gauge_dec, int_gauge_inc, new_error, GuestBinary, MultiUseSandbox, Result, - SandboxRunOptions, UninitializedSandbox, + new_error, GuestBinary, MultiUseSandbox, Result, SandboxRunOptions, UninitializedSandbox, }; +use super::metrics::{METRIC_ACTIVE_PROTO_WASM_SANDBOXES, METRIC_TOTAL_PROTO_WASM_SANDBOXES}; use super::sandbox_builder::SandboxBuilder; use super::wasm_sandbox::WasmSandbox; use crate::build_info::BuildInfo; -use crate::sandbox::metrics::SandboxMetric::{ - CurrentNumberOfProtoWasmSandboxes, TotalNumberOfProtoWasmSandboxes, -}; use crate::{HostPrintFn, ReturnType, ReturnValue}; /// A Hyperlight Sandbox with no Wasm run time loaded and no guest module code loaded. @@ -95,8 +92,8 @@ impl<'a> ProtoWasmSandbox { ) -> Result { BuildInfo::log(); let inner = UninitializedSandbox::new(guest_binary, cfg, opts, host_print_fn)?; - int_gauge_inc!(&CurrentNumberOfProtoWasmSandboxes); - int_counter_inc!(&TotalNumberOfProtoWasmSandboxes); + metrics::gauge!(METRIC_ACTIVE_PROTO_WASM_SANDBOXES).increment(1); + metrics::counter!(METRIC_TOTAL_PROTO_WASM_SANDBOXES).increment(1); Ok(Self { inner: Some(inner) }) } @@ -291,7 +288,7 @@ impl std::fmt::Debug for ProtoWasmSandbox { impl Drop for ProtoWasmSandbox { fn drop(&mut self) { - int_gauge_dec!(&CurrentNumberOfProtoWasmSandboxes); + metrics::gauge!(METRIC_ACTIVE_PROTO_WASM_SANDBOXES).decrement(1); } } diff --git a/src/hyperlight_wasm/src/sandbox/wasm_sandbox.rs b/src/hyperlight_wasm/src/sandbox/wasm_sandbox.rs index 9adb2e4..c961926 100644 --- a/src/hyperlight_wasm/src/sandbox/wasm_sandbox.rs +++ b/src/hyperlight_wasm/src/sandbox/wasm_sandbox.rs @@ -20,13 +20,11 @@ use hyperlight_host::func::call_ctx::MultiUseGuestCallContext; use hyperlight_host::sandbox::Callable; use hyperlight_host::sandbox_state::sandbox::{EvolvableSandbox, Sandbox}; use hyperlight_host::sandbox_state::transition::MultiUseContextCallback; -use hyperlight_host::{ - int_counter_inc, int_gauge_dec, int_gauge_inc, new_error, MultiUseSandbox, Result, -}; +use hyperlight_host::{new_error, MultiUseSandbox, Result}; use super::loaded_wasm_sandbox::LoadedWasmSandbox; -use crate::sandbox::metrics::SandboxMetric::{ - CurrentNumberOfWasmSandboxes, NumberOfLoadsOfWasmSandboxes, TotalNumberOfWasmSandboxes, +use crate::sandbox::metrics::{ + METRIC_ACTIVE_WASM_SANDBOXES, METRIC_SANDBOX_LOADS, METRIC_TOTAL_WASM_SANDBOXES, }; use crate::{ParameterValue, ReturnType, ReturnValue}; @@ -40,7 +38,7 @@ pub struct WasmSandbox { // inner is an Option as we need to take ownership of it // We implement drop on the WasmSandbox to decrement the count of Sandboxes when it is dropped // because of this we cannot implement drop without making inner an Option (alternatively we could make MultiUseSandbox Copy but that would introduce other issues) - pub(super) inner: Option, + inner: Option, } impl Sandbox for WasmSandbox {} @@ -51,8 +49,8 @@ impl WasmSandbox { /// The difference between this function and creating a `WasmSandbox` directly is that /// this function will increment the metrics for the number of `WasmSandbox`es in the system. pub(super) fn new(inner: MultiUseSandbox) -> Self { - int_gauge_inc!(&CurrentNumberOfWasmSandboxes); - int_counter_inc!(&TotalNumberOfWasmSandboxes); + metrics::gauge!(METRIC_ACTIVE_WASM_SANDBOXES).increment(1); + metrics::counter!(METRIC_TOTAL_WASM_SANDBOXES).increment(1); WasmSandbox { inner: Some(inner) } } @@ -92,11 +90,11 @@ impl WasmSandbox { }); let transition_func = MultiUseContextCallback::from(func); - int_counter_inc!(&NumberOfLoadsOfWasmSandboxes); match self.inner.take() { Some(sbox) => { let new_sbox: MultiUseSandbox = sbox.evolve(transition_func)?; + metrics::counter!(METRIC_SANDBOX_LOADS).increment(1); LoadedWasmSandbox::new(new_sbox) } None => Err(new_error!("WasmSandbox is None, cannot load module")), @@ -112,7 +110,7 @@ impl std::fmt::Debug for WasmSandbox { impl Drop for WasmSandbox { fn drop(&mut self) { - int_gauge_dec!(&CurrentNumberOfWasmSandboxes); + metrics::gauge!(METRIC_ACTIVE_WASM_SANDBOXES).decrement(1); } }