diff --git a/.gitignore b/.gitignore index bcbfeee..e9b395c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ .vscode/ target/ +logs/ +plonky2/ \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index cc9c117..5b6561d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -42,6 +42,17 @@ version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +[[package]] +name = "async-trait" +version = "0.1.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.72", +] + [[package]] name = "autocfg" version = "1.3.0" @@ -233,6 +244,15 @@ dependencies = [ "itertools 0.10.5", ] +[[package]] +name = "crossbeam-channel" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-deque" version = "0.8.5" @@ -264,6 +284,15 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + [[package]] name = "dyn-clone" version = "1.0.17" @@ -295,6 +324,58 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-core", + "futures-sink", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", +] + [[package]] name = "getrandom" version = "0.2.15" @@ -470,6 +551,15 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + [[package]] name = "memchr" version = "2.7.4" @@ -492,6 +582,16 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num" version = "0.4.3" @@ -527,6 +627,12 @@ dependencies = [ "rand", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-integer" version = "0.1.46" @@ -579,12 +685,76 @@ version = "11.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" +[[package]] +name = "opentelemetry" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6105e89802af13fdf48c49d7646d3b533a70e536d818aae7e78ba0433d01acb8" +dependencies = [ + "async-trait", + "crossbeam-channel", + "futures-channel", + "futures-executor", + "futures-util", + "js-sys", + "lazy_static", + "percent-encoding", + "pin-project", + "rand", + "serde", + "thiserror", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "peeking_take_while" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.72", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "plonky2" version = "0.2.0" @@ -643,6 +813,12 @@ name = "plonky2_util" version = "0.2.0" source = "git+https://github.com/okx/plonky2#140d97a8081cfae1d08e43199e13084c1acf1dae" +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.18" @@ -748,8 +924,17 @@ checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", - "regex-automata", - "regex-syntax", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", ] [[package]] @@ -760,9 +945,15 @@ checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.8.4", ] +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + [[package]] name = "regex-syntax" version = "0.8.4" @@ -835,12 +1026,36 @@ dependencies = [ "serde", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shlex" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + [[package]] name = "static_assertions" version = "1.1.0" @@ -869,6 +1084,67 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "thiserror" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.72", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tiny-keccak" version = "2.0.2" @@ -888,6 +1164,115 @@ dependencies = [ "serde_json", ] +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-appender" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" +dependencies = [ + "crossbeam-channel", + "thiserror", + "time", + "tracing-subscriber", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.72", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-flame" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bae117ee14789185e129aaee5d93750abe67fdc5a9a62650452bfe4e122a3a9" +dependencies = [ + "lazy_static", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tracing-log" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-opentelemetry" +version = "0.17.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbbe89715c1dbbb790059e2565353978564924ee85017b5fff365c872ff6721f" +dependencies = [ + "once_cell", + "opentelemetry", + "tracing", + "tracing-core", + "tracing-log 0.1.4", + "tracing-subscriber", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log 0.2.0", +] + [[package]] name = "uint" version = "0.9.5" @@ -916,6 +1301,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "version_check" version = "0.9.5" @@ -1004,6 +1395,22 @@ dependencies = [ "rustix", ] +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + [[package]] name = "winapi-util" version = "0.1.8" @@ -1013,6 +1420,12 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-sys" version = "0.52.0" @@ -1149,4 +1562,21 @@ dependencies = [ "rayon", "serde", "serde_json", + "tracing", + "zk-por-tracing", +] + +[[package]] +name = "zk-por-tracing" +version = "0.1.0" +dependencies = [ + "async-trait", + "opentelemetry", + "serde_json", + "thiserror", + "tracing", + "tracing-appender", + "tracing-flame", + "tracing-opentelemetry", + "tracing-subscriber", ] diff --git a/Cargo.toml b/Cargo.toml index a5ef781..e7092d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,10 +2,12 @@ members = [ "crates/zk-por-core", "crates/zk-por-api", + "crates/zk-por-tracing" ] resolver = "2" [workspace.package] +version="0.1.0" edition = "2021" license = "MIT OR Apache-2.0" homepage = "https://github.com/okx/proof-of-reserves-v2.git" @@ -14,8 +16,15 @@ keywords = ["crypto", "por", "plonky2"] categories = ["por"] [workspace.dependencies] +# zkp plonky2 = { git = "https://github.com/okx/plonky2"} plonky2_field = { git = "https://github.com/okx/plonky2"} +# computing +rayon = "1.8" +# data serde = "1.0.204" serde_json = "1.0.120" -rayon = "1.8" +# misc +thiserror = "1.0" +tracing = "0.1" +opentelemetry = { version = "0.17", features = ["serialize"]} \ No newline at end of file diff --git a/crates/zk-por-core/Cargo.toml b/crates/zk-por-core/Cargo.toml index 91ab1e9..4d19c17 100644 --- a/crates/zk-por-core/Cargo.toml +++ b/crates/zk-por-core/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "zk-por-core" description = "zk por circuits and proving logic" -version = "0.1.0" +version ={workspace=true} authors = [ ] @@ -17,12 +17,14 @@ categories.workspace = true default = [] [dependencies] +zk-por-tracing={path="../zk-por-tracing"} plonky2={workspace=true} plonky2_field={workspace=true} log = "0.4.17" serde={workspace=true} serde_json={workspace=true} rayon={workspace=true} +tracing={workspace=true} [dev-dependencies] criterion = { version = "0.5.1", default-features = false } diff --git a/crates/zk-por-core/src/main.rs b/crates/zk-por-core/src/main.rs index a285917..e7e3c33 100644 --- a/crates/zk-por-core/src/main.rs +++ b/crates/zk-por-core/src/main.rs @@ -1,3 +1,15 @@ +use tracing::{debug, Level}; +use zk_por_tracing::{init_tracing, TraceConfig}; + pub fn main() { - println!("It works!"); + let cfg = TraceConfig { + prefix: "zkpor".to_string(), + dir: "logs".to_string(), + level: Level::DEBUG, + console: false, + flame: false, + }; + let guard = init_tracing(cfg); + debug!("tracing works"); + drop(guard) } diff --git a/crates/zk-por-core/src/merkle_sum_prover/prover.rs b/crates/zk-por-core/src/merkle_sum_prover/prover.rs index 4796779..957345b 100644 --- a/crates/zk-por-core/src/merkle_sum_prover/prover.rs +++ b/crates/zk-por-core/src/merkle_sum_prover/prover.rs @@ -22,7 +22,7 @@ use crate::{ /// A merkle sum tree prover with a batch id representing its index in the recursive proof tree and a Vec of accounts representing accounts in this batch. #[derive(Clone, Debug)] pub struct MerkleSumTreeProver { - batch_id: usize, + // batch_id: usize, accounts: Vec, } @@ -116,7 +116,10 @@ pub mod test { let path = "../../test-data/batch0.json"; let accounts = read_json_into_accounts_vec(path); - let prover = MerkleSumTreeProver { batch_id: 0, accounts }; + let prover = MerkleSumTreeProver { + // batch_id: 0, + accounts, + }; prover.build_and_set_merkle_tree_targets(&mut builder, &mut pw); @@ -138,7 +141,10 @@ pub mod test { pub fn test_get_proof() { let path = "../../test-data/batch0.json"; let accounts = read_json_into_accounts_vec(path); - let prover = MerkleSumTreeProver { batch_id: 0, accounts }; + let prover = MerkleSumTreeProver { + // batch_id: 0, + accounts, + }; let _proof = prover.get_proof(); } diff --git a/crates/zk-por-tracing/Cargo.toml b/crates/zk-por-tracing/Cargo.toml new file mode 100644 index 0000000..306c5bc --- /dev/null +++ b/crates/zk-por-tracing/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "zk-por-tracing" +description = "zk por tracing" +version = {workspace=true} + +readme = "README.md" +edition.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true +keywords.workspace = true +categories.workspace = true + +[features] +default = [] + +[dependencies] +thiserror.workspace = true +serde_json.workspace = true +tracing.workspace = true +opentelemetry.workspace = true +async-trait = "0.1" +tracing-subscriber = { version = "0.3", features = ["env-filter"] } +tracing-appender = "0.2" +tracing-flame = "0.2" +tracing-opentelemetry = "0.17" + + + diff --git a/crates/zk-por-tracing/src/lib.rs b/crates/zk-por-tracing/src/lib.rs new file mode 100644 index 0000000..a72cc11 --- /dev/null +++ b/crates/zk-por-tracing/src/lib.rs @@ -0,0 +1,57 @@ +pub mod opentelemetry; + +use crate::opentelemetry::exporter::stdout; +use tracing::Level; +pub use tracing_appender::non_blocking::WorkerGuard; +use tracing_appender::rolling; +use tracing_flame::FlameLayer; +use tracing_opentelemetry::OpenTelemetryLayer; +use tracing_subscriber::{fmt, prelude::*}; + +pub struct TraceConfig { + pub prefix: String, + pub dir: String, + pub level: Level, + pub console: bool, + pub flame: bool, +} + +pub fn init_tracing(config: TraceConfig) -> Vec { + let prefix = config.prefix; + let dir = config.dir; + let level = config.level; + let console = config.console; + let flame = config.flame; + + let mut guards = vec![]; + let (fmt_writer, fmt_guard) = tracing_appender::non_blocking(rolling::daily(&dir, &prefix)); + guards.push(fmt_guard); + let (telemetry_writer, telemetry_guard) = + tracing_appender::non_blocking(rolling::daily(&dir, prefix.clone() + ".telemetry")); + guards.push(telemetry_guard); + let tracer = stdout::new_pipeline().with_writer(telemetry_writer).install_simple(); + let layered = tracing_subscriber::fmt() + .with_max_level(level) + .with_writer(fmt_writer) + .with_ansi(false) + .finish() + .with(OpenTelemetryLayer::new(tracer)); + if flame { + let (folded_writer, folded_guard) = + tracing_appender::non_blocking(rolling::daily(&dir, prefix.clone() + ".folded")); + guards.push(folded_guard); + if console { + layered.with(fmt::Layer::default()).with(FlameLayer::new(folded_writer)).init(); + } else { + layered.with(FlameLayer::new(folded_writer)).init() + } + } else { + if console { + layered.with(fmt::Layer::default()).init(); + } else { + layered.init() + } + } + + guards +} diff --git a/crates/zk-por-tracing/src/opentelemetry.rs b/crates/zk-por-tracing/src/opentelemetry.rs new file mode 100644 index 0000000..af68cc2 --- /dev/null +++ b/crates/zk-por-tracing/src/opentelemetry.rs @@ -0,0 +1 @@ +pub mod exporter; diff --git a/crates/zk-por-tracing/src/opentelemetry/exporter.rs b/crates/zk-por-tracing/src/opentelemetry/exporter.rs new file mode 100644 index 0000000..76c718c --- /dev/null +++ b/crates/zk-por-tracing/src/opentelemetry/exporter.rs @@ -0,0 +1 @@ +pub mod stdout; diff --git a/crates/zk-por-tracing/src/opentelemetry/exporter/stdout.rs b/crates/zk-por-tracing/src/opentelemetry/exporter/stdout.rs new file mode 100644 index 0000000..ab8a096 --- /dev/null +++ b/crates/zk-por-tracing/src/opentelemetry/exporter/stdout.rs @@ -0,0 +1,157 @@ +//! # Stdout Span Exporter +//! +//! The stdout [`SpanExporter`] writes debug printed [`Span`]s to its configured +//! [`Write`] instance. By default it will write to [`Stdout`]. +//! +//! [`SpanExporter`]: super::SpanExporter +//! [`Span`]: crate::trace::Span +//! [`Write`]: Write +//! [`Stdout`]: Stdout +//! +//! # Examples +//! +//! ```no_run +//! use opentelemetry::trace::Tracer; +//! use opentelemetry::sdk::export::trace::stdout; +//! use opentelemetry::global::shutdown_tracer_provider; +//! +//! fn main() { +//! let tracer = stdout::new_pipeline() +//! .with_pretty_print(true) +//! .install_simple(); +//! +//! tracer.in_span("doing_work", |cx| { +//! // Traced app logic here... +//! }); +//! +//! shutdown_tracer_provider(); // sending remaining spans +//! } +//! ``` +use async_trait::async_trait; +use opentelemetry::{ + global, sdk, + sdk::export::{ + trace::{ExportResult, SpanData, SpanExporter}, + ExportError, + }, + trace::TracerProvider, +}; +use std::{ + fmt::Debug, + io::{stdout, Stdout, Write}, +}; + +/// Pipeline builder +#[derive(Debug)] +pub struct PipelineBuilder { + pretty_print: bool, + trace_config: Option, + writer: W, +} + +/// Create a new stdout exporter pipeline builder. +pub fn new_pipeline() -> PipelineBuilder { + PipelineBuilder::default() +} + +impl Default for PipelineBuilder { + /// Return the default pipeline builder. + fn default() -> Self { + Self { pretty_print: false, trace_config: None, writer: stdout() } + } +} + +impl PipelineBuilder { + /// Specify the pretty print setting. + pub fn with_pretty_print(mut self, pretty_print: bool) -> Self { + self.pretty_print = pretty_print; + self + } + + /// Assign the SDK trace configuration. + pub fn with_trace_config(mut self, config: sdk::trace::Config) -> Self { + self.trace_config = Some(config); + self + } + + /// Specify the writer to use. + pub fn with_writer(self, writer: T) -> PipelineBuilder { + PipelineBuilder { pretty_print: self.pretty_print, trace_config: self.trace_config, writer } + } +} + +impl PipelineBuilder +where + W: Write + Debug + Send + 'static, +{ + /// Install the stdout exporter pipeline with the recommended defaults. + pub fn install_simple(mut self) -> sdk::trace::Tracer { + let exporter = Exporter::new(self.writer, self.pretty_print); + + let mut provider_builder = + sdk::trace::TracerProvider::builder().with_simple_exporter(exporter); + if let Some(config) = self.trace_config.take() { + provider_builder = provider_builder.with_config(config); + } + let provider = provider_builder.build(); + + let tracer = + provider.versioned_tracer("opentelemetry", Some(env!("CARGO_PKG_VERSION")), None); + let _ = global::set_tracer_provider(provider); + + tracer + } +} + +/// A [`SpanExporter`] that writes to [`Stdout`] or other configured [`Write`]. +/// +/// [`SpanExporter`]: super::SpanExporter +/// [`Write`]: Write +/// [`Stdout`]: Stdout +#[derive(Debug)] +pub struct Exporter { + writer: W, + pretty_print: bool, +} + +impl Exporter { + /// Create a new stdout `Exporter`. + pub fn new(writer: W, pretty_print: bool) -> Self { + Self { writer, pretty_print } + } +} + +#[async_trait] +impl SpanExporter for Exporter +where + W: Write + Debug + Send + 'static, +{ + /// Export spans to stdout + async fn export(&mut self, batch: Vec) -> ExportResult { + for span in batch { + let json = if self.pretty_print { + serde_json::to_string_pretty(&span).map_err::(Into::into)? + } else { + serde_json::to_string(&span).map_err::(Into::into)? + }; + self.writer.write_all(json.as_bytes()).map_err::(Into::into)?; + self.writer.write_all("\n".as_bytes()).map_err::(Into::into)?; + } + + Ok(()) + } +} + +/// Stdout exporter's error +#[derive(thiserror::Error, Debug)] +#[error(transparent)] +enum Error { + Json(#[from] serde_json::Error), + Io(#[from] std::io::Error), +} + +impl ExportError for Error { + fn exporter_name(&self) -> &'static str { + "stdout" + } +}