diff --git a/Cargo.lock b/Cargo.lock index e8d7d561..9c421585 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -59,6 +59,12 @@ dependencies = [ "libc", ] +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + [[package]] name = "ansi_term" version = "0.12.1" @@ -68,6 +74,56 @@ dependencies = [ "winapi", ] +[[package]] +name = "anstream" +version = "0.6.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.59.0", +] + [[package]] name = "anyhow" version = "1.0.98" @@ -326,6 +382,77 @@ dependencies = [ "fs_extra", ] +[[package]] +name = "axum" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" +dependencies = [ + "async-trait", + "axum-core", + "bytes", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "hyper 1.6.0", + "hyper-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-core" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-server" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "495c05f60d6df0093e8fb6e74aa5846a0ad06abaf96d76166283720bf740f8ab" +dependencies = [ + "bytes", + "fs-err", + "http 1.3.1", + "http-body 1.0.1", + "hyper 1.6.0", + "hyper-util", + "tokio", + "tower-service", +] + [[package]] name = "backtrace" version = "0.3.74" @@ -530,6 +657,12 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + [[package]] name = "cc" version = "1.2.21" @@ -575,6 +708,33 @@ dependencies = [ "windows-link", ] +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + [[package]] name = "clang-sys" version = "1.8.1" @@ -586,6 +746,46 @@ dependencies = [ "libloading", ] +[[package]] +name = "clap" +version = "4.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "clap_lex" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" + [[package]] name = "cmake" version = "0.1.54" @@ -595,6 +795,12 @@ dependencies = [ "cc", ] +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + [[package]] name = "concurrent-queue" version = "2.5.0" @@ -650,6 +856,44 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "criterion" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" +dependencies = [ + "anes", + "cast", + "ciborium", + "clap", + "criterion-plot", + "futures", + "is-terminal", + "itertools 0.10.5", + "num-traits", + "once_cell", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "tokio", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +dependencies = [ + "cast", + "itertools 0.10.5", +] + [[package]] name = "crossbeam-channel" version = "0.5.15" @@ -659,6 +903,25 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -671,6 +934,22 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" +[[package]] +name = "ctor" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4735f265ba6a1188052ca32d461028a7d1125868be18e287e756019da7607b5" +dependencies = [ + "ctor-proc-macro", + "dtor", +] + +[[package]] +name = "ctor-proc-macro" +version = "0.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f211af61d8efdd104f96e57adf5e426ba1bc3ed7a4ead616e15e5881fd79c4d" + [[package]] name = "darling" version = "0.20.11" @@ -754,6 +1033,7 @@ name = "datadog-opentelemetry" version = "0.0.1" dependencies = [ "assert_unordered", + "criterion", "data-pipeline", "datadog-opentelemetry", "datadog-opentelemetry-mappings", @@ -770,6 +1050,32 @@ dependencies = [ "tokio", ] +[[package]] +name = "datadog-opentelemetry-benches" +version = "0.0.1" +dependencies = [ + "axum", + "axum-server", + "clap", + "criterion", + "ctor", + "datadog-opentelemetry", + "dd-trace", + "futures", + "opentelemetry", + "opentelemetry-http", + "opentelemetry-otlp", + "opentelemetry-stdout", + "opentelemetry_sdk", + "serde", + "serde_json", + "tokio", + "tower", + "tower-http", + "tracing", + "tracing-subscriber", +] + [[package]] name = "datadog-opentelemetry-mappings" version = "0.0.1" @@ -1023,6 +1329,21 @@ dependencies = [ "tracing", ] +[[package]] +name = "dtor" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97cbdf2ad6846025e8e25df05171abfb30e3ababa12ee0a0e44b9bbe570633a8" +dependencies = [ + "dtor-proc-macro", +] + +[[package]] +name = "dtor-proc-macro" +version = "0.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7454e41ff9012c00d53cf7f475c5e3afa3b91b7c90568495495e8d9bf47a1055" + [[package]] name = "dunce" version = "1.0.5" @@ -1141,6 +1462,16 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs-err" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d7be93788013f265201256d58f04936a8079ad5dc898743aa20525f503b683" +dependencies = [ + "autocfg", + "tokio", +] + [[package]] name = "fs_extra" version = "1.3.0" @@ -1319,6 +1650,16 @@ dependencies = [ "tracing", ] +[[package]] +name = "half" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" +dependencies = [ + "cfg-if", + "crunchy", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -1357,6 +1698,12 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + [[package]] name = "hex" version = "0.4.3" @@ -1835,6 +2182,32 @@ version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +[[package]] +name = "is-terminal" +version = "0.4.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" +dependencies = [ + "hermit-abi 0.5.2", + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.11.0" @@ -2036,6 +2409,12 @@ dependencies = [ "regex-automata 0.1.10", ] +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + [[package]] name = "memchr" version = "2.7.4" @@ -2111,6 +2490,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-conv" version = "0.1.0" @@ -2141,6 +2530,18 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "once_cell_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" + +[[package]] +name = "oorandom" +version = "11.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" + [[package]] name = "openssl-probe" version = "0.1.6" @@ -2183,9 +2584,41 @@ dependencies = [ "bytes", "http 1.3.1", "opentelemetry", + "reqwest", "tracing", ] +[[package]] +name = "opentelemetry-otlp" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bef114c6d41bea83d6dc60eb41720eedd0261a67af57b66dd2b84ac46c01d91" +dependencies = [ + "async-trait", + "futures-core", + "http 1.3.1", + "opentelemetry", + "opentelemetry-http", + "opentelemetry-proto", + "opentelemetry_sdk", + "prost", + "reqwest", + "thiserror 2.0.12", + "tracing", +] + +[[package]] +name = "opentelemetry-proto" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f8870d3024727e99212eb3bb1762ec16e255e3e6f58eeb3dc8db1aa226746d" +dependencies = [ + "opentelemetry", + "opentelemetry_sdk", + "prost", + "tonic", +] + [[package]] name = "opentelemetry-semantic-conventions" version = "0.15.0" @@ -2244,6 +2677,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "parking" version = "2.2.1" @@ -2378,6 +2817,34 @@ dependencies = [ "futures-io", ] +[[package]] +name = "plotters" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" + +[[package]] +name = "plotters-svg" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" +dependencies = [ + "plotters-backend", +] + [[package]] name = "polling" version = "3.7.4" @@ -2386,7 +2853,7 @@ checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f" dependencies = [ "cfg-if", "concurrent-queue", - "hermit-abi", + "hermit-abi 0.4.0", "pin-project-lite", "rustix", "tracing", @@ -2616,6 +3083,26 @@ dependencies = [ "getrandom 0.3.2", ] +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "redox_syscall" version = "0.5.12" @@ -2689,6 +3176,7 @@ dependencies = [ "base64 0.22.1", "bytes", "encoding_rs", + "futures-channel", "futures-core", "futures-util", "h2", @@ -3002,6 +3490,16 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_path_to_error" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59fab13f937fa393d08645bf3a84bdfe86e296747b506ada67bb15f10f218b2a" +dependencies = [ + "itoa", + "serde", +] + [[package]] name = "serde_regex" version = "1.1.0" @@ -3385,6 +3883,16 @@ dependencies = [ "zerovec", ] +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "tinyvec" version = "1.9.0" @@ -3463,6 +3971,27 @@ dependencies = [ "tokio", ] +[[package]] +name = "tonic" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" +dependencies = [ + "async-trait", + "base64 0.22.1", + "bytes", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "percent-encoding", + "pin-project", + "prost", + "tokio-stream", + "tower-layer", + "tower-service", + "tracing", +] + [[package]] name = "tower" version = "0.5.2" @@ -3476,6 +4005,23 @@ dependencies = [ "tokio", "tower-layer", "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +dependencies = [ + "bitflags", + "bytes", + "http 1.3.1", + "http-body 1.0.1", + "pin-project-lite", + "tower-layer", + "tower-service", + "tracing", ] [[package]] @@ -3496,6 +4042,7 @@ version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -3519,6 +4066,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", + "valuable", +] + +[[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]] @@ -3528,12 +4087,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "matchers", + "nu-ansi-term", "once_cell", "regex", "sharded-slab", + "smallvec", "thread_local", "tracing", "tracing-core", + "tracing-log", ] [[package]] @@ -3590,6 +4152,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "uuid" version = "1.16.0" @@ -3599,6 +4167,12 @@ dependencies = [ "getrandom 0.3.2", ] +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + [[package]] name = "value-bag" version = "1.11.1" diff --git a/Cargo.toml b/Cargo.toml index 78184345..eaf6c136 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ members = [ "datadog-opentelemetry", "datadog-opentelemetry/examples/propagator", + "datadog-opentelemetry-benches", "datadog-opentelemetry-mappings", "dd-trace", "dd-trace-propagation", diff --git a/LICENSE-3rdparty.csv b/LICENSE-3rdparty.csv index 05b3893f..cbd43a4d 100644 --- a/LICENSE-3rdparty.csv +++ b/LICENSE-3rdparty.csv @@ -6,7 +6,13 @@ aho-corasick,https://github.com/BurntSushi/aho-corasick,Unlicense OR MIT,Andrew allocator-api2,https://github.com/zakarumych/allocator-api2,MIT OR Apache-2.0,Zakarum android-tzdata,https://github.com/RumovZ/android-tzdata,MIT OR Apache-2.0,RumovZ android_system_properties,https://github.com/nical/android_system_properties,MIT OR Apache-2.0,Nicolas Silva +anes,https://github.com/zrzka/anes-rs,MIT OR Apache-2.0,Robert Vojta ansi_term,https://github.com/ogham/rust-ansi-term,MIT,"ogham@bsago.me, Ryan Scheel (Havvy) , Josh Triplett " +anstream,https://github.com/rust-cli/anstyle,MIT OR Apache-2.0,The anstream Authors +anstyle,https://github.com/rust-cli/anstyle,MIT OR Apache-2.0,The anstyle Authors +anstyle-parse,https://github.com/rust-cli/anstyle,MIT OR Apache-2.0,The anstyle-parse Authors +anstyle-query,https://github.com/rust-cli/anstyle,MIT OR Apache-2.0,The anstyle-query Authors +anstyle-wincon,https://github.com/rust-cli/anstyle,MIT OR Apache-2.0,The anstyle-wincon Authors anyhow,https://github.com/dtolnay/anyhow,MIT OR Apache-2.0,David Tolnay arc-swap,https://github.com/vorner/arc-swap,MIT OR Apache-2.0,Michal 'vorner' Vaner ascii-canvas,https://github.com/nikomatsakis/ascii-canvas,Apache-2.0 OR MIT,Niko Matsakis @@ -26,6 +32,7 @@ async-trait,https://github.com/dtolnay/async-trait,MIT OR Apache-2.0,David Tolna atomic-waker,https://github.com/smol-rs/atomic-waker,Apache-2.0 OR MIT,"Stjepan Glavina , Contributors to futures-rs" aws-lc-rs,https://github.com/aws/aws-lc-rs,ISC AND (Apache-2.0 OR ISC),AWS-LibCrypto aws-lc-sys,https://github.com/aws/aws-lc-rs,ISC AND (Apache-2.0 OR ISC) AND OpenSSL,AWS-LC +axum-core,https://github.com/tokio-rs/axum,MIT,The axum-core Authors backtrace,https://github.com/rust-lang/backtrace-rs,MIT OR Apache-2.0,The Rust Project Developers base64,https://github.com/marshallpierce/rust-base64,MIT OR Apache-2.0,"Alice Maz , Marshall Pierce " base64,https://github.com/marshallpierce/rust-base64,MIT OR Apache-2.0,Marshall Pierce @@ -43,19 +50,32 @@ cadence,https://github.com/56quarters/cadence,Apache-2.0 OR MIT,Nick Pillitteri camino,https://github.com/camino-rs/camino,MIT OR Apache-2.0,"Without Boats , Ashley Williams , Steve Klabnik , Rain " cargo-platform,https://github.com/rust-lang/cargo,MIT OR Apache-2.0,The cargo-platform Authors cargo_metadata,https://github.com/oli-obk/cargo_metadata,MIT,Oliver Schneider +cast,https://github.com/japaric/cast.rs,MIT OR Apache-2.0,Jorge Aparicio cc,https://github.com/rust-lang/cc-rs,MIT OR Apache-2.0,Alex Crichton cexpr,https://github.com/jethrogb/rust-cexpr,Apache-2.0 OR MIT,Jethro Beekman cfg-if,https://github.com/alexcrichton/cfg-if,MIT OR Apache-2.0,Alex Crichton chrono,https://github.com/chronotope/chrono,MIT OR Apache-2.0,The chrono Authors +ciborium,https://github.com/enarx/ciborium,Apache-2.0,Nathaniel McCallum +ciborium-io,https://github.com/enarx/ciborium,Apache-2.0,Nathaniel McCallum +ciborium-ll,https://github.com/enarx/ciborium,Apache-2.0,Nathaniel McCallum clang-sys,https://github.com/KyleMayes/clang-sys,Apache-2.0,Kyle Mayes +clap,https://github.com/clap-rs/clap,MIT OR Apache-2.0,The clap Authors +clap_builder,https://github.com/clap-rs/clap,MIT OR Apache-2.0,The clap_builder Authors +clap_derive,https://github.com/clap-rs/clap,MIT OR Apache-2.0,The clap_derive Authors +clap_lex,https://github.com/clap-rs/clap,MIT OR Apache-2.0,The clap_lex Authors +colorchoice,https://github.com/rust-cli/anstyle,MIT OR Apache-2.0,The colorchoice Authors concurrent-queue,https://github.com/smol-rs/concurrent-queue,Apache-2.0 OR MIT,"Stjepan Glavina , Taiki Endo , John Nunley " const_format,https://github.com/rodrimati1992/const_format_crates,Zlib,rodrimati1992 const_format_proc_macros,https://github.com/rodrimati1992/const_format_crates,Zlib,rodrimati1992 core-foundation,https://github.com/servo/core-foundation-rs,MIT OR Apache-2.0,The Servo Project Developers core-foundation-sys,https://github.com/servo/core-foundation-rs,MIT OR Apache-2.0,The Servo Project Developers +criterion-plot,https://github.com/bheisler/criterion.rs,MIT OR Apache-2.0,"Jorge Aparicio , Brook Heisler " crossbeam-channel,https://github.com/crossbeam-rs/crossbeam,MIT OR Apache-2.0,The crossbeam-channel Authors +crossbeam-deque,https://github.com/crossbeam-rs/crossbeam,MIT OR Apache-2.0,The crossbeam-deque Authors +crossbeam-epoch,https://github.com/crossbeam-rs/crossbeam,MIT OR Apache-2.0,The crossbeam-epoch Authors crossbeam-utils,https://github.com/crossbeam-rs/crossbeam,MIT OR Apache-2.0,The crossbeam-utils Authors crunchy,https://github.com/eira-fransham/crunchy,MIT,Eira Fransham +ctor-proc-macro,https://github.com/mmastrac/rust-ctor,Apache-2.0 OR MIT,Matt Mastracci darling,https://github.com/TedDriggs/darling,MIT,Ted Driggs darling_core,https://github.com/TedDriggs/darling,MIT,Ted Driggs darling_macro,https://github.com/TedDriggs/darling,MIT,Ted Driggs @@ -76,6 +96,8 @@ dirs-sys-next,https://github.com/xdg-rs/dirs/tree/master/dirs-sys,MIT OR Apache- displaydoc,https://github.com/yaahc/displaydoc,MIT OR Apache-2.0,Jane Lusby docker_credential,https://github.com/keirlawson/docker_credential,MIT OR Apache-2.0,Keir Lawson dogstatsd-client,https://github.com/Datadog/libdatadog,Apache-2.0,The dogstatsd-client Authors +dtor,https://github.com/mmastrac/rust-ctor,Apache-2.0 OR MIT,Matt Mastracci +dtor-proc-macro,https://github.com/mmastrac/rust-ctor,Apache-2.0 OR MIT,Matt Mastracci either,https://github.com/rayon-rs/either,MIT OR Apache-2.0,bluss ena,https://github.com/rust-lang/ena,MIT OR Apache-2.0,Niko Matsakis encoding_rs,https://github.com/hsivonen/encoding_rs,(Apache-2.0 OR MIT) AND BSD-3-Clause,Henri Sivonen @@ -90,6 +112,7 @@ fixedbitset,https://github.com/petgraph/fixedbitset,MIT OR Apache-2.0,bluss fnv,https://github.com/servo/rust-fnv,Apache-2.0 OR MIT,Alex Crichton foldhash,https://github.com/orlp/foldhash,Zlib,Orson Peters form_urlencoded,https://github.com/servo/rust-url,MIT OR Apache-2.0,The rust-url developers +fs-err,https://github.com/andrewhickman/fs-err,MIT OR Apache-2.0,Andrew Hickman futures,https://github.com/rust-lang/futures-rs,MIT OR Apache-2.0,The futures Authors futures-channel,https://github.com/rust-lang/futures-rs,MIT OR Apache-2.0,The futures-channel Authors futures-core,https://github.com/rust-lang/futures-rs,MIT OR Apache-2.0,The futures-core Authors @@ -105,6 +128,7 @@ gimli,https://github.com/gimli-rs/gimli,MIT OR Apache-2.0,The gimli Authors glob,https://github.com/rust-lang/glob,MIT OR Apache-2.0,The Rust Project Developers gloo-timers,https://github.com/rustwasm/gloo/tree/master/crates/timers,MIT OR Apache-2.0,Rust and WebAssembly Working Group h2,https://github.com/hyperium/h2,MIT,"Carl Lerche , Sean McArthur " +half,https://github.com/VoidStarKat/half-rs,MIT OR Apache-2.0,Kathryn Long hashbrown,https://github.com/rust-lang/hashbrown,MIT OR Apache-2.0,Amanieu d'Antras heck,https://github.com/withoutboats/heck,MIT OR Apache-2.0,The heck Authors hermit-abi,https://github.com/hermit-os/hermit-rs,MIT OR Apache-2.0,Stefan Lankes @@ -142,6 +166,8 @@ indexmap,https://github.com/bluss/indexmap,Apache-2.0 OR MIT,The indexmap Author indexmap,https://github.com/indexmap-rs/indexmap,Apache-2.0 OR MIT,The indexmap Authors ipconfig,https://github.com/liranringel/ipconfig,MIT OR Apache-2.0,Liran Ringel ipnet,https://github.com/krisprice/ipnet,MIT OR Apache-2.0,Kris Price +is-terminal,https://github.com/sunfishcode/is-terminal,MIT,"softprops , Dan Gohman " +is_terminal_polyfill,https://github.com/polyfill-rs/is_terminal_polyfill,MIT OR Apache-2.0,The is_terminal_polyfill Authors itertools,https://github.com/rust-itertools/itertools,MIT OR Apache-2.0,bluss itoa,https://github.com/dtolnay/itoa,MIT OR Apache-2.0,David Tolnay jobserver,https://github.com/rust-lang/jobserver-rs,MIT OR Apache-2.0,Alex Crichton @@ -162,6 +188,7 @@ log,https://github.com/rust-lang/log,MIT OR Apache-2.0,The Rust Project Develope lru,https://github.com/jeromefroe/lru-rs,MIT,Jerome Froelich lru-cache,https://github.com/contain-rs/lru-cache,MIT OR Apache-2.0,Stepan Koltsov matchers,https://github.com/hawkw/matchers,MIT,Eliza Weisman +matchit,https://github.com/ibraheemdev/matchit,MIT AND BSD-3-Clause,Ibraheem Ahmed memchr,https://github.com/BurntSushi/memchr,Unlicense OR MIT,"Andrew Gallant , bluss" memfd,https://github.com/lucab/memfd-rs,MIT OR Apache-2.0,"Luca Bruno , Simonas Kazlauskas " mime,https://github.com/hyperium/mime,MIT OR Apache-2.0,Sean McArthur @@ -171,18 +198,23 @@ mio,https://github.com/tokio-rs/mio,MIT,"Carl Lerche , Thomas new_debug_unreachable,https://github.com/mbrubeck/rust-debug-unreachable,MIT,"Matt Brubeck , Jonathan Reem " nix,https://github.com/nix-rust/nix,MIT,The nix-rust Project Developers nom,https://github.com/Geal/nom,MIT,contact@geoffroycouprie.com +nu-ansi-term,https://github.com/nushell/nu-ansi-term,MIT,"ogham@bsago.me, Ryan Scheel (Havvy) , Josh Triplett , The Nushell Project Developers" num-conv,https://github.com/jhpratt/num-conv,MIT OR Apache-2.0,Jacob Pratt num-traits,https://github.com/rust-num/num-traits,MIT OR Apache-2.0,The Rust Project Developers object,https://github.com/gimli-rs/object,Apache-2.0 OR MIT,The object Authors once_cell,https://github.com/matklad/once_cell,MIT OR Apache-2.0,Aleksey Kladov +once_cell_polyfill,https://github.com/polyfill-rs/once_cell_polyfill,MIT OR Apache-2.0,The once_cell_polyfill Authors +oorandom,https://hg.sr.ht/~icefox/oorandom,MIT,Simon Heath openssl-probe,https://github.com/alexcrichton/openssl-probe,MIT OR Apache-2.0,Alex Crichton opentelemetry,https://github.com/open-telemetry/opentelemetry-rust,Apache-2.0,The opentelemetry Authors opentelemetry-appender-tracing,https://github.com/open-telemetry/opentelemetry-rust/tree/main/opentelemetry-appender-tracing,Apache-2.0,The opentelemetry-appender-tracing Authors opentelemetry-http,https://github.com/open-telemetry/opentelemetry-rust,Apache-2.0,The opentelemetry-http Authors +opentelemetry-proto,https://github.com/open-telemetry/opentelemetry-rust/tree/main/opentelemetry-proto,Apache-2.0,The opentelemetry-proto Authors opentelemetry-semantic-conventions,https://github.com/open-telemetry/opentelemetry-rust/tree/main/opentelemetry-semantic-conventions,Apache-2.0,The opentelemetry-semantic-conventions Authors opentelemetry-stdout,https://github.com/open-telemetry/opentelemetry-rust/tree/main/opentelemetry-stdout,Apache-2.0,The opentelemetry-stdout Authors opentelemetry_sdk,https://github.com/open-telemetry/opentelemetry-rust,Apache-2.0,The opentelemetry_sdk Authors option-ext,https://github.com/soc/option-ext,MPL-2.0,Simon Ochsenreither +overload,https://github.com/danaugrs/overload,MIT,Daniel Salvadori parking,https://github.com/smol-rs/parking,Apache-2.0 OR MIT,"Stjepan Glavina , The Rust Project Developers" parking_lot,https://github.com/Amanieu/parking_lot,MIT OR Apache-2.0,Amanieu d'Antras parking_lot_core,https://github.com/Amanieu/parking_lot,MIT OR Apache-2.0,Amanieu d'Antras @@ -198,6 +230,9 @@ pin-project-internal,https://github.com/taiki-e/pin-project,Apache-2.0 OR MIT,Th pin-project-lite,https://github.com/taiki-e/pin-project-lite,Apache-2.0 OR MIT,The pin-project-lite Authors pin-utils,https://github.com/rust-lang-nursery/pin-utils,MIT OR Apache-2.0,Josef Brandl piper,https://github.com/smol-rs/piper,MIT OR Apache-2.0,"Stjepan Glavina , John Nunley " +plotters,https://github.com/plotters-rs/plotters,MIT,Hao Hou +plotters-backend,https://github.com/plotters-rs/plotters,MIT,Hao Hou +plotters-svg,https://github.com/plotters-rs/plotters,MIT,Hao Hou polling,https://github.com/smol-rs/polling,Apache-2.0 OR MIT,"Stjepan Glavina , John Nunley " powerfmt,https://github.com/jhpratt/powerfmt,MIT OR Apache-2.0,Jacob Pratt ppv-lite86,https://github.com/cryptocorrosion/cryptocorrosion,MIT OR Apache-2.0,The CryptoCorrosion Contributors @@ -214,6 +249,8 @@ r-efi,https://github.com/r-efi/r-efi,MIT OR Apache-2.0 OR LGPL-2.1-or-later,The rand,https://github.com/rust-random/rand,MIT OR Apache-2.0,"The Rand Project Developers, The Rust Project Developers" rand_chacha,https://github.com/rust-random/rand,MIT OR Apache-2.0,"The Rand Project Developers, The Rust Project Developers, The CryptoCorrosion Contributors" rand_core,https://github.com/rust-random/rand,MIT OR Apache-2.0,"The Rand Project Developers, The Rust Project Developers" +rayon,https://github.com/rayon-rs/rayon,MIT OR Apache-2.0,"Niko Matsakis , Josh Stone " +rayon-core,https://github.com/rayon-rs/rayon,MIT OR Apache-2.0,"Niko Matsakis , Josh Stone " redox_syscall,https://gitlab.redox-os.org/redox-os/syscall,MIT,Jeremy Soller redox_users,https://gitlab.redox-os.org/redox-os/users,MIT,"Jose Narvaez , Wesley Hershberger " regex,https://github.com/rust-lang/regex,MIT OR Apache-2.0,"The Rust Project Developers, Andrew Gallant " @@ -248,6 +285,7 @@ serde,https://github.com/serde-rs/serde,MIT OR Apache-2.0,"Erick Tryzelaar serde_derive,https://github.com/serde-rs/serde,MIT OR Apache-2.0,"Erick Tryzelaar , David Tolnay " serde_json,https://github.com/serde-rs/json,MIT OR Apache-2.0,"Erick Tryzelaar , David Tolnay " +serde_path_to_error,https://github.com/dtolnay/path-to-error,MIT OR Apache-2.0,David Tolnay serde_regex,https://github.com/tailhook/serde-regex,MIT OR Apache-2.0,paul@colomiets.name serde_repr,https://github.com/dtolnay/serde-repr,MIT OR Apache-2.0,David Tolnay serde_urlencoded,https://github.com/nox/serde_urlencoded,MIT OR Apache-2.0,Anthony Ramine @@ -283,6 +321,7 @@ time-macros,https://github.com/time-rs/time,MIT OR Apache-2.0,"Jacob Pratt tinybytes,https://github.com/Datadog/libdatadog,Apache-2.0,The tinybytes Authors tinystr,https://github.com/unicode-org/icu4x,Unicode-3.0,The ICU4X Project Developers +tinytemplate,https://github.com/bheisler/TinyTemplate,Apache-2.0 OR MIT,Brook Heisler tinyvec,https://github.com/Lokathor/tinyvec,Zlib OR Apache-2.0 OR MIT,Lokathor tinyvec_macros,https://github.com/Soveu/tinyvec_macros,MIT OR Apache-2.0 OR Zlib,Soveu tokio,https://github.com/tokio-rs/tokio,MIT,Tokio Contributors @@ -290,12 +329,14 @@ tokio-macros,https://github.com/tokio-rs/tokio,MIT,Tokio Contributors tokio-util,https://github.com/tokio-rs/tokio,MIT,Tokio Contributors +tonic,https://github.com/hyperium/tonic,MIT,Lucio Franco tower,https://github.com/tower-rs/tower,MIT,Tower Maintainers tower-layer,https://github.com/tower-rs/tower,MIT,Tower Maintainers tower-service,https://github.com/tower-rs/tower,MIT,Tower Maintainers tracing,https://github.com/tokio-rs/tracing,MIT,"Eliza Weisman , Tokio Contributors " tracing-attributes,https://github.com/tokio-rs/tracing,MIT,"Tokio Contributors , Eliza Weisman , David Barsky " tracing-core,https://github.com/tokio-rs/tracing,MIT,Tokio Contributors +tracing-log,https://github.com/tokio-rs/tracing,MIT,Tokio Contributors tracing-subscriber,https://github.com/tokio-rs/tracing,MIT,"Eliza Weisman , David Barsky , Tokio Contributors " try-lock,https://github.com/seanmonstar/try-lock,MIT,Sean McArthur unicode-ident,https://github.com/dtolnay/unicode-ident,(MIT OR Apache-2.0) AND Unicode-3.0,David Tolnay @@ -305,7 +346,9 @@ url,https://github.com/servo/rust-url,MIT OR Apache-2.0,The rust-url developers urlencoding,https://github.com/kornelski/rust_urlencoding,MIT,"Kornel , Bertram Truong " utf16_iter,https://github.com/hsivonen/utf16_iter,Apache-2.0 OR MIT,Henri Sivonen utf8_iter,https://github.com/hsivonen/utf8_iter,Apache-2.0 OR MIT,Henri Sivonen +utf8parse,https://github.com/alacritty/vte,Apache-2.0 OR MIT,"Joe Wilm , Christian Duerr " uuid,https://github.com/uuid-rs/uuid,Apache-2.0 OR MIT,"Ashley Mannix, Dylan DPC, Hunar Roop Kahlon" +valuable,https://github.com/tokio-rs/valuable,MIT,The valuable Authors value-bag,https://github.com/sval-rs/value-bag,Apache-2.0 OR MIT,Ashley Mannix walkdir,https://github.com/BurntSushi/walkdir,Unlicense OR MIT,Andrew Gallant want,https://github.com/seanmonstar/want,MIT,Sean McArthur diff --git a/datadog-opentelemetry-benches/Cargo.toml b/datadog-opentelemetry-benches/Cargo.toml new file mode 100644 index 00000000..0352fa6f --- /dev/null +++ b/datadog-opentelemetry-benches/Cargo.toml @@ -0,0 +1,41 @@ +[package] +name = "datadog-opentelemetry-benches" +edition.workspace = true +version.workspace = true +license.workspace = true +repository.workspace = true +readme.workspace = true +description = "Benchmarks for datadog-opentelemetry crate" + +[dependencies] +# Workspace dependencies +dd-trace = { path = "../dd-trace" } +datadog-opentelemetry = { path = "../datadog-opentelemetry" } + +# External dependencies +criterion = { version = "0.5", features = ["html_reports", "async_tokio"] } +tokio = { workspace = true } +futures = { workspace = true } +opentelemetry_sdk = { workspace = true } +opentelemetry = { workspace = true } + +# HTTP/Web dependencies for benchmarks +axum = "0.7" +axum-server = "0.7.2" +tower = "0.5" +tower-http = { version = "0.6", features = ["trace", "cors"] } +opentelemetry-http = "0.28" +opentelemetry-otlp = "0.28" +opentelemetry-stdout = "0.28" + +# Additional dependencies +ctor = "0.4.2" +clap = { version = "4.0", features = ["derive"] } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +tracing = "0.1" +tracing-subscriber = { version = "0.3", features = ["env-filter"] } + +[[bench]] +name = "dd_otel_tracer_comparison" +harness = false \ No newline at end of file diff --git a/datadog-opentelemetry-benches/README.md b/datadog-opentelemetry-benches/README.md new file mode 100644 index 00000000..d04d5ce9 --- /dev/null +++ b/datadog-opentelemetry-benches/README.md @@ -0,0 +1,42 @@ +# Datadog OpenTelemetry Benchmarks + +This crate contains performance benchmarks for the `datadog-opentelemetry` crate. + +## Benchmarks + +### dd_otel_tracer_comparison + +Compares the performance of Datadog tracing vs vanilla OpenTelemetry tracing using Axum web servers. + +The benchmark tests various scenarios: +- Health endpoint calls +- Echo endpoint with request body processing +- Compute-intensive operations +- Nested span creation +- Middleware overhead +- Span creation overhead + +## Running Benchmarks + +To run all benchmarks: + +```bash +cargo bench -p datadog-opentelemetry-benches +``` + +To run a specific benchmark: + +```bash +cargo bench -p datadog-opentelemetry-benches --bench dd_otel_tracer_comparison +``` + +To run with additional criterion options: + +```bash +cargo bench -p datadog-opentelemetry-benches --bench dd_otel_tracer_comparison -- --help +``` + +## Output + +Benchmark results are generated in HTML format and can be found in: +`target/criterion/dd_otel_tracer_comparison/` \ No newline at end of file diff --git a/datadog-opentelemetry-benches/benches/dd_otel_tracer_comparison.rs b/datadog-opentelemetry-benches/benches/dd_otel_tracer_comparison.rs new file mode 100644 index 00000000..4d84d37b --- /dev/null +++ b/datadog-opentelemetry-benches/benches/dd_otel_tracer_comparison.rs @@ -0,0 +1,536 @@ +// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/ +// SPDX-License-Identifier: Apache-2.0 + +use axum::{body::to_bytes, http::Method, Router}; +use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion}; +use opentelemetry::{ + global::{self}, + trace::{SpanKind, Tracer}, +}; +use tokio::runtime::Runtime; + +use crate::axum_servers::{DatadogServer, OpenTelemetryServer}; + +mod axum_servers { + use axum::{ + extract::Request, + http::StatusCode, + middleware::{self, Next}, + response::{IntoResponse, Response}, + routing::{get, post}, + Router, + }; + use opentelemetry::{ + global::{self}, + trace::{FutureExt, SpanKind, TraceContextExt, Tracer}, + Context, KeyValue, + }; + use opentelemetry_http::HeaderExtractor; + use opentelemetry_otlp::{Protocol, SpanExporter, WithExportConfig}; + use opentelemetry_sdk::{trace::SdkTracerProvider, Resource}; + use std::time::{Duration, Instant}; + use tower::ServiceBuilder; + use tower_http::trace::TraceLayer; + + // OpenTelemetry server setup + pub struct OpenTelemetryServer { + pub tracer_provider: SdkTracerProvider, + pub router: Router, + } + + impl OpenTelemetryServer { + pub fn new() -> Self { + let exporter = SpanExporter::builder() + .with_http() + .with_protocol(Protocol::HttpBinary) //can be changed to `Protocol::HttpJson` to export in JSON format + .build() + .expect("Failed to create trace exporter"); + + let tracer_provider = SdkTracerProvider::builder() + .with_resource( + Resource::builder() + .with_service_name("otel-bench-server") + .build(), + ) + .with_simple_exporter(opentelemetry_stdout::SpanExporter::default()) + .with_batch_exporter(exporter) + .build(); + + global::set_tracer_provider(tracer_provider.clone()); + + let router = Router::new() + .route("/health", get(health_handler)) + .route("/echo", post(echo_handler)) + .route("/compute", get(compute_handler)) + .route("/nested", get(nested_handler)) + .layer( + ServiceBuilder::new() + .layer(middleware::from_fn(tracing_middleware)) + .layer(TraceLayer::new_for_http()), + ); + + Self { + tracer_provider, + router, + } + } + } + + // Datadog server setup + pub struct DatadogServer { + pub tracer_provider: opentelemetry_sdk::trace::SdkTracerProvider, + pub router: Router, + } + + impl DatadogServer { + pub fn new(agent_uri: Option) -> Self { + let mut config = dd_trace::Config::builder(); + config + .set_service("dd-bench-server".to_string()) + .set_version("1.0.0".to_string()); + + if let Some(agent_uri) = agent_uri { + config.set_trace_agent_url(agent_uri.into()); + } + + let tracer_provider = datadog_opentelemetry::init_datadog( + config.build(), + SdkTracerProvider::builder().with_resource( + Resource::builder() + .with_service_name("dd-bench-server") + .build(), + ), + ); + + global::set_tracer_provider(tracer_provider.clone()); + + let router = Router::new() + .route("/health", get(health_handler)) + .route("/echo", post(echo_handler)) + .route("/compute", get(compute_handler)) + .route("/nested", get(nested_handler)) + .layer(ServiceBuilder::new().layer(middleware::from_fn(tracing_middleware))); + + Self { + tracer_provider, + router, + } + } + } + + // Datadog middleware + async fn tracing_middleware(request: Request, next: Next) -> Response { + let start = Instant::now(); + + // Extract tracing context from headers + let parent_cx = global::get_text_map_propagator(|propagator| { + propagator.extract(&HeaderExtractor(request.headers())) + }); + + let tracer = global::tracer("axum-server"); + let span = tracer + .span_builder(format!("{} {}", request.method(), request.uri().path())) + .with_kind(SpanKind::Server) + .with_attributes([ + KeyValue::new("http.method", request.method().to_string()), + KeyValue::new("http.target", request.uri().path().to_string()), + ]) + .start_with_context(&tracer, &parent_cx); + + let cx = parent_cx.with_span(span); + let response = next.run(request).with_context(cx).await; + + let duration = start.elapsed(); + Context::current() + .span() + .set_attribute(KeyValue::new("duration_ms", duration.as_millis() as i64)); + + response + } + + // Datadog handlers (identical logic, different tracer) + async fn health_handler() -> impl IntoResponse { + let tracer = global::tracer("axum-server"); + tracer.in_span("health_check", |_cx| { + std::thread::sleep(Duration::from_micros(10)); + }); + + (StatusCode::OK, "OK") + } + + async fn echo_handler(body: String) -> impl IntoResponse { + let tracer = global::tracer("axum-server"); + tracer.in_span("echo_processing", |cx| { + cx.span() + .set_attribute(KeyValue::new("body.length", body.len() as i64)); + std::thread::sleep(Duration::from_micros(50)); + }); + + body + } + + async fn compute_handler() -> impl IntoResponse { + let tracer = global::tracer("axum-server"); + let result = tracer.in_span("compute_operation", |_cx| { + let mut sum = 0u64; + for i in 0..10000 { + sum = sum.wrapping_add(i * i); + } + sum + }); + + result.to_string() + } + + async fn nested_handler() -> impl IntoResponse { + let tracer = global::tracer("axum-server"); + tracer.in_span("nested_operation", |_cx| { + tracer.in_span("sub_operation_1", |_cx| { + std::thread::sleep(Duration::from_micros(20)); + }); + + tracer.in_span("sub_operation_2", |_cx| { + std::thread::sleep(Duration::from_micros(30)); + }); + }); + + "nested operations completed" + } +} + +// Benchmark helper functions +async fn simulate_request_otel( + router: Router, + path: &str, + method: &str, + body: Option, +) -> Result<(), Box> { + use axum::body::Body; + use axum::http::{Method, Request}; + use tower::ServiceExt; + + let request = Request::builder() + .uri(path) + .method(Method::from_bytes(method.as_bytes())?) + .body(Body::from(body.unwrap_or_default()))?; + + let _response = router.oneshot(request).await?; + Ok(()) +} + +async fn simulate_request_datadog( + router: Router, + path: &str, + method: &str, + body: Option, +) -> Result<(), Box> { + use axum::body::Body; + use axum::http::{Method, Request}; + use tower::ServiceExt; + + let request = Request::builder() + .uri(path) + .method(Method::from_bytes(method.as_bytes())?) + .body(Body::from(body.unwrap_or_default()))?; + + let _response = router.oneshot(request).await?; + Ok(()) +} + +// Benchmark functions +fn bench_health_endpoint(c: &mut Criterion) { + let rt = Runtime::new().unwrap(); + + let otel_server = OpenTelemetryServer::new(); + let dd_server = DatadogServer::new(None); + + let mut group = c.benchmark_group("health_endpoint"); + + group.bench_function("opentelemetry", |b| { + b.to_async(&rt).iter(|| async { + simulate_request_otel( + otel_server.router.clone(), + black_box("/health"), + "GET", + None, + ) + .await + .unwrap(); + }); + }); + + group.bench_function("datadog", |b| { + b.to_async(&rt).iter(|| async { + simulate_request_datadog(dd_server.router.clone(), black_box("/health"), "GET", None) + .await + .unwrap(); + }); + }); + + group.finish(); +} + +fn bench_echo_endpoint(c: &mut Criterion) { + let rt = Runtime::new().unwrap(); + let medium = "x".repeat(1024); + let large = "x".repeat(10240); + let test_bodies = vec![ + ("small", "Hello, World!"), + ("medium", &medium), + ("large", &large), + ]; + + let otel_server = OpenTelemetryServer::new(); + let dd_server = DatadogServer::new(None); + + let mut group = c.benchmark_group("echo_endpoint"); + + for (size, body) in test_bodies { + group.bench_with_input(BenchmarkId::new("opentelemetry", size), body, |b, body| { + b.to_async(&rt).iter(|| async { + simulate_request_otel( + otel_server.router.clone(), + black_box("/echo"), + "POST", + Some(body.to_string()), + ) + .await + .unwrap(); + }); + }); + + group.bench_with_input(BenchmarkId::new("datadog", size), body, |b, body| { + b.to_async(&rt).iter(|| async { + simulate_request_datadog( + dd_server.router.clone(), + black_box("/echo"), + "POST", + Some(body.to_string()), + ) + .await + .unwrap(); + }); + }); + } + + group.finish(); +} + +fn bench_compute_endpoint(c: &mut Criterion) { + let rt = Runtime::new().unwrap(); + + let otel_server = OpenTelemetryServer::new(); + let dd_server = DatadogServer::new(None); + + let mut group = c.benchmark_group("compute_endpoint"); + + group.bench_function("opentelemetry", |b| { + b.to_async(&rt).iter(|| async { + simulate_request_otel( + otel_server.router.clone(), + black_box("/compute"), + "GET", + None, + ) + .await + .unwrap(); + }); + }); + + group.bench_function("datadog", |b| { + b.to_async(&rt).iter(|| async { + simulate_request_datadog(dd_server.router.clone(), black_box("/compute"), "GET", None) + .await + .unwrap(); + }); + }); + + group.finish(); +} + +fn bench_nested_spans(c: &mut Criterion) { + let rt = Runtime::new().unwrap(); + + let otel_server = OpenTelemetryServer::new(); + let dd_server = DatadogServer::new(None); + + let mut group = c.benchmark_group("nested_spans"); + + group.bench_function("opentelemetry", |b| { + b.to_async(&rt).iter(|| async { + simulate_request_otel( + otel_server.router.clone(), + black_box("/nested"), + "GET", + None, + ) + .await + .unwrap(); + }); + }); + + group.bench_function("datadog", |b| { + b.to_async(&rt).iter(|| async { + simulate_request_datadog(dd_server.router.clone(), black_box("/nested"), "GET", None) + .await + .unwrap(); + }); + }); + + group.finish(); +} + +fn bench_middleware_overhead(c: &mut Criterion) { + let rt = Runtime::new().unwrap(); + + let otel_server = OpenTelemetryServer::new(); + let dd_server = DatadogServer::new(None); + + let mut group = c.benchmark_group("middleware_overhead"); + group.significance_level(0.1).sample_size(1000); + + // Test multiple concurrent requests to measure middleware scaling + let concurrent_requests = vec![1, 5, 10, 20]; + + for &concurrency in &concurrent_requests { + group.bench_with_input( + BenchmarkId::new("opentelemetry", concurrency), + &concurrency, + |b, &concurrency| { + b.to_async(&rt).iter(|| { + let router = otel_server.router.clone(); + async move { + let futures: Vec<_> = (0..concurrency) + .map(|_| simulate_request_otel(router.clone(), "/health", "GET", None)) + .collect(); + + futures::future::try_join_all(futures).await.unwrap(); + } + }); + }, + ); + + group.bench_with_input( + BenchmarkId::new("datadog", concurrency), + &concurrency, + |b, &concurrency| { + b.to_async(&rt).iter(|| { + let router = dd_server.router.clone(); + async move { + let futures: Vec<_> = (0..concurrency) + .map(|_| { + simulate_request_datadog(router.clone(), "/health", "GET", None) + }) + .collect(); + + futures::future::try_join_all(futures).await.unwrap(); + } + }); + }, + ); + } + + group.finish(); +} + +fn bench_span_creation_overhead(c: &mut Criterion) { + let mut group = c.benchmark_group("span_creation"); + + group.bench_function("opentelemetry_span_creation", |b| { + let otel_server = axum_servers::OpenTelemetryServer::new(); + + b.iter(|| { + let tracer = global::tracer("benchmark"); + let _span = tracer + .span_builder(black_box("test_span")) + .with_kind(SpanKind::Internal) + .start(&tracer); + }); + + let _ = otel_server.tracer_provider.shutdown(); + }); + + group.bench_function("datadog_span_creation", |b| { + let dd_server = axum_servers::DatadogServer::new(None); + + b.iter(|| { + let tracer = global::tracer("benchmark"); + let _span = tracer + .span_builder(black_box("test_span")) + .with_kind(SpanKind::Internal) + .start(&tracer); + }); + + let _ = dd_server.tracer_provider.shutdown(); + }); + + group.finish(); +} + +#[ctor::ctor] +fn start_listeners() { + // if Otel collector or Datadog Agent are running, they will be used! + let listeners = vec![ + ("4318", "Otel Collector"), + ("8126", "Datadog Agent"), + // ("8125", "Datadog statsd"), + ]; + + for (port, service) in listeners { + let t = std::thread::spawn(move || { + let rt = tokio::runtime::Runtime::new().unwrap(); + rt.block_on(async { + use axum::body::Bytes; + use axum::extract::Request; + use axum::{routing::any, Router}; + use std::net::SocketAddr; + + // Handler that prints received requests + let handle_any = |mut req: Request| { + let service = service.to_string(); + async move { + if service.contains("Datadog") { + let method = req.method().clone(); + let uri = req.uri().to_string(); + let mut body_str = String::new(); + if method == Method::POST || method == Method::PUT { + let bytes = to_bytes(req.into_body(), usize::MAX).await.unwrap(); + // body_str = String::from_utf8_lossy(&bytes).to_string(); + } + + // println!( + // "{} {} {} received body bytes: {:?}", + // service, method, uri, body_str + // ); + } + "OK" + } + }; + + let listener = tokio::net::TcpListener::bind(format!("127.0.0.1:{port}")) + .await + .unwrap(); + println!( + "{} listening on {}", + service, + listener.local_addr().unwrap() + ); + + let app = Router::new().route("/*path", any(handle_any)); + axum::serve(listener, app).await.unwrap(); + }); + }); + } +} + +criterion_group!( + benches, + bench_health_endpoint, + bench_echo_endpoint, + bench_compute_endpoint, + bench_nested_spans, + bench_middleware_overhead, + bench_span_creation_overhead +); + +criterion_main!(benches); diff --git a/datadog-opentelemetry/Cargo.toml b/datadog-opentelemetry/Cargo.toml index d86364bb..6140155c 100644 --- a/datadog-opentelemetry/Cargo.toml +++ b/datadog-opentelemetry/Cargo.toml @@ -28,8 +28,9 @@ datadog-trace-utils = { workspace = true } tinybytes = { workspace = true } [dev-dependencies] -tokio = { workspace = true } assert_unordered = "0.3" +criterion = { version = "0.5", features = ["html_reports", "async_tokio"] } +tokio = { workspace = true } # Libdatadog dependencies - change to a stable version once we release datadog-trace-utils = { workspace = true, features = ["test-utils"] } @@ -39,4 +40,4 @@ dd-trace-sampling = { path = "../dd-trace-sampling" } datadog-opentelemetry = { path = ".", features = ["test-utils"] } [features] -test-utils = ["dd-trace/test-utils", "data-pipeline/test-utils"] +test-utils = ["dd-trace/test-utils", "data-pipeline/test-utils"] \ No newline at end of file