From 6e2eb02d1249fc9f204b5cb6d28620856dd60400 Mon Sep 17 00:00:00 2001 From: Pierre Fenoll Date: Mon, 8 Apr 2024 09:43:05 +0200 Subject: [PATCH 001/148] deps: upgrade tonic to v0.11 (#651) Signed-off-by: Pierre Fenoll --- CHANGELOG.md | 1 + Cargo.lock | 67 ++++++++++++++++++----------------------- sentry-tower/Cargo.toml | 2 +- 3 files changed, 31 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45483f584..cabc9fb3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ **Updates**: - Updated `reqwest` to version `0.12`. +- Updated `tonic` to version `0.11`. ## 0.32.2 diff --git a/Cargo.lock b/Cargo.lock index aed028cba..f14dc5696 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -257,7 +257,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" dependencies = [ "cfg-if", - "getrandom 0.2.12", + "getrandom 0.2.13", "once_cell", "version_check", "zerocopy", @@ -301,9 +301,9 @@ checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" dependencies = [ "backtrace", ] @@ -521,9 +521,9 @@ checksum = "b4eb2cdb97421e01129ccb49169d8279ed21e829929144f4a22a6e54ac549ca1" [[package]] name = "async-trait" -version = "0.1.74" +version = "0.1.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" dependencies = [ "proc-macro2", "quote", @@ -971,7 +971,7 @@ dependencies = [ "clap", "criterion-plot", "is-terminal", - "itertools 0.10.5", + "itertools", "num-traits", "once_cell", "oorandom", @@ -992,7 +992,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" dependencies = [ "cast", - "itertools 0.10.5", + "itertools", ] [[package]] @@ -1194,9 +1194,9 @@ checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" [[package]] name = "either" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" [[package]] name = "encoding_rs" @@ -1497,9 +1497,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "a06fddc2749e0528d2813f95e050e87e52c8cbbae56223b9babf73b3e53b0cc6" dependencies = [ "cfg-if", "libc", @@ -1752,7 +1752,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.6", + "socket2 0.4.10", "tokio", "tower-service", "tracing", @@ -1950,15 +1950,6 @@ dependencies = [ "either", ] -[[package]] -name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - [[package]] name = "itoa" version = "1.0.11" @@ -2346,18 +2337,18 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", @@ -2501,9 +2492,9 @@ dependencies = [ [[package]] name = "prost" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +checksum = "d0f5d036824e4761737860779c906171497f6d55681139d8312388f8fe398922" dependencies = [ "bytes 1.6.0", "prost-derive", @@ -2511,12 +2502,12 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +checksum = "19de2de2a00075bf566bee3bd4db014b11587e84184d3f7a791bc17f1a8e9e48" dependencies = [ "anyhow", - "itertools 0.11.0", + "itertools", "proc-macro2", "quote", "syn 2.0.58", @@ -2590,7 +2581,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.12", + "getrandom 0.2.13", ] [[package]] @@ -2719,7 +2710,7 @@ checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.12", + "getrandom 0.2.13", "libc", "spin", "untrusted", @@ -3422,7 +3413,7 @@ dependencies = [ "async-trait", "cfg-if", "futures-util", - "getrandom 0.2.12", + "getrandom 0.2.13", "http-client", "http-types", "log", @@ -3667,9 +3658,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" dependencies = [ "futures-core", "pin-project-lite", @@ -3692,9 +3683,9 @@ dependencies = [ [[package]] name = "tonic" -version = "0.10.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d560933a0de61cf715926b9cac824d4c883c2c43142f787595e48280c40a1d0e" +checksum = "76c4eb7a4e9ef9d4763600161f12f5070b92a578e1b634db88a6887844c91a13" dependencies = [ "async-stream", "async-trait", @@ -3918,7 +3909,7 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" dependencies = [ - "getrandom 0.2.12", + "getrandom 0.2.13", "serde", ] diff --git a/sentry-tower/Cargo.toml b/sentry-tower/Cargo.toml index 37a98052c..48ebb7ef5 100644 --- a/sentry-tower/Cargo.toml +++ b/sentry-tower/Cargo.toml @@ -36,5 +36,5 @@ prost = "0.12.3" sentry = { path = "../sentry", default-features = false, features = ["test"] } sentry-anyhow = { path = "../sentry-anyhow" } tokio = { version = "1", features = ["macros", "rt-multi-thread"] } -tonic = { version = "0.10.2", features = ["transport"] } +tonic = { version = "0.11", features = ["transport"] } tower = { version = "0.4", features = ["util", "timeout"] } From 1df2e4ca3cc678695bc47e90489c3f83847b9abb Mon Sep 17 00:00:00 2001 From: Pierre Fenoll Date: Mon, 8 Apr 2024 15:46:06 +0200 Subject: [PATCH 002/148] deps: upgrade hostname to v0.4 (#652) Signed-off-by: Pierre Fenoll --- Cargo.lock | 35 ++++++++++++++++++++++++----------- sentry-contexts/Cargo.toml | 2 +- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f14dc5696..7c934098e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1611,13 +1611,13 @@ dependencies = [ [[package]] name = "hostname" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +checksum = "f9c7c7c8ac16c798734b8a24560c1362120597c40d5e1459f09498f8f6c8f2ba" dependencies = [ + "cfg-if", "libc", - "match_cfg", - "winapi", + "windows", ] [[package]] @@ -1752,7 +1752,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.10", + "socket2 0.5.6", "tokio", "tower-service", "tracing", @@ -2084,12 +2084,6 @@ dependencies = [ "value-bag", ] -[[package]] -name = "match_cfg" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" - [[package]] name = "matchit" version = "0.7.3" @@ -4096,6 +4090,25 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core", + "windows-targets 0.52.4", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.4", +] + [[package]] name = "windows-sys" version = "0.48.0" diff --git a/sentry-contexts/Cargo.toml b/sentry-contexts/Cargo.toml index 8dd48b78c..f1baa9840 100644 --- a/sentry-contexts/Cargo.toml +++ b/sentry-contexts/Cargo.toml @@ -16,7 +16,7 @@ rust-version = "1.73" [dependencies] sentry-core = { version = "0.32.2", path = "../sentry-core" } libc = "0.2.66" -hostname = "0.3.0" +hostname = "0.4" [target."cfg(not(windows))".dependencies] uname = "0.1.1" From e1529e88a239c7aaa33091210e0b6764a7ccc113 Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Tue, 16 Apr 2024 07:19:06 +0000 Subject: [PATCH 003/148] release: 0.32.3 --- CHANGELOG.md | 2 +- sentry-actix/Cargo.toml | 4 ++-- sentry-anyhow/Cargo.toml | 6 +++--- sentry-backtrace/Cargo.toml | 4 ++-- sentry-contexts/Cargo.toml | 4 ++-- sentry-core/Cargo.toml | 4 ++-- sentry-core/README.md | 2 +- sentry-debug-images/Cargo.toml | 4 ++-- sentry-debug-images/README.md | 2 +- sentry-log/Cargo.toml | 4 ++-- sentry-panic/Cargo.toml | 6 +++--- sentry-slog/Cargo.toml | 4 ++-- sentry-tower/Cargo.toml | 4 ++-- sentry-tower/README.md | 2 +- sentry-tracing/Cargo.toml | 6 +++--- sentry-tracing/README.md | 2 +- sentry-types/Cargo.toml | 2 +- sentry/Cargo.toml | 22 +++++++++++----------- sentry/README.md | 12 ++++++------ 19 files changed, 48 insertions(+), 48 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cabc9fb3d..8b6c11098 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 0.32.3 **Compatiblity**: diff --git a/sentry-actix/Cargo.toml b/sentry-actix/Cargo.toml index ba337e25d..5da5bef38 100644 --- a/sentry-actix/Cargo.toml +++ b/sentry-actix/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-actix" -version = "0.32.2" +version = "0.32.3" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -15,7 +15,7 @@ rust-version = "1.73" [dependencies] actix-web = { version = "4", default-features = false } futures-util = { version = "0.3.5", default-features = false } -sentry-core = { version = "0.32.2", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.32.3", path = "../sentry-core", default-features = false, features = [ "client", ] } diff --git a/sentry-anyhow/Cargo.toml b/sentry-anyhow/Cargo.toml index ac2a44bb0..cbe957a93 100644 --- a/sentry-anyhow/Cargo.toml +++ b/sentry-anyhow/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-anyhow" -version = "0.32.2" +version = "0.32.3" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -17,8 +17,8 @@ default = ["backtrace"] backtrace = ["anyhow/backtrace"] [dependencies] -sentry-backtrace = { version = "0.32.2", path = "../sentry-backtrace" } -sentry-core = { version = "0.32.2", path = "../sentry-core" } +sentry-backtrace = { version = "0.32.3", path = "../sentry-backtrace" } +sentry-core = { version = "0.32.3", path = "../sentry-core" } anyhow = "1.0.39" [dev-dependencies] diff --git a/sentry-backtrace/Cargo.toml b/sentry-backtrace/Cargo.toml index 8a82b2a3f..48c2c85c4 100644 --- a/sentry-backtrace/Cargo.toml +++ b/sentry-backtrace/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-backtrace" -version = "0.32.2" +version = "0.32.3" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -19,4 +19,4 @@ regex = { version = "1.5.5", default-features = false, features = [ "std", "unicode-perl", ] } -sentry-core = { version = "0.32.2", path = "../sentry-core" } +sentry-core = { version = "0.32.3", path = "../sentry-core" } diff --git a/sentry-contexts/Cargo.toml b/sentry-contexts/Cargo.toml index f1baa9840..dd9c258ff 100644 --- a/sentry-contexts/Cargo.toml +++ b/sentry-contexts/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-contexts" -version = "0.32.2" +version = "0.32.3" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -14,7 +14,7 @@ edition = "2021" rust-version = "1.73" [dependencies] -sentry-core = { version = "0.32.2", path = "../sentry-core" } +sentry-core = { version = "0.32.3", path = "../sentry-core" } libc = "0.2.66" hostname = "0.4" diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index c1bbf1846..3c2bfd0e9 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-core" -version = "0.32.2" +version = "0.32.3" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -34,7 +34,7 @@ cadence = { version = "0.29.0", optional = true } log = { version = "0.4.8", optional = true, features = ["std"] } once_cell = "1" rand = { version = "0.8.1", optional = true } -sentry-types = { version = "0.32.2", path = "../sentry-types" } +sentry-types = { version = "0.32.3", path = "../sentry-types" } serde = { version = "1.0.104", features = ["derive"] } serde_json = { version = "1.0.46" } uuid = { version = "1.0.0", features = ["v4", "serde"], optional = true } diff --git a/sentry-core/README.md b/sentry-core/README.md index 498e54256..b29fa2dbf 100644 --- a/sentry-core/README.md +++ b/sentry-core/README.md @@ -102,7 +102,7 @@ functionality. [Sentry]: https://sentry.io/ [`sentry`]: https://crates.io/crates/sentry [Unified API]: https://develop.sentry.dev/sdk/unified-api/ -[`test`]: https://docs.rs/sentry-core/0.32.2/sentry_core/test/index.html +[`test`]: https://docs.rs/sentry-core/0.32.3/sentry_core/test/index.html ## Resources diff --git a/sentry-debug-images/Cargo.toml b/sentry-debug-images/Cargo.toml index 777490c6b..906e90663 100644 --- a/sentry-debug-images/Cargo.toml +++ b/sentry-debug-images/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-debug-images" -version = "0.32.2" +version = "0.32.3" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -15,4 +15,4 @@ rust-version = "1.73" [dependencies] findshlibs = "=0.10.2" once_cell = "1" -sentry-core = { version = "0.32.2", path = "../sentry-core" } +sentry-core = { version = "0.32.3", path = "../sentry-core" } diff --git a/sentry-debug-images/README.md b/sentry-debug-images/README.md index 962f75dcf..d3d614d6e 100644 --- a/sentry-debug-images/README.md +++ b/sentry-debug-images/README.md @@ -22,7 +22,7 @@ let integration = sentry_debug_images::DebugImagesIntegration::new() .filter(|event| event.level >= Level::Warning); ``` -[`Event`]: https://docs.rs/sentry-debug-images/0.32.2/sentry_debug_images/sentry_core::protocol::Event +[`Event`]: https://docs.rs/sentry-debug-images/0.32.3/sentry_debug_images/sentry_core::protocol::Event ## Resources diff --git a/sentry-log/Cargo.toml b/sentry-log/Cargo.toml index 106485764..73c318510 100644 --- a/sentry-log/Cargo.toml +++ b/sentry-log/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-log" -version = "0.32.2" +version = "0.32.3" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.73" [dependencies] -sentry-core = { version = "0.32.2", path = "../sentry-core" } +sentry-core = { version = "0.32.3", path = "../sentry-core" } log = { version = "0.4.8", features = ["std"] } [dev-dependencies] diff --git a/sentry-panic/Cargo.toml b/sentry-panic/Cargo.toml index 7fc70a03b..f5b7de00a 100644 --- a/sentry-panic/Cargo.toml +++ b/sentry-panic/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-panic" -version = "0.32.2" +version = "0.32.3" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -13,8 +13,8 @@ edition = "2021" rust-version = "1.73" [dependencies] -sentry-core = { version = "0.32.2", path = "../sentry-core" } -sentry-backtrace = { version = "0.32.2", path = "../sentry-backtrace" } +sentry-core = { version = "0.32.3", path = "../sentry-core" } +sentry-backtrace = { version = "0.32.3", path = "../sentry-backtrace" } [dev-dependencies] sentry = { path = "../sentry", default-features = false, features = ["test"] } diff --git a/sentry-slog/Cargo.toml b/sentry-slog/Cargo.toml index b5ea736c9..e58c42bc3 100644 --- a/sentry-slog/Cargo.toml +++ b/sentry-slog/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-slog" -version = "0.32.2" +version = "0.32.3" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.73" [dependencies] -sentry-core = { version = "0.32.2", path = "../sentry-core" } +sentry-core = { version = "0.32.3", path = "../sentry-core" } slog = { version = "2.5.2", features = ["nested-values"] } serde_json = "1.0.46" diff --git a/sentry-tower/Cargo.toml b/sentry-tower/Cargo.toml index 48ebb7ef5..8a1767230 100644 --- a/sentry-tower/Cargo.toml +++ b/sentry-tower/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tower" -version = "0.32.2" +version = "0.32.3" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -25,7 +25,7 @@ tower-layer = "0.3" tower-service = "0.3" http = { version = "1.0.0", optional = true } pin-project = { version = "1.0.10", optional = true } -sentry-core = { version = "0.32.2", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.32.3", path = "../sentry-core", default-features = false, features = [ "client", ] } url = { version = "2.2.2", optional = true } diff --git a/sentry-tower/README.md b/sentry-tower/README.md index 278ff8710..14861034b 100644 --- a/sentry-tower/README.md +++ b/sentry-tower/README.md @@ -103,7 +103,7 @@ feature of the `sentry` crate instead of the `tower` feature. The created transaction will automatically use the request URI as its name. This is sometimes not desirable in case the request URI contains unique IDs or similar. In this case, users should manually override the transaction name -in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.32.2/sentry_tower/sentry_core::Scope::set_transaction) +in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.32.3/sentry_tower/sentry_core::Scope::set_transaction) method. When combining both layers, take care of the ordering of both. For example diff --git a/sentry-tracing/Cargo.toml b/sentry-tracing/Cargo.toml index 16493e637..0f8914d85 100644 --- a/sentry-tracing/Cargo.toml +++ b/sentry-tracing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tracing" -version = "0.32.2" +version = "0.32.3" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -20,14 +20,14 @@ default = [] backtrace = ["dep:sentry-backtrace"] [dependencies] -sentry-core = { version = "0.32.2", path = "../sentry-core", features = [ +sentry-core = { version = "0.32.3", path = "../sentry-core", features = [ "client", ] } tracing-core = "0.1" tracing-subscriber = { version = "0.3.1", default-features = false, features = [ "std", ] } -sentry-backtrace = { version = "0.32.2", path = "../sentry-backtrace", optional = true } +sentry-backtrace = { version = "0.32.3", path = "../sentry-backtrace", optional = true } [dev-dependencies] log = "0.4" diff --git a/sentry-tracing/README.md b/sentry-tracing/README.md index 4d12211ee..78384cae0 100644 --- a/sentry-tracing/README.md +++ b/sentry-tracing/README.md @@ -83,7 +83,7 @@ tracing::error!( ); ``` -To track [error structs](https://docs.rs/sentry-tracing/0.32.2/sentry_tracing/std::error::Error), assign a reference to error trait object as field +To track [error structs](https://docs.rs/sentry-tracing/0.32.3/sentry_tracing/std::error::Error), assign a reference to error trait object as field in one of the logging macros. By convention, it is recommended to use the `ERROR` level and assign it to a field called `error`, although the integration will also work with all other levels and field names. diff --git a/sentry-types/Cargo.toml b/sentry-types/Cargo.toml index c2476a762..2fcd3538f 100644 --- a/sentry-types/Cargo.toml +++ b/sentry-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-types" -version = "0.32.2" +version = "0.32.3" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index a9ff2cecb..117ccde49 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry" -version = "0.32.2" +version = "0.32.3" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -52,18 +52,18 @@ native-tls = ["dep:native-tls", "reqwest?/default-tls", "ureq?/native-tls"] rustls = ["dep:rustls", "reqwest?/rustls-tls", "ureq?/tls", "webpki-roots"] [dependencies] -sentry-core = { version = "0.32.2", path = "../sentry-core", features = [ +sentry-core = { version = "0.32.3", path = "../sentry-core", features = [ "client", ] } -sentry-anyhow = { version = "0.32.2", path = "../sentry-anyhow", optional = true } -sentry-backtrace = { version = "0.32.2", path = "../sentry-backtrace", optional = true } -sentry-contexts = { version = "0.32.2", path = "../sentry-contexts", optional = true } -sentry-debug-images = { version = "0.32.2", path = "../sentry-debug-images", optional = true } -sentry-log = { version = "0.32.2", path = "../sentry-log", optional = true } -sentry-panic = { version = "0.32.2", path = "../sentry-panic", optional = true } -sentry-slog = { version = "0.32.2", path = "../sentry-slog", optional = true } -sentry-tower = { version = "0.32.2", path = "../sentry-tower", optional = true } -sentry-tracing = { version = "0.32.2", path = "../sentry-tracing", optional = true } +sentry-anyhow = { version = "0.32.3", path = "../sentry-anyhow", optional = true } +sentry-backtrace = { version = "0.32.3", path = "../sentry-backtrace", optional = true } +sentry-contexts = { version = "0.32.3", path = "../sentry-contexts", optional = true } +sentry-debug-images = { version = "0.32.3", path = "../sentry-debug-images", optional = true } +sentry-log = { version = "0.32.3", path = "../sentry-log", optional = true } +sentry-panic = { version = "0.32.3", path = "../sentry-panic", optional = true } +sentry-slog = { version = "0.32.3", path = "../sentry-slog", optional = true } +sentry-tower = { version = "0.32.3", path = "../sentry-tower", optional = true } +sentry-tracing = { version = "0.32.3", path = "../sentry-tracing", optional = true } log = { version = "0.4.8", optional = true, features = ["std"] } reqwest = { version = "0.12", optional = true, features = [ "blocking", diff --git a/sentry/README.md b/sentry/README.md index ba51bfcb3..e3c54b796 100644 --- a/sentry/README.md +++ b/sentry/README.md @@ -34,8 +34,8 @@ sentry::capture_message("Hello World!", sentry::Level::Info); More complex examples on how to use sentry can also be found in [examples]. Extended instructions may also be found on [Sentry itself]. -[`sentry::init`]: https://docs.rs/sentry/0.32.2/sentry/fn.init.html -[`Hub`]: https://docs.rs/sentry/0.32.2/sentry/struct.Hub.html +[`sentry::init`]: https://docs.rs/sentry/0.32.3/sentry/fn.init.html +[`Hub`]: https://docs.rs/sentry/0.32.3/sentry/struct.Hub.html [examples]: https://github.com/getsentry/sentry-rust/tree/master/sentry/examples [Sentry itself]: https://docs.sentry.io/platforms/rust @@ -47,8 +47,8 @@ the ecosystem require a feature flag. For available integrations and how to use [integrations] and [apply_defaults]. [Features]: #features -[integrations]: https://docs.rs/sentry/0.32.2/sentry/integrations/index.html -[apply_defaults]: https://docs.rs/sentry/0.32.2/sentry/fn.apply_defaults.html +[integrations]: https://docs.rs/sentry/0.32.3/sentry/integrations/index.html +[apply_defaults]: https://docs.rs/sentry/0.32.3/sentry/fn.apply_defaults.html ## Minimal API @@ -56,8 +56,8 @@ This crate comes fully-featured. If the goal is to instrument libraries for usag with sentry, or to extend sentry with a custom [`Integration`] or a [`Transport`], one should use the [`sentry-core`] crate instead. -[`Integration`]: https://docs.rs/sentry/0.32.2/sentry/trait.Integration.html -[`Transport`]: https://docs.rs/sentry/0.32.2/sentry/trait.Transport.html +[`Integration`]: https://docs.rs/sentry/0.32.3/sentry/trait.Integration.html +[`Transport`]: https://docs.rs/sentry/0.32.3/sentry/trait.Transport.html [`sentry-core`]: https://crates.io/crates/sentry-core ## Features From 8c701e8cf8b288f7d103ddb956705b624851b2e6 Mon Sep 17 00:00:00 2001 From: Moritz Bitsch Date: Tue, 16 Apr 2024 17:06:30 +0200 Subject: [PATCH 004/148] feat: add embedded-svc based http transport (#654) embedded-svc is used on esp32 for doing https --- sentry/Cargo.toml | 4 ++ sentry/src/transports/embedded_svc_http.rs | 64 ++++++++++++++++++++++ sentry/src/transports/mod.rs | 21 +++++++ 3 files changed, 89 insertions(+) create mode 100644 sentry/src/transports/embedded_svc_http.rs diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index 117ccde49..8958d20bc 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -50,6 +50,7 @@ ureq = ["dep:ureq", "httpdate"] # transport settings native-tls = ["dep:native-tls", "reqwest?/default-tls", "ureq?/native-tls"] rustls = ["dep:rustls", "reqwest?/rustls-tls", "ureq?/tls", "webpki-roots"] +embedded-svc-http = ["dep:embedded-svc", "dep:esp-idf-svc"] [dependencies] sentry-core = { version = "0.32.3", path = "../sentry-core", features = [ @@ -82,6 +83,9 @@ rustls = { version = "0.21.2", optional = true, features = [ "dangerous_configuration", ] } webpki-roots = { version = "0.25.1", optional = true } +embedded-svc = { version = "0.27.1", optional = true } +[target.'cfg(target_os = "espidf")'.dependencies] +esp-idf-svc = { version = "0.48.1", optional = true } [dev-dependencies] sentry-anyhow = { path = "../sentry-anyhow" } diff --git a/sentry/src/transports/embedded_svc_http.rs b/sentry/src/transports/embedded_svc_http.rs new file mode 100644 index 000000000..f040cb957 --- /dev/null +++ b/sentry/src/transports/embedded_svc_http.rs @@ -0,0 +1,64 @@ +use crate::{sentry_debug, ClientOptions, Transport}; +use embedded_svc::http::client::Client as HttpClient; +use esp_idf_svc::{http::client::EspHttpConnection, io::Write}; + +/// Transport using the embedded-svc http client +pub struct EmbeddedSVCHttpTransport { + options: ClientOptions, +} + +impl EmbeddedSVCHttpTransport { + /// Creates a new transport + pub fn new(options: &ClientOptions) -> Self { + Self { + options: options.clone(), + } + } +} + +impl EmbeddedSVCHttpTransport { + fn send_envelope( + &self, + envelope: sentry_core::Envelope, + ) -> Result<(), Box> { + let dsn = self + .options + .dsn + .as_ref() + .ok_or_else(|| "No DSN specified")?; + let user_agent = &self.options.user_agent; + let auth = dsn.to_auth(Some(user_agent)).to_string(); + let headers = [("X-Sentry-Auth", auth.as_str())]; + let url = dsn.envelope_api_url(); + + let mut body = Vec::new(); + envelope.to_writer(&mut body)?; + + let config = esp_idf_svc::http::client::Configuration { + use_global_ca_store: true, + crt_bundle_attach: Some(esp_idf_svc::sys::esp_crt_bundle_attach), + ..Default::default() + }; + + let mut client = HttpClient::wrap(EspHttpConnection::new(&config)?); + + let mut request = client.post(url.as_str(), &headers)?; + request.write_all(&body)?; + request.flush()?; + let mut response = request.submit()?; + + // read the whole response + let mut buf = [0u8; 1024]; + while response.read(&mut buf)? > 0 {} + + Ok(()) + } +} + +impl Transport for EmbeddedSVCHttpTransport { + fn send_envelope(&self, envelope: sentry_core::Envelope) { + if let Err(err) = self.send_envelope(envelope) { + sentry_debug!("Failed to send envelope: {}", err); + } + } +} diff --git a/sentry/src/transports/mod.rs b/sentry/src/transports/mod.rs index 253c7fe0e..46a849880 100644 --- a/sentry/src/transports/mod.rs +++ b/sentry/src/transports/mod.rs @@ -18,6 +18,11 @@ mod reqwest; #[cfg(feature = "reqwest")] pub use self::reqwest::ReqwestHttpTransport; +#[cfg(all(target_os = "espidf", feature = "embedded-svc-http"))] +mod embedded_svc_http; +#[cfg(all(target_os = "espidf", feature = "embedded-svc-http"))] +pub use self::embedded_svc_http::EmbeddedSVCHttpTransport; + #[cfg(feature = "curl")] mod curl; #[cfg(feature = "curl")] @@ -38,6 +43,7 @@ type DefaultTransport = ReqwestHttpTransport; #[cfg(all( feature = "curl", + not(all(target_os = "espidf", feature = "embedded-svc-http")), not(feature = "reqwest"), not(feature = "surf"), not(feature = "ureq") @@ -46,6 +52,7 @@ type DefaultTransport = CurlHttpTransport; #[cfg(all( feature = "surf", + not(all(target_os = "espidf", feature = "embedded-svc-http")), not(feature = "reqwest"), not(feature = "curl"), not(feature = "ureq") @@ -54,14 +61,26 @@ type DefaultTransport = SurfHttpTransport; #[cfg(all( feature = "ureq", + not(all(target_os = "espidf", feature = "embedded-svc-http")), not(feature = "reqwest"), not(feature = "curl"), not(feature = "surf") ))] type DefaultTransport = UreqHttpTransport; +#[cfg(all( + target_os = "espidf", + feature = "embedded-svc-http", + not(feature = "reqwest"), + not(feature = "curl"), + not(feature = "surf"), + not(feature = "ureq") +))] +type DefaultTransport = EmbeddedSVCHttpTransport; + /// The default http transport. #[cfg(any( + all(target_os = "espidf", feature = "embedded-svc-http"), feature = "reqwest", feature = "curl", feature = "surf", @@ -80,6 +99,7 @@ pub struct DefaultTransportFactory; impl TransportFactory for DefaultTransportFactory { fn create_transport(&self, options: &ClientOptions) -> Arc { #[cfg(any( + all(target_os = "espidf", feature = "embedded-svc-http"), feature = "reqwest", feature = "curl", feature = "surf", @@ -89,6 +109,7 @@ impl TransportFactory for DefaultTransportFactory { Arc::new(HttpTransport::new(options)) } #[cfg(not(any( + all(target_os = "espidf", feature = "embedded-svc-http"), feature = "reqwest", feature = "curl", feature = "surf", From 73d04ae0be4f01030d5e2d4ff8bc204206e2762e Mon Sep 17 00:00:00 2001 From: elramen <158566966+elramen@users.noreply.github.com> Date: Mon, 27 May 2024 17:10:02 +0200 Subject: [PATCH 005/148] ref(metrics): Add normalization and update set metrics hashing (#658) Add metrics normalization in accordance with the metrics developer docs. Add metric name, unit, and tag truncation to adhere to the metrics user docs. Add to_envelope for a single Metric instance to facilitate sending metrics from sentry-cli. Change hash function to crc32 as described here, this ensures compatibility between different SDKs using the same metric. Use clone_from instead of clone and clone_into instead of to_owned in a couple of places as suggested by clippy. --- Cargo.lock | 996 +++++++++++++++++- sentry-core/Cargo.toml | 3 + sentry-core/src/cadence.rs | 7 +- sentry-core/src/client.rs | 6 +- .../src/{metrics.rs => metrics/mod.rs} | 252 +++-- sentry-core/src/metrics/normalization/mod.rs | 28 + .../metrics/normalization/normalized_name.rs | 33 + .../metrics/normalization/normalized_tags.rs | 179 ++++ .../metrics/normalization/normalized_unit.rs | 57 + sentry-core/src/performance.rs | 4 +- sentry-core/src/units.rs | 6 + sentry-tracing/src/converters.rs | 10 +- sentry-types/src/protocol/envelope.rs | 25 +- 13 files changed, 1467 insertions(+), 139 deletions(-) rename sentry-core/src/{metrics.rs => metrics/mod.rs} (86%) create mode 100644 sentry-core/src/metrics/normalization/mod.rs create mode 100644 sentry-core/src/metrics/normalization/normalized_name.rs create mode 100644 sentry-core/src/metrics/normalization/normalized_tags.rs create mode 100644 sentry-core/src/metrics/normalization/normalized_unit.rs diff --git a/Cargo.lock b/Cargo.lock index 7c934098e..03d647348 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -272,6 +272,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "aligned" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "377e4c0ba83e4431b10df45c1d4666f178ea9c552cac93e60c3a88bf32785923" +dependencies = [ + "as-slice", +] + [[package]] name = "alloc-no-stdlib" version = "2.0.4" @@ -287,6 +296,21 @@ dependencies = [ "alloc-no-stdlib", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anes" version = "0.1.6" @@ -314,6 +338,15 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +[[package]] +name = "as-slice" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "516b6b4f0e40d50dcda9365d53964ec74560ad4284da2e7fc97122cd83174516" +dependencies = [ + "stable_deref_trait", +] + [[package]] name = "async-channel" version = "1.9.0" @@ -673,6 +706,28 @@ version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" +[[package]] +name = "bindgen" +version = "0.63.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36d860121800b2a9a94f9b5604b332d5cffb234ce17609ea479d723dbc9d3885" +dependencies = [ + "bitflags 1.3.2", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 1.0.109", + "which", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -740,12 +795,41 @@ dependencies = [ "alloc-stdlib", ] +[[package]] +name = "bstr" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "build-time" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1219c19fc29b7bfd74b7968b420aff5bc951cf517800176e795d6b2300dd382" +dependencies = [ + "chrono", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.58", +] + [[package]] name = "bumpalo" version = "3.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "bytes" version = "0.5.6" @@ -776,6 +860,38 @@ dependencies = [ "crossbeam-channel", ] +[[package]] +name = "camino" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +dependencies = [ + "camino", + "cargo-platform", + "semver 1.0.20", + "serde", + "serde_json", + "thiserror", +] + [[package]] name = "cast" version = "0.3.0" @@ -792,12 +908,33 @@ dependencies = [ "libc", ] +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom 7.1.3", +] + [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "windows-targets 0.52.4", +] + [[package]] name = "ciborium" version = "0.2.1" @@ -834,6 +971,17 @@ dependencies = [ "generic-array", ] +[[package]] +name = "clang-sys" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "clap" version = "4.4.10" @@ -859,6 +1007,15 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +[[package]] +name = "cmake" +version = "0.1.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" +dependencies = [ + "cc", +] + [[package]] name = "concurrent-queue" version = "2.3.0" @@ -875,7 +1032,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b076e143e1d9538dde65da30f8481c2a6c44040edb8e02b9bf1351edb92ce3" dependencies = [ "lazy_static", - "nom", + "nom 5.1.3", "serde", ] @@ -885,6 +1042,26 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbdcdcb6d86f71c5e97409ad45898af11cbc995b4ee8112d59095a28d376c935" +[[package]] +name = "const_format" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + [[package]] name = "convert_case" version = "0.4.0" @@ -952,9 +1129,9 @@ checksum = "dcb25d077389e53838a8158c8e99174c5a9d902dee4904320db714f3c653ffba" [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] @@ -971,7 +1148,7 @@ dependencies = [ "clap", "criterion-plot", "is-terminal", - "itertools", + "itertools 0.10.5", "num-traits", "once_cell", "oorandom", @@ -992,9 +1169,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" dependencies = [ "cast", - "itertools", + "itertools 0.10.5", ] +[[package]] +name = "critical-section" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" + [[package]] name = "crossbeam-channel" version = "0.5.8" @@ -1108,6 +1291,49 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "cvt" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ae9bf77fbf2d39ef573205d554d87e86c12f1994e9ea335b0651b9b278bcf1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "darling" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "syn 2.0.58", +] + +[[package]] +name = "darling_macro" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.58", +] + [[package]] name = "dashmap" version = "5.5.3" @@ -1145,6 +1371,38 @@ dependencies = [ "uuid", ] +[[package]] +name = "defmt" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a99dd22262668b887121d4672af5a64b238f026099f1a2a1b322066c9ecfe9e0" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9f309eff1f79b3ebdf252954d90ae440599c26c2c553fe87a2d17195f2dcb" +dependencies = [ + "defmt-parser", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.58", +] + +[[package]] +name = "defmt-parser" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4a5fefe330e8d7f31b16a318f9ce81000d8e35e69b93eae154d16d2278f70f" +dependencies = [ + "thiserror", +] + [[package]] name = "deranged" version = "0.3.9" @@ -1198,6 +1456,127 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +[[package]] +name = "embassy-futures" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f878075b9794c1e4ac788c95b728f26aa6366d32eeb10c7051389f898f7d067" + +[[package]] +name = "embassy-sync" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd938f25c0798db4280fcd8026bf4c2f48789aebf8f77b6e5cf8a7693ba114ec" +dependencies = [ + "cfg-if", + "critical-section", + "embedded-io-async", + "futures-util", + "heapless", +] + +[[package]] +name = "embedded-can" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9d2e857f87ac832df68fa498d18ddc679175cf3d2e4aa893988e5601baf9438" +dependencies = [ + "nb 1.1.0", +] + +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "embedded-hal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" + +[[package]] +name = "embedded-hal-async" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884" +dependencies = [ + "embedded-hal 1.0.0", +] + +[[package]] +name = "embedded-hal-nb" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba4268c14288c828995299e59b12babdbe170f6c6d73731af1b4648142e8605" +dependencies = [ + "embedded-hal 1.0.0", + "nb 1.1.0", +] + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + +[[package]] +name = "embedded-io-async" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f" +dependencies = [ + "embedded-io", +] + +[[package]] +name = "embedded-svc" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac6f87e7654f28018340aa55f933803017aefabaa5417820a3b2f808033c7bbc" +dependencies = [ + "defmt", + "embedded-io", + "embedded-io-async", + "enumset", + "heapless", + "log", + "no-std-net", + "num_enum", + "serde", + "strum 0.25.0", + "strum_macros 0.25.3", +] + +[[package]] +name = "embuild" +version = "0.31.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4caa4f198bb9152a55c0103efb83fa4edfcbb8625f4c9e94ae8ec8e23827c563" +dependencies = [ + "anyhow", + "bindgen", + "bitflags 1.3.2", + "cmake", + "filetime", + "globwalk", + "home", + "log", + "remove_dir_all", + "serde", + "serde_json", + "shlex", + "strum 0.24.1", + "tempfile", + "thiserror", + "which", +] + [[package]] name = "encoding_rs" version = "0.8.33" @@ -1207,6 +1586,28 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "enumset" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "226c0da7462c13fb57e5cc9e0dc8f0635e7d27f276a3a7fd30054647f669007d" +dependencies = [ + "enumset_derive", + "serde", +] + +[[package]] +name = "enumset_derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.58", +] + [[package]] name = "env_logger" version = "0.10.1" @@ -1220,6 +1621,15 @@ dependencies = [ "termcolor", ] +[[package]] +name = "envy" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f47e0157f2cb54f5ae1bd371b30a2ae4311e1c028f575cd4e81de7353215965" +dependencies = [ + "serde", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -1245,6 +1655,68 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "esp-idf-hal" +version = "0.43.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7adf3fb19a9ca016cbea1ab8a7b852ac69df8fcde4923c23d3b155efbc42a74" +dependencies = [ + "atomic-waker", + "embassy-sync", + "embedded-can", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-hal-nb", + "embedded-io", + "embedded-io-async", + "embuild", + "enumset", + "esp-idf-sys", + "heapless", + "log", + "nb 1.1.0", + "num_enum", +] + +[[package]] +name = "esp-idf-svc" +version = "0.48.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2180642ca122a7fec1ec417a9b1a77aa66aaa067fdf1daae683dd8caba84f26b" +dependencies = [ + "embassy-futures", + "embedded-hal-async", + "embedded-svc", + "embuild", + "enumset", + "esp-idf-hal", + "heapless", + "log", + "num_enum", + "uncased", +] + +[[package]] +name = "esp-idf-sys" +version = "0.34.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e148f97c04ed3e9181a08bcdc9560a515aad939b0ba7f50a0022e294665e0af" +dependencies = [ + "anyhow", + "bindgen", + "build-time", + "cargo_metadata", + "const_format", + "embuild", + "envy", + "libc", + "regex", + "serde", + "strum 0.24.1", + "which", +] + [[package]] name = "event-listener" version = "2.5.3" @@ -1287,6 +1759,18 @@ version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" +[[package]] +name = "filetime" +version = "0.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "windows-sys 0.52.0", +] + [[package]] name = "findshlibs" version = "0.10.2" @@ -1350,6 +1834,20 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs_at" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "982f82cc75107eef84f417ad6c53ae89bf65b561937ca4a3b3b0fd04d0aa2425" +dependencies = [ + "aligned", + "cfg-if", + "cvt", + "libc", + "nix", + "windows-sys 0.48.0", +] + [[package]] name = "futures" version = "0.3.29" @@ -1528,6 +2026,30 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "globset" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "globwalk" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" +dependencies = [ + "bitflags 1.3.2", + "ignore", + "walkdir", +] + [[package]] name = "gloo-timers" version = "0.2.6" @@ -1565,6 +2087,15 @@ version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -1577,6 +2108,23 @@ version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "hash32", + "serde", + "stable_deref_trait", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "hermit-abi" version = "0.3.9" @@ -1609,6 +2157,15 @@ dependencies = [ "digest 0.9.0", ] +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "hostname" version = "0.4.0" @@ -1843,6 +2400,35 @@ dependencies = [ "tracing", ] +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "0.5.0" @@ -1853,6 +2439,22 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "ignore" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" +dependencies = [ + "crossbeam-deque", + "globset", + "log", + "memchr", + "regex-automata", + "same-file", + "walkdir", + "winapi-util", +] + [[package]] name = "indexmap" version = "1.9.3" @@ -1950,6 +2552,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -1995,6 +2606,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + [[package]] name = "lexical-core" version = "0.7.6" @@ -2014,6 +2631,16 @@ version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +[[package]] +name = "libloading" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" +dependencies = [ + "cfg-if", + "windows-targets 0.52.4", +] + [[package]] name = "libnghttp2-sys" version = "0.1.8+1.55.1" @@ -2121,6 +2748,12 @@ dependencies = [ "unicase", ] +[[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.7.2" @@ -2160,6 +2793,41 @@ dependencies = [ "tempfile", ] +[[package]] +name = "nb" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" +dependencies = [ + "nb 1.1.0", +] + +[[package]] +name = "nb" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" + +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", +] + +[[package]] +name = "no-std-net" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bcece43b12349917e096cddfa66107277f123e6c96a5aea78711dc601a47152" +dependencies = [ + "serde", +] + [[package]] name = "nom" version = "5.1.3" @@ -2171,6 +2839,25 @@ dependencies = [ "version_check", ] +[[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 = "normpath" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5831952a9476f2fed74b77d74182fa5ddc4d21c72ec45a333b250e3ed0272804" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -2200,6 +2887,27 @@ dependencies = [ "libc", ] +[[package]] +name = "num_enum" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.58", +] + [[package]] name = "object" version = "0.32.2" @@ -2323,6 +3031,12 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +[[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" @@ -2469,6 +3183,39 @@ dependencies = [ "log", ] +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro-hack" version = "0.5.20+deprecated" @@ -2501,7 +3248,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19de2de2a00075bf566bee3bd4db014b11587e84184d3f7a791bc17f1a8e9e48" dependencies = [ "anyhow", - "itertools", + "itertools 0.10.5", "proc-macro2", "quote", "syn 2.0.58", @@ -2651,6 +3398,22 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c707298afce11da2efef2f600116fa93ffa7a032b5d7b628aa17711ec81383ca" +[[package]] +name = "remove_dir_all" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23895cfadc1917fed9c6ed76a8c2903615fa3704f7493ff82b364c6540acc02b" +dependencies = [ + "aligned", + "cfg-if", + "cvt", + "fs_at", + "lazy_static", + "libc", + "normpath", + "windows-sys 0.45.0", +] + [[package]] name = "reqwest" version = "0.12.3" @@ -2746,6 +3509,12 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustc_version" version = "0.2.3" @@ -2937,6 +3706,9 @@ name = "semver" version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +dependencies = [ + "serde", +] [[package]] name = "semver-parser" @@ -2946,11 +3718,13 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "sentry" -version = "0.32.2" +version = "0.32.3" dependencies = [ "actix-web", "anyhow", "curl", + "embedded-svc", + "esp-idf-svc", "http-client", "httpdate", "isahc", @@ -2982,7 +3756,7 @@ dependencies = [ [[package]] name = "sentry-actix" -version = "0.32.2" +version = "0.32.3" dependencies = [ "actix-web", "futures", @@ -2994,7 +3768,7 @@ dependencies = [ [[package]] name = "sentry-anyhow" -version = "0.32.2" +version = "0.32.3" dependencies = [ "anyhow", "sentry", @@ -3004,7 +3778,7 @@ dependencies = [ [[package]] name = "sentry-backtrace" -version = "0.32.2" +version = "0.32.3" dependencies = [ "backtrace", "once_cell", @@ -3014,7 +3788,7 @@ dependencies = [ [[package]] name = "sentry-contexts" -version = "0.32.2" +version = "0.32.3" dependencies = [ "hostname", "libc", @@ -3027,16 +3801,19 @@ dependencies = [ [[package]] name = "sentry-core" -version = "0.32.2" +version = "0.32.3" dependencies = [ "anyhow", "cadence", + "crc32fast", "criterion", "futures", + "itertools 0.13.0", "log", "once_cell", "rand 0.8.5", "rayon", + "regex", "sentry", "sentry-types", "serde", @@ -3048,7 +3825,7 @@ dependencies = [ [[package]] name = "sentry-debug-images" -version = "0.32.2" +version = "0.32.3" dependencies = [ "findshlibs", "once_cell", @@ -3057,7 +3834,7 @@ dependencies = [ [[package]] name = "sentry-log" -version = "0.32.2" +version = "0.32.3" dependencies = [ "log", "pretty_env_logger", @@ -3067,7 +3844,7 @@ dependencies = [ [[package]] name = "sentry-panic" -version = "0.32.2" +version = "0.32.3" dependencies = [ "sentry", "sentry-backtrace", @@ -3076,7 +3853,7 @@ dependencies = [ [[package]] name = "sentry-slog" -version = "0.32.2" +version = "0.32.3" dependencies = [ "erased-serde", "sentry", @@ -3088,7 +3865,7 @@ dependencies = [ [[package]] name = "sentry-tower" -version = "0.32.2" +version = "0.32.3" dependencies = [ "anyhow", "axum 0.7.1", @@ -3108,7 +3885,7 @@ dependencies = [ [[package]] name = "sentry-tracing" -version = "0.32.2" +version = "0.32.3" dependencies = [ "log", "sentry", @@ -3122,7 +3899,7 @@ dependencies = [ [[package]] name = "sentry-types" -version = "0.32.2" +version = "0.32.3" dependencies = [ "debugid", "hex", @@ -3238,6 +4015,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -3326,6 +4109,12 @@ dependencies = [ "lock_api", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "standback" version = "0.2.17" @@ -3390,6 +4179,50 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" +dependencies = [ + "strum_macros 0.24.3", +] + +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +dependencies = [ + "strum_macros 0.25.3", +] + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 1.0.109", +] + +[[package]] +name = "strum_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.58", +] + [[package]] name = "subtle" version = "2.5.0" @@ -3675,6 +4508,23 @@ dependencies = [ "tracing", ] +[[package]] +name = "toml_datetime" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" + +[[package]] +name = "toml_edit" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap 2.2.6", + "toml_datetime", + "winnow", +] + [[package]] name = "tonic" version = "0.11.0" @@ -3823,6 +4673,15 @@ dependencies = [ "libc", ] +[[package]] +name = "uncased" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1b88fcfe09e89d3866a5c11019378088af2d24c3fbd4f0543f96b479ec90697" +dependencies = [ + "version_check", +] + [[package]] name = "unicase" version = "2.7.0" @@ -3853,6 +4712,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + [[package]] name = "universal-hash" version = "0.4.0" @@ -3931,6 +4796,12 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + [[package]] name = "waker-fn" version = "1.1.1" @@ -4059,6 +4930,18 @@ dependencies = [ "rustls-pki-types", ] +[[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.32", +] + [[package]] name = "winapi" version = "0.3.9" @@ -4109,6 +4992,15 @@ dependencies = [ "windows-targets 0.52.4", ] +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -4127,6 +5019,21 @@ dependencies = [ "windows-targets 0.52.4", ] +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + [[package]] name = "windows-targets" version = "0.48.5" @@ -4157,6 +5064,12 @@ dependencies = [ "windows_x86_64_msvc 0.52.4", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -4169,6 +5082,12 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -4181,6 +5100,12 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -4193,6 +5118,12 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -4205,6 +5136,12 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -4217,6 +5154,12 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -4229,6 +5172,12 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -4241,6 +5190,15 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.52.0" diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index 3c2bfd0e9..619f2d314 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -31,9 +31,12 @@ UNSTABLE_cadence = ["dep:cadence", "UNSTABLE_metrics"] [dependencies] cadence = { version = "0.29.0", optional = true } +crc32fast = "1.4.0" +itertools = "0.13.0" log = { version = "0.4.8", optional = true, features = ["std"] } once_cell = "1" rand = { version = "0.8.1", optional = true } +regex = "1.7.3" sentry-types = { version = "0.32.3", path = "../sentry-types" } serde = { version = "1.0.104", features = ["derive"] } serde_json = { version = "1.0.46" } diff --git a/sentry-core/src/cadence.rs b/sentry-core/src/cadence.rs index 8cd7c3d0d..401f53d94 100644 --- a/sentry-core/src/cadence.rs +++ b/sentry-core/src/cadence.rs @@ -154,9 +154,10 @@ mod tests { println!("{metrics}"); - assert!(metrics.contains("sentry.test.count.with.tags:1|c|#foo:bar|T")); - assert!(metrics.contains("sentry.test.some.count:11|c|T")); - assert!(metrics.contains("sentry.test.some.distr:1:2:3|d|T")); + assert!(metrics + .contains("sentry.test.count.with.tags@none:1|c|#environment:production,foo:bar|T")); + assert!(metrics.contains("sentry.test.some.count@none:11|c|#environment:production|T")); + assert!(metrics.contains("sentry.test.some.distr@none:1:2:3|d|#environment:production|T")); assert_eq!(items.next(), None); } } diff --git a/sentry-core/src/client.rs b/sentry-core/src/client.rs index a485d99ca..ed52f05b9 100644 --- a/sentry-core/src/client.rs +++ b/sentry-core/src/client.rs @@ -207,13 +207,13 @@ impl Client { } if event.release.is_none() { - event.release = self.options.release.clone(); + event.release.clone_from(&self.options.release); } if event.environment.is_none() { - event.environment = self.options.environment.clone(); + event.environment.clone_from(&self.options.environment); } if event.server_name.is_none() { - event.server_name = self.options.server_name.clone(); + event.server_name.clone_from(&self.options.server_name); } if &event.platform == "other" { event.platform = "native".into(); diff --git a/sentry-core/src/metrics.rs b/sentry-core/src/metrics/mod.rs similarity index 86% rename from sentry-core/src/metrics.rs rename to sentry-core/src/metrics/mod.rs index 0e8b6f3b9..65cd74781 100644 --- a/sentry-core/src/metrics.rs +++ b/sentry-core/src/metrics/mod.rs @@ -44,10 +44,12 @@ //! //! [our docs]: https://develop.sentry.dev/delightful-developer-metrics/ +mod normalization; + use std::borrow::Cow; -use std::collections::hash_map::{DefaultHasher, Entry}; +use std::collections::hash_map::Entry; use std::collections::{BTreeMap, BTreeSet, HashMap}; -use std::fmt::{self, Write}; +use std::fmt::{self, Display}; use std::sync::{Arc, Mutex}; use std::thread::{self, JoinHandle}; use std::time::{Duration, SystemTime, UNIX_EPOCH}; @@ -168,15 +170,23 @@ impl MetricValue { } } +impl Display for MetricValue { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Counter(v) => write!(f, "{}", v), + Self::Distribution(v) => write!(f, "{}", v), + Self::Gauge(v) => write!(f, "{}", v), + Self::Set(v) => write!(f, "{}", v), + } + } +} + /// Hashes the given set value. /// /// Sets only guarantee 32-bit accuracy, but arbitrary strings are allowed on the protocol. Upon /// parsing, they are hashed and only used as hashes subsequently. fn hash_set_value(string: &str) -> u32 { - use std::hash::Hasher; - let mut hasher = DefaultHasher::default(); - hasher.write(string.as_bytes()); - hasher.finish() as u32 + crc32fast::hash(string.as_bytes()) } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] @@ -510,6 +520,26 @@ impl Metric { client.add_metric(self); } } + + /// Convert the metric into an [`Envelope`] containing a single [`EnvelopeItem::Statsd`]. + pub fn to_envelope(self) -> Envelope { + let timestamp = self + .time + .unwrap_or(SystemTime::now()) + .duration_since(UNIX_EPOCH) + .unwrap_or_default() + .as_secs(); + let data = format!( + "{}@{}:{}|{}|#{}|T{}", + normalization::normalize_name(self.name.as_ref()), + normalization::normalize_unit(self.unit.to_string().as_ref()), + self.value, + self.value.ty(), + normalization::normalize_tags(&self.tags), + timestamp + ); + EnvelopeItem::Statsd(data.into_bytes()).into() + } } /// A builder for metrics. @@ -550,6 +580,26 @@ impl MetricBuilder { self } + /// Adds multiple tags to the metric. + /// + /// Tags allow you to add dimensions to metrics. They are key-value pairs that can be filtered + /// or grouped by in Sentry. + /// + /// When sent to Sentry via [`MetricBuilder::send`] or when added to a + /// [`Client`](crate::Client), the client may add default tags to the metrics, such as the + /// `release` or the `environment` from the Scope. + pub fn with_tags(mut self, tags: T) -> Self + where + T: IntoIterator, + K: Into, + V: Into, + { + for (k, v) in tags { + self.metric.tags.insert(k.into(), v.into()); + } + self + } + /// Sets the timestamp for the metric. /// /// By default, the timestamp is set to the current time when the metric is built or sent. @@ -723,9 +773,14 @@ fn get_default_tags(options: &ClientOptions) -> TagMap { if let Some(ref release) = options.release { tags.insert("release".into(), release.clone()); } - if let Some(ref environment) = options.environment { - tags.insert("environment".into(), environment.clone()); - } + tags.insert( + "environment".into(), + options + .environment + .clone() + .filter(|e| !e.is_empty()) + .unwrap_or(Cow::Borrowed("production")), + ); tags } @@ -778,11 +833,17 @@ impl Worker { for (timestamp, buckets) in buckets { for (key, value) in buckets { - write!(&mut out, "{}", SafeKey(key.name.as_ref()))?; - if key.unit != MetricUnit::None { - write!(&mut out, "@{}", key.unit)?; + write!( + &mut out, + "{}", + normalization::normalize_name(key.name.as_ref()) + )?; + match key.unit { + MetricUnit::Custom(u) => { + write!(&mut out, "@{}", normalization::normalize_unit(u.as_ref()))? + } + _ => write!(&mut out, "@{}", key.unit)?, } - match value { BucketValue::Counter(c) => { write!(&mut out, ":{}", c)?; @@ -807,16 +868,9 @@ impl Worker { } write!(&mut out, "|{}", key.ty.as_str())?; - - for (i, (k, v)) in key.tags.iter().chain(&self.default_tags).enumerate() { - match i { - 0 => write!(&mut out, "|#")?, - _ => write!(&mut out, ",")?, - } - - write!(&mut out, "{}:{}", SafeKey(k.as_ref()), SafeVal(v.as_ref()))?; - } - + let normalized_tags = + normalization::normalize_tags(&key.tags).with_default_tags(&self.default_tags); + write!(&mut out, "|#{}", normalized_tags)?; writeln!(&mut out, "|T{}", timestamp)?; } } @@ -922,51 +976,6 @@ impl Drop for MetricAggregator { } } -fn safe_fmt(f: &mut fmt::Formatter<'_>, string: &str, mut check: F) -> fmt::Result -where - F: FnMut(char) -> bool, -{ - let mut valid = true; - - for c in string.chars() { - if check(c) { - valid = true; - f.write_char(c)?; - } else if valid { - valid = false; - f.write_char('_')?; - } - } - - Ok(()) -} - -// Helper that serializes a string into a safe format for metric names or tag keys. -struct SafeKey<'s>(&'s str); - -impl<'s> fmt::Display for SafeKey<'s> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - safe_fmt(f, self.0, |c| { - c.is_ascii_alphanumeric() || matches!(c, '_' | '-' | '.' | '/') - }) - } -} - -// Helper that serializes a string into a safe format for tag values. -struct SafeVal<'s>(&'s str); - -impl<'s> fmt::Display for SafeVal<'s> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - safe_fmt(f, self.0, |c| { - c.is_alphanumeric() - || matches!( - c, - '_' | ':' | '/' | '@' | '.' | '{' | '}' | '[' | ']' | '$' | '-' - ) - }) - } -} - #[cfg(test)] mod tests { use crate::test::{with_captured_envelopes, with_captured_envelopes_options}; @@ -1007,7 +1016,10 @@ mod tests { }); let metrics = get_single_metrics(&envelopes); - assert_eq!(metrics, format!("my.metric:1|c|#and:more,foo:bar|T{ts}")); + assert_eq!( + metrics, + format!("my.metric@none:1|c|#and:more,environment:production,foo:bar|T{ts}") + ); } #[test] @@ -1022,7 +1034,10 @@ mod tests { }); let metrics = get_single_metrics(&envelopes); - assert_eq!(metrics, format!("my.metric@custom:1|c|T{ts}")); + assert_eq!( + metrics, + format!("my.metric@custom:1|c|#environment:production|T{ts}") + ); } #[test] @@ -1034,7 +1049,10 @@ mod tests { }); let metrics = get_single_metrics(&envelopes); - assert_eq!(metrics, format!("my_metric:1|c|T{ts}")); + assert_eq!( + metrics, + format!("my___metric@none:1|c|#environment:production|T{ts}") + ); } #[test] @@ -1051,29 +1069,43 @@ mod tests { let metrics = get_single_metrics(&envelopes); assert_eq!( metrics, - format!("my.metric:1|c|#foo-bar_blub:_$föö{{}}|T{ts}") + format!("my.metric@none:1|c|#environment:production,foo-barblub:%$föö{{}}|T{ts}") ); } #[test] - fn test_own_namespace() { + fn test_default_tags() { let (time, ts) = current_time(); - let envelopes = with_captured_envelopes(|| { - Metric::count("ns/my.metric").with_time(time).send(); - }); + let options = ClientOptions { + release: Some("myapp@1.0.0".into()), + environment: Some("development".into()), + ..Default::default() + }; + + let envelopes = with_captured_envelopes_options( + || { + Metric::count("requests") + .with_tag("foo", "bar") + .with_time(time) + .send(); + }, + options, + ); let metrics = get_single_metrics(&envelopes); - assert_eq!(metrics, format!("ns/my.metric:1|c|T{ts}")); + assert_eq!( + metrics, + format!("requests@none:1|c|#environment:development,foo:bar,release:myapp@1.0.0|T{ts}") + ); } #[test] - fn test_default_tags() { + fn test_empty_default_tags() { let (time, ts) = current_time(); - let options = ClientOptions { - release: Some("myapp@1.0.0".into()), - environment: Some("production".into()), + release: Some("".into()), + environment: Some("".into()), ..Default::default() }; @@ -1090,7 +1122,34 @@ mod tests { let metrics = get_single_metrics(&envelopes); assert_eq!( metrics, - format!("requests:1|c|#foo:bar,environment:production,release:myapp@1.0.0|T{ts}") + format!("requests@none:1|c|#environment:production,foo:bar|T{ts}") + ); + } + + #[test] + fn test_override_default_tags() { + let (time, ts) = current_time(); + let options = ClientOptions { + release: Some("default_release".into()), + environment: Some("default_env".into()), + ..Default::default() + }; + + let envelopes = with_captured_envelopes_options( + || { + Metric::count("requests") + .with_tag("environment", "custom_env") + .with_tag("release", "custom_release") + .with_time(time) + .send(); + }, + options, + ); + + let metrics = get_single_metrics(&envelopes); + assert_eq!( + metrics, + format!("requests@none:1|c|#environment:custom_env,release:custom_release|T{ts}") ); } @@ -1104,7 +1163,10 @@ mod tests { }); let metrics = get_single_metrics(&envelopes); - assert_eq!(metrics, format!("my.metric:3|c|T{ts}")); + assert_eq!( + metrics, + format!("my.metric@none:3|c|#environment:production|T{ts}") + ); } #[test] @@ -1121,7 +1183,10 @@ mod tests { }); let metrics = get_single_metrics(&envelopes); - assert_eq!(metrics, format!("my.metric@second:0.2:0.1|d|T{ts}")); + assert_eq!( + metrics, + format!("my.metric@second:0.2:0.1|d|#environment:production|T{ts}") + ); } #[test] @@ -1138,7 +1203,10 @@ mod tests { }); let metrics = get_single_metrics(&envelopes); - assert_eq!(metrics, format!("my.metric:2:1|d|T{ts}")); + assert_eq!( + metrics, + format!("my.metric@none:2:1|d|#environment:production|T{ts}") + ); } #[test] @@ -1153,7 +1221,10 @@ mod tests { }); let metrics = get_single_metrics(&envelopes); - assert_eq!(metrics, format!("my.metric:3410894750:3817476724|s|T{ts}")); + assert_eq!( + metrics, + format!("my.metric@none:907060870:980881731|s|#environment:production|T{ts}") + ); } #[test] @@ -1167,7 +1238,10 @@ mod tests { }); let metrics = get_single_metrics(&envelopes); - assert_eq!(metrics, format!("my.metric:1.5:1:2:4.5:3|g|T{ts}")); + assert_eq!( + metrics, + format!("my.metric@none:1.5:1:2:4.5:3|g|#environment:production|T{ts}") + ); } #[test] @@ -1182,8 +1256,8 @@ mod tests { let metrics = get_single_metrics(&envelopes); println!("{metrics}"); - assert!(metrics.contains(&format!("my.metric:1|c|T{ts}"))); - assert!(metrics.contains(&format!("my.dist:2|d|T{ts}"))); + assert!(metrics.contains(&format!("my.metric@none:1|c|#environment:production|T{ts}"))); + assert!(metrics.contains(&format!("my.dist@none:2|d|#environment:production|T{ts}"))); } #[test] diff --git a/sentry-core/src/metrics/normalization/mod.rs b/sentry-core/src/metrics/normalization/mod.rs new file mode 100644 index 000000000..2b228b90b --- /dev/null +++ b/sentry-core/src/metrics/normalization/mod.rs @@ -0,0 +1,28 @@ +pub mod normalized_name; +pub mod normalized_tags; +pub mod normalized_unit; + +pub use normalized_name::normalize_name; +pub use normalized_tags::normalize_tags; +pub use normalized_unit::normalize_unit; + +pub fn truncate(s: &str, max_chars: usize) -> &str { + match s.char_indices().nth(max_chars) { + None => s, + Some((i, _)) => &s[..i], + } +} + +#[cfg(test)] +mod test { + + #[test] + fn test_truncate_ascii_chars() { + assert_eq!("abc", super::truncate("abcde", 3)); + } + + #[test] + fn test_truncate_unicode_chars() { + assert_eq!("😀😀😀", super::truncate("😀😀😀😀😀", 3)); + } +} diff --git a/sentry-core/src/metrics/normalization/normalized_name.rs b/sentry-core/src/metrics/normalization/normalized_name.rs new file mode 100644 index 000000000..4abc2fe1e --- /dev/null +++ b/sentry-core/src/metrics/normalization/normalized_name.rs @@ -0,0 +1,33 @@ +use std::{borrow::Cow, sync::OnceLock}; + +use regex::Regex; + +pub fn normalize_name(name: &str) -> Cow { + static METRIC_NAME_RE: OnceLock = OnceLock::new(); + METRIC_NAME_RE + .get_or_init(|| Regex::new(r"[^a-zA-Z0-9_\-.]").expect("Regex should compile")) + .replace_all(super::truncate(name, 150), "_") +} + +#[cfg(test)] +mod test { + + #[test] + fn test_from() { + let expected = "aA1_-.____________"; + + let actual = super::normalize_name("aA1_-./+ö{😀\n\t\r\\| ,"); + + assert_eq!(expected, actual); + } + + #[test] + fn test_length_restriction() { + let expected = "a".repeat(150); + + let too_long_name = "a".repeat(155); + let actual = super::normalize_name(&too_long_name); + + assert_eq!(expected, actual); + } +} diff --git a/sentry-core/src/metrics/normalization/normalized_tags.rs b/sentry-core/src/metrics/normalization/normalized_tags.rs new file mode 100644 index 000000000..f98935fb4 --- /dev/null +++ b/sentry-core/src/metrics/normalization/normalized_tags.rs @@ -0,0 +1,179 @@ +use itertools::Itertools; +use regex::Regex; +use std::{borrow::Cow, collections::HashMap, sync::OnceLock}; + +use crate::metrics::TagMap; + +pub fn normalize_tags(tags: &TagMap) -> NormalizedTags { + NormalizedTags { + tags: tags + .iter() + .map(|(k, v)| { + ( + NormalizedTags::normalize_key(super::truncate(k, 32)), + NormalizedTags::normalize_value(super::truncate(v, 200)), + ) + }) + .filter(|(k, v)| !k.is_empty() && !v.is_empty()) + .collect(), + } +} + +pub struct NormalizedTags<'a> { + tags: HashMap, String>, +} + +impl<'a> NormalizedTags<'a> { + pub fn with_default_tags(mut self, tags: &'a TagMap) -> Self { + for (k, v) in tags { + let k = Self::normalize_key(super::truncate(k, 32)); + let v = Self::normalize_value(super::truncate(v, 200)); + if !k.is_empty() && !v.is_empty() { + self.tags.entry(k).or_insert(v); + } + } + self + } + + fn normalize_key(key: &str) -> Cow { + static METRIC_TAG_KEY_RE: OnceLock = OnceLock::new(); + METRIC_TAG_KEY_RE + .get_or_init(|| Regex::new(r"[^a-zA-Z0-9_\-./]").expect("Regex should compile")) + .replace_all(key, "") + } + + fn normalize_value(value: &str) -> String { + let mut escaped = String::with_capacity(value.len()); + for c in value.chars() { + match c { + '\t' => escaped.push_str("\\t"), + '\n' => escaped.push_str("\\n"), + '\r' => escaped.push_str("\\r"), + '\\' => escaped.push_str("\\\\"), + '|' => escaped.push_str("\\u{7c}"), + ',' => escaped.push_str("\\u{2c}"), + _ if c.is_control() => (), + _ => escaped.push(c), + } + } + escaped + } +} + +impl std::fmt::Display for NormalizedTags<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let res = self + .tags + .iter() + .map(|(k, v)| format!("{}:{}", k, v)) + .sorted() + .join(","); + write!(f, "{res}") + } +} + +#[cfg(test)] +mod test { + use super::TagMap; + + #[test] + fn test_replacement_characters() { + let tags = TagMap::from_iter( + [ + ("a\na", "a\na"), + ("b\rb", "b\rb"), + ("c\tc", "c\tc"), + ("d\\d", "d\\d"), + ("e|e", "e|e"), + ("f,f", "f,f"), + ] + .into_iter() + .map(|(k, v)| (k.into(), v.into())), + ); + let expected = "aa:a\\na,bb:b\\rb,cc:c\\tc,dd:d\\\\d,ee:e\\u{7c}e,ff:f\\u{2c}f"; + + let actual = super::normalize_tags(&tags).to_string(); + + assert_eq!(expected, actual); + } + + #[test] + fn test_empty_tags() { + let tags = TagMap::from_iter( + [("+", "a"), ("a", ""), ("", "a"), ("", "")] + .into_iter() + .map(|(k, v)| (k.into(), v.into())), + ); + let expected = ""; + + let actual = super::normalize_tags(&tags).to_string(); + + assert_eq!(expected, actual); + } + + #[test] + fn test_special_characters() { + let tags = TagMap::from([("aA1_-./+ö{ 😀".into(), "aA1_-./+ö{ 😀".into())]); + let expected = "aA1_-./:aA1_-./+ö{ 😀"; + + let actual = super::normalize_tags(&tags).to_string(); + + assert_eq!(expected, actual); + } + + #[test] + fn test_add_default_tags() { + let default_tags = TagMap::from([ + ("release".into(), "default_release".into()), + ("environment".into(), "production".into()), + ]); + let expected = "environment:production,release:default_release"; + + let actual = super::normalize_tags(&TagMap::new()) + .with_default_tags(&default_tags) + .to_string(); + + assert_eq!(expected, actual); + } + + #[test] + fn test_override_default_tags() { + let default_tags = TagMap::from([ + ("release".into(), "default_release".into()), + ("environment".into(), "production".into()), + ]); + let expected = "environment:custom_env,release:custom_release"; + + let actual = super::normalize_tags(&TagMap::from([ + ("release".into(), "custom_release".into()), + ("environment".into(), "custom_env".into()), + ])) + .with_default_tags(&default_tags) + .to_string(); + + assert_eq!(expected, actual); + } + + #[test] + fn test_length_restriction() { + let expected = "dk".repeat(16) + + ":" + + "dv".repeat(100).as_str() + + "," + + "k".repeat(32).as_str() + + ":" + + "v".repeat(200).as_str(); + + let actual = super::normalize_tags(&TagMap::from([( + "k".repeat(35).into(), + "v".repeat(210).into(), + )])) + .with_default_tags(&TagMap::from([( + "dk".repeat(35).into(), + "dv".repeat(210).into(), + )])) + .to_string(); + + assert_eq!(expected, actual); + } +} diff --git a/sentry-core/src/metrics/normalization/normalized_unit.rs b/sentry-core/src/metrics/normalization/normalized_unit.rs new file mode 100644 index 000000000..e6b488b12 --- /dev/null +++ b/sentry-core/src/metrics/normalization/normalized_unit.rs @@ -0,0 +1,57 @@ +use std::{borrow::Cow, sync::OnceLock}; + +use regex::Regex; + +use crate::units::MetricUnit; + +pub fn normalize_unit(unit: &str) -> Cow { + static METRIC_UNIT_RE: OnceLock = OnceLock::new(); + let normalized_unit = METRIC_UNIT_RE + .get_or_init(|| Regex::new(r"[^a-zA-Z0-9_]").expect("Regex should compile")) + .replace_all(super::truncate(unit, 15), ""); + if normalized_unit.is_empty() { + MetricUnit::None.to_string().into() + } else { + normalized_unit + } +} + +#[cfg(test)] +mod test { + + #[test] + fn test_from() { + let expected = "aA1_"; + + let actual = super::normalize_unit("aA1_-./+ö{😀\n\t\r\\| ,").to_string(); + + assert_eq!(expected, actual); + } + + #[test] + fn test_from_empty() { + let expected = "none"; + + let actual = super::normalize_unit("").to_string(); + + assert_eq!(expected, actual); + } + + #[test] + fn test_from_empty_after_normalization() { + let expected = "none"; + + let actual = super::normalize_unit("+").to_string(); + + assert_eq!(expected, actual); + } + + #[test] + fn test_length_restriction() { + let expected = "a".repeat(15); + + let actual = super::normalize_unit("a".repeat(20).as_ref()).to_string(); + + assert_eq!(expected, actual); + } +} diff --git a/sentry-core/src/performance.rs b/sentry-core/src/performance.rs index d707c370b..552cc563b 100644 --- a/sentry-core/src/performance.rs +++ b/sentry-core/src/performance.rs @@ -552,8 +552,8 @@ impl Transaction { Hub::current().with_current_scope(|scope| scope.apply_to_transaction(&mut transaction)); let opts = client.options(); - transaction.release = opts.release.clone(); - transaction.environment = opts.environment.clone(); + transaction.release.clone_from(&opts.release); + transaction.environment.clone_from(&opts.environment); transaction.sdk = Some(std::borrow::Cow::Owned(client.sdk_info.clone())); drop(inner); diff --git a/sentry-core/src/units.rs b/sentry-core/src/units.rs index bc47af659..a0f5026c8 100644 --- a/sentry-core/src/units.rs +++ b/sentry-core/src/units.rs @@ -120,6 +120,12 @@ impl From> for MetricUnit { } } +impl From> for MetricUnit { + fn from(unit: Option) -> Self { + unit.map_or_else(|| Self::None, |u| Self::Custom(u.into())) + } +} + /// Time duration units used in [`MetricUnit::Duration`]. /// /// Defaults to `millisecond`. diff --git a/sentry-tracing/src/converters.rs b/sentry-tracing/src/converters.rs index 9f290607d..08f329098 100644 --- a/sentry-tracing/src/converters.rs +++ b/sentry-tracing/src/converters.rs @@ -279,10 +279,12 @@ where } if let Some(exception) = exceptions.last_mut() { - exception - .mechanism - .get_or_insert_with(Mechanism::default) - .ty = "tracing".to_owned(); + "tracing".clone_into( + &mut exception + .mechanism + .get_or_insert_with(Mechanism::default) + .ty, + ); } Event { diff --git a/sentry-types/src/protocol/envelope.rs b/sentry-types/src/protocol/envelope.rs index 56809a7f2..c978b74f3 100644 --- a/sentry-types/src/protocol/envelope.rs +++ b/sentry-types/src/protocol/envelope.rs @@ -533,26 +533,13 @@ impl Envelope { } } -impl From> for Envelope { - fn from(event: Event<'static>) -> Self { - let mut envelope = Self::default(); - envelope.add_item(event); - envelope - } -} - -impl From> for Envelope { - fn from(transaction: Transaction<'static>) -> Self { - let mut envelope = Self::default(); - envelope.add_item(transaction); - envelope - } -} - -impl From for Envelope { - fn from(check_in: MonitorCheckIn) -> Self { +impl From for Envelope +where + T: Into, +{ + fn from(item: T) -> Self { let mut envelope = Self::default(); - envelope.add_item(check_in); + envelope.add_item(item.into()); envelope } } From f063f79a9ad52566ad6c1ec2ef017087fed9e65e Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Mon, 27 May 2024 15:16:32 +0000 Subject: [PATCH 006/148] release: 0.33.0 --- CHANGELOG.md | 7 +++++++ sentry-actix/Cargo.toml | 4 ++-- sentry-anyhow/Cargo.toml | 6 +++--- sentry-backtrace/Cargo.toml | 4 ++-- sentry-contexts/Cargo.toml | 4 ++-- sentry-core/Cargo.toml | 4 ++-- sentry-core/README.md | 2 +- sentry-debug-images/Cargo.toml | 4 ++-- sentry-debug-images/README.md | 2 +- sentry-log/Cargo.toml | 4 ++-- sentry-panic/Cargo.toml | 6 +++--- sentry-slog/Cargo.toml | 4 ++-- sentry-tower/Cargo.toml | 4 ++-- sentry-tower/README.md | 2 +- sentry-tracing/Cargo.toml | 6 +++--- sentry-tracing/README.md | 2 +- sentry-types/Cargo.toml | 2 +- sentry/Cargo.toml | 22 +++++++++++----------- sentry/README.md | 12 ++++++------ 19 files changed, 54 insertions(+), 47 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b6c11098..7adcb234a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 0.33.0 + +### Various fixes & improvements + +- ref(metrics): Add normalization and update set metrics hashing (#658) by @elramen +- feat: add embedded-svc based http transport (#654) by @madmo + ## 0.32.3 **Compatiblity**: diff --git a/sentry-actix/Cargo.toml b/sentry-actix/Cargo.toml index 5da5bef38..d5eea3460 100644 --- a/sentry-actix/Cargo.toml +++ b/sentry-actix/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-actix" -version = "0.32.3" +version = "0.33.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -15,7 +15,7 @@ rust-version = "1.73" [dependencies] actix-web = { version = "4", default-features = false } futures-util = { version = "0.3.5", default-features = false } -sentry-core = { version = "0.32.3", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.33.0", path = "../sentry-core", default-features = false, features = [ "client", ] } diff --git a/sentry-anyhow/Cargo.toml b/sentry-anyhow/Cargo.toml index cbe957a93..849799dc7 100644 --- a/sentry-anyhow/Cargo.toml +++ b/sentry-anyhow/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-anyhow" -version = "0.32.3" +version = "0.33.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -17,8 +17,8 @@ default = ["backtrace"] backtrace = ["anyhow/backtrace"] [dependencies] -sentry-backtrace = { version = "0.32.3", path = "../sentry-backtrace" } -sentry-core = { version = "0.32.3", path = "../sentry-core" } +sentry-backtrace = { version = "0.33.0", path = "../sentry-backtrace" } +sentry-core = { version = "0.33.0", path = "../sentry-core" } anyhow = "1.0.39" [dev-dependencies] diff --git a/sentry-backtrace/Cargo.toml b/sentry-backtrace/Cargo.toml index 48c2c85c4..2becc83a6 100644 --- a/sentry-backtrace/Cargo.toml +++ b/sentry-backtrace/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-backtrace" -version = "0.32.3" +version = "0.33.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -19,4 +19,4 @@ regex = { version = "1.5.5", default-features = false, features = [ "std", "unicode-perl", ] } -sentry-core = { version = "0.32.3", path = "../sentry-core" } +sentry-core = { version = "0.33.0", path = "../sentry-core" } diff --git a/sentry-contexts/Cargo.toml b/sentry-contexts/Cargo.toml index dd9c258ff..f98af5706 100644 --- a/sentry-contexts/Cargo.toml +++ b/sentry-contexts/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-contexts" -version = "0.32.3" +version = "0.33.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -14,7 +14,7 @@ edition = "2021" rust-version = "1.73" [dependencies] -sentry-core = { version = "0.32.3", path = "../sentry-core" } +sentry-core = { version = "0.33.0", path = "../sentry-core" } libc = "0.2.66" hostname = "0.4" diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index 619f2d314..35faa89d6 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-core" -version = "0.32.3" +version = "0.33.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -37,7 +37,7 @@ log = { version = "0.4.8", optional = true, features = ["std"] } once_cell = "1" rand = { version = "0.8.1", optional = true } regex = "1.7.3" -sentry-types = { version = "0.32.3", path = "../sentry-types" } +sentry-types = { version = "0.33.0", path = "../sentry-types" } serde = { version = "1.0.104", features = ["derive"] } serde_json = { version = "1.0.46" } uuid = { version = "1.0.0", features = ["v4", "serde"], optional = true } diff --git a/sentry-core/README.md b/sentry-core/README.md index b29fa2dbf..b08c3e116 100644 --- a/sentry-core/README.md +++ b/sentry-core/README.md @@ -102,7 +102,7 @@ functionality. [Sentry]: https://sentry.io/ [`sentry`]: https://crates.io/crates/sentry [Unified API]: https://develop.sentry.dev/sdk/unified-api/ -[`test`]: https://docs.rs/sentry-core/0.32.3/sentry_core/test/index.html +[`test`]: https://docs.rs/sentry-core/0.33.0/sentry_core/test/index.html ## Resources diff --git a/sentry-debug-images/Cargo.toml b/sentry-debug-images/Cargo.toml index 906e90663..c10e59a5a 100644 --- a/sentry-debug-images/Cargo.toml +++ b/sentry-debug-images/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-debug-images" -version = "0.32.3" +version = "0.33.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -15,4 +15,4 @@ rust-version = "1.73" [dependencies] findshlibs = "=0.10.2" once_cell = "1" -sentry-core = { version = "0.32.3", path = "../sentry-core" } +sentry-core = { version = "0.33.0", path = "../sentry-core" } diff --git a/sentry-debug-images/README.md b/sentry-debug-images/README.md index d3d614d6e..7c8b48099 100644 --- a/sentry-debug-images/README.md +++ b/sentry-debug-images/README.md @@ -22,7 +22,7 @@ let integration = sentry_debug_images::DebugImagesIntegration::new() .filter(|event| event.level >= Level::Warning); ``` -[`Event`]: https://docs.rs/sentry-debug-images/0.32.3/sentry_debug_images/sentry_core::protocol::Event +[`Event`]: https://docs.rs/sentry-debug-images/0.33.0/sentry_debug_images/sentry_core::protocol::Event ## Resources diff --git a/sentry-log/Cargo.toml b/sentry-log/Cargo.toml index 73c318510..14960eb7c 100644 --- a/sentry-log/Cargo.toml +++ b/sentry-log/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-log" -version = "0.32.3" +version = "0.33.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.73" [dependencies] -sentry-core = { version = "0.32.3", path = "../sentry-core" } +sentry-core = { version = "0.33.0", path = "../sentry-core" } log = { version = "0.4.8", features = ["std"] } [dev-dependencies] diff --git a/sentry-panic/Cargo.toml b/sentry-panic/Cargo.toml index f5b7de00a..60f19f96f 100644 --- a/sentry-panic/Cargo.toml +++ b/sentry-panic/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-panic" -version = "0.32.3" +version = "0.33.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -13,8 +13,8 @@ edition = "2021" rust-version = "1.73" [dependencies] -sentry-core = { version = "0.32.3", path = "../sentry-core" } -sentry-backtrace = { version = "0.32.3", path = "../sentry-backtrace" } +sentry-core = { version = "0.33.0", path = "../sentry-core" } +sentry-backtrace = { version = "0.33.0", path = "../sentry-backtrace" } [dev-dependencies] sentry = { path = "../sentry", default-features = false, features = ["test"] } diff --git a/sentry-slog/Cargo.toml b/sentry-slog/Cargo.toml index e58c42bc3..06c06b28a 100644 --- a/sentry-slog/Cargo.toml +++ b/sentry-slog/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-slog" -version = "0.32.3" +version = "0.33.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.73" [dependencies] -sentry-core = { version = "0.32.3", path = "../sentry-core" } +sentry-core = { version = "0.33.0", path = "../sentry-core" } slog = { version = "2.5.2", features = ["nested-values"] } serde_json = "1.0.46" diff --git a/sentry-tower/Cargo.toml b/sentry-tower/Cargo.toml index 8a1767230..93ae734d1 100644 --- a/sentry-tower/Cargo.toml +++ b/sentry-tower/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tower" -version = "0.32.3" +version = "0.33.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -25,7 +25,7 @@ tower-layer = "0.3" tower-service = "0.3" http = { version = "1.0.0", optional = true } pin-project = { version = "1.0.10", optional = true } -sentry-core = { version = "0.32.3", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.33.0", path = "../sentry-core", default-features = false, features = [ "client", ] } url = { version = "2.2.2", optional = true } diff --git a/sentry-tower/README.md b/sentry-tower/README.md index 14861034b..e314311d0 100644 --- a/sentry-tower/README.md +++ b/sentry-tower/README.md @@ -103,7 +103,7 @@ feature of the `sentry` crate instead of the `tower` feature. The created transaction will automatically use the request URI as its name. This is sometimes not desirable in case the request URI contains unique IDs or similar. In this case, users should manually override the transaction name -in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.32.3/sentry_tower/sentry_core::Scope::set_transaction) +in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.33.0/sentry_tower/sentry_core::Scope::set_transaction) method. When combining both layers, take care of the ordering of both. For example diff --git a/sentry-tracing/Cargo.toml b/sentry-tracing/Cargo.toml index 0f8914d85..5775805df 100644 --- a/sentry-tracing/Cargo.toml +++ b/sentry-tracing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tracing" -version = "0.32.3" +version = "0.33.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -20,14 +20,14 @@ default = [] backtrace = ["dep:sentry-backtrace"] [dependencies] -sentry-core = { version = "0.32.3", path = "../sentry-core", features = [ +sentry-core = { version = "0.33.0", path = "../sentry-core", features = [ "client", ] } tracing-core = "0.1" tracing-subscriber = { version = "0.3.1", default-features = false, features = [ "std", ] } -sentry-backtrace = { version = "0.32.3", path = "../sentry-backtrace", optional = true } +sentry-backtrace = { version = "0.33.0", path = "../sentry-backtrace", optional = true } [dev-dependencies] log = "0.4" diff --git a/sentry-tracing/README.md b/sentry-tracing/README.md index 78384cae0..a2376344d 100644 --- a/sentry-tracing/README.md +++ b/sentry-tracing/README.md @@ -83,7 +83,7 @@ tracing::error!( ); ``` -To track [error structs](https://docs.rs/sentry-tracing/0.32.3/sentry_tracing/std::error::Error), assign a reference to error trait object as field +To track [error structs](https://docs.rs/sentry-tracing/0.33.0/sentry_tracing/std::error::Error), assign a reference to error trait object as field in one of the logging macros. By convention, it is recommended to use the `ERROR` level and assign it to a field called `error`, although the integration will also work with all other levels and field names. diff --git a/sentry-types/Cargo.toml b/sentry-types/Cargo.toml index 2fcd3538f..949527622 100644 --- a/sentry-types/Cargo.toml +++ b/sentry-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-types" -version = "0.32.3" +version = "0.33.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index 8958d20bc..206751751 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry" -version = "0.32.3" +version = "0.33.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -53,18 +53,18 @@ rustls = ["dep:rustls", "reqwest?/rustls-tls", "ureq?/tls", "webpki-roots"] embedded-svc-http = ["dep:embedded-svc", "dep:esp-idf-svc"] [dependencies] -sentry-core = { version = "0.32.3", path = "../sentry-core", features = [ +sentry-core = { version = "0.33.0", path = "../sentry-core", features = [ "client", ] } -sentry-anyhow = { version = "0.32.3", path = "../sentry-anyhow", optional = true } -sentry-backtrace = { version = "0.32.3", path = "../sentry-backtrace", optional = true } -sentry-contexts = { version = "0.32.3", path = "../sentry-contexts", optional = true } -sentry-debug-images = { version = "0.32.3", path = "../sentry-debug-images", optional = true } -sentry-log = { version = "0.32.3", path = "../sentry-log", optional = true } -sentry-panic = { version = "0.32.3", path = "../sentry-panic", optional = true } -sentry-slog = { version = "0.32.3", path = "../sentry-slog", optional = true } -sentry-tower = { version = "0.32.3", path = "../sentry-tower", optional = true } -sentry-tracing = { version = "0.32.3", path = "../sentry-tracing", optional = true } +sentry-anyhow = { version = "0.33.0", path = "../sentry-anyhow", optional = true } +sentry-backtrace = { version = "0.33.0", path = "../sentry-backtrace", optional = true } +sentry-contexts = { version = "0.33.0", path = "../sentry-contexts", optional = true } +sentry-debug-images = { version = "0.33.0", path = "../sentry-debug-images", optional = true } +sentry-log = { version = "0.33.0", path = "../sentry-log", optional = true } +sentry-panic = { version = "0.33.0", path = "../sentry-panic", optional = true } +sentry-slog = { version = "0.33.0", path = "../sentry-slog", optional = true } +sentry-tower = { version = "0.33.0", path = "../sentry-tower", optional = true } +sentry-tracing = { version = "0.33.0", path = "../sentry-tracing", optional = true } log = { version = "0.4.8", optional = true, features = ["std"] } reqwest = { version = "0.12", optional = true, features = [ "blocking", diff --git a/sentry/README.md b/sentry/README.md index e3c54b796..5b5d16a50 100644 --- a/sentry/README.md +++ b/sentry/README.md @@ -34,8 +34,8 @@ sentry::capture_message("Hello World!", sentry::Level::Info); More complex examples on how to use sentry can also be found in [examples]. Extended instructions may also be found on [Sentry itself]. -[`sentry::init`]: https://docs.rs/sentry/0.32.3/sentry/fn.init.html -[`Hub`]: https://docs.rs/sentry/0.32.3/sentry/struct.Hub.html +[`sentry::init`]: https://docs.rs/sentry/0.33.0/sentry/fn.init.html +[`Hub`]: https://docs.rs/sentry/0.33.0/sentry/struct.Hub.html [examples]: https://github.com/getsentry/sentry-rust/tree/master/sentry/examples [Sentry itself]: https://docs.sentry.io/platforms/rust @@ -47,8 +47,8 @@ the ecosystem require a feature flag. For available integrations and how to use [integrations] and [apply_defaults]. [Features]: #features -[integrations]: https://docs.rs/sentry/0.32.3/sentry/integrations/index.html -[apply_defaults]: https://docs.rs/sentry/0.32.3/sentry/fn.apply_defaults.html +[integrations]: https://docs.rs/sentry/0.33.0/sentry/integrations/index.html +[apply_defaults]: https://docs.rs/sentry/0.33.0/sentry/fn.apply_defaults.html ## Minimal API @@ -56,8 +56,8 @@ This crate comes fully-featured. If the goal is to instrument libraries for usag with sentry, or to extend sentry with a custom [`Integration`] or a [`Transport`], one should use the [`sentry-core`] crate instead. -[`Integration`]: https://docs.rs/sentry/0.32.3/sentry/trait.Integration.html -[`Transport`]: https://docs.rs/sentry/0.32.3/sentry/trait.Transport.html +[`Integration`]: https://docs.rs/sentry/0.33.0/sentry/trait.Integration.html +[`Transport`]: https://docs.rs/sentry/0.33.0/sentry/trait.Transport.html [`sentry-core`]: https://crates.io/crates/sentry-core ## Features From 7492d24d72e30ffedb60d64d45681f402f177963 Mon Sep 17 00:00:00 2001 From: Dylan Anthony <43723790+dbanty@users.noreply.github.com> Date: Tue, 28 May 2024 01:22:07 -0600 Subject: [PATCH 007/148] Make regex an optional dependency (#659) Co-authored-by: Dylan Anthony --- Cargo.lock | 26 +++++++++++++------------- sentry-core/Cargo.toml | 4 ++-- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 03d647348..dd7046bbb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3718,7 +3718,7 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "sentry" -version = "0.32.3" +version = "0.33.0" dependencies = [ "actix-web", "anyhow", @@ -3756,7 +3756,7 @@ dependencies = [ [[package]] name = "sentry-actix" -version = "0.32.3" +version = "0.33.0" dependencies = [ "actix-web", "futures", @@ -3768,7 +3768,7 @@ dependencies = [ [[package]] name = "sentry-anyhow" -version = "0.32.3" +version = "0.33.0" dependencies = [ "anyhow", "sentry", @@ -3778,7 +3778,7 @@ dependencies = [ [[package]] name = "sentry-backtrace" -version = "0.32.3" +version = "0.33.0" dependencies = [ "backtrace", "once_cell", @@ -3788,7 +3788,7 @@ dependencies = [ [[package]] name = "sentry-contexts" -version = "0.32.3" +version = "0.33.0" dependencies = [ "hostname", "libc", @@ -3801,7 +3801,7 @@ dependencies = [ [[package]] name = "sentry-core" -version = "0.32.3" +version = "0.33.0" dependencies = [ "anyhow", "cadence", @@ -3825,7 +3825,7 @@ dependencies = [ [[package]] name = "sentry-debug-images" -version = "0.32.3" +version = "0.33.0" dependencies = [ "findshlibs", "once_cell", @@ -3834,7 +3834,7 @@ dependencies = [ [[package]] name = "sentry-log" -version = "0.32.3" +version = "0.33.0" dependencies = [ "log", "pretty_env_logger", @@ -3844,7 +3844,7 @@ dependencies = [ [[package]] name = "sentry-panic" -version = "0.32.3" +version = "0.33.0" dependencies = [ "sentry", "sentry-backtrace", @@ -3853,7 +3853,7 @@ dependencies = [ [[package]] name = "sentry-slog" -version = "0.32.3" +version = "0.33.0" dependencies = [ "erased-serde", "sentry", @@ -3865,7 +3865,7 @@ dependencies = [ [[package]] name = "sentry-tower" -version = "0.32.3" +version = "0.33.0" dependencies = [ "anyhow", "axum 0.7.1", @@ -3885,7 +3885,7 @@ dependencies = [ [[package]] name = "sentry-tracing" -version = "0.32.3" +version = "0.33.0" dependencies = [ "log", "sentry", @@ -3899,7 +3899,7 @@ dependencies = [ [[package]] name = "sentry-types" -version = "0.32.3" +version = "0.33.0" dependencies = [ "debugid", "hex", diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index 35faa89d6..758e5f762 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -26,7 +26,7 @@ client = ["rand"] # and macros actually expand features (and extern crate) where they are used! debug-logs = ["dep:log"] test = ["client"] -UNSTABLE_metrics = ["sentry-types/UNSTABLE_metrics"] +UNSTABLE_metrics = ["sentry-types/UNSTABLE_metrics", "regex"] UNSTABLE_cadence = ["dep:cadence", "UNSTABLE_metrics"] [dependencies] @@ -36,7 +36,7 @@ itertools = "0.13.0" log = { version = "0.4.8", optional = true, features = ["std"] } once_cell = "1" rand = { version = "0.8.1", optional = true } -regex = "1.7.3" +regex = { version = "1.7.3" , optional = true} sentry-types = { version = "0.33.0", path = "../sentry-types" } serde = { version = "1.0.104", features = ["derive"] } serde_json = { version = "1.0.46" } From 7ae972e42ea77a3d61915d98792561c2eb34dfa3 Mon Sep 17 00:00:00 2001 From: Arpad Borsos Date: Fri, 31 May 2024 10:02:37 +0200 Subject: [PATCH 008/148] Stabilize the `metrics` feature (#660) Removes the `UNSTABLE_` prefix from the feature flag. Also runs a `cargo update` and updates some dependencies for good measure. --- CHANGELOG.md | 6 + Cargo.lock | 977 +++++++++--------- sentry-core/Cargo.toml | 11 +- sentry-core/src/cadence.rs | 2 +- sentry-core/src/client.rs | 18 +- sentry-core/src/lib.rs | 6 +- .../metrics/normalization/normalized_tags.rs | 22 +- sentry-types/Cargo.toml | 4 +- sentry-types/src/protocol/envelope.rs | 10 +- sentry/Cargo.toml | 9 +- sentry/src/transports/ratelimit.rs | 2 +- sentry/src/transports/ureq.rs | 74 +- 12 files changed, 588 insertions(+), 553 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7adcb234a..27e506d8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +**Features**: + +- Renamed the `UNSTABLE_metrics` and `UNSTABLE_cadence` feature flags to `metrics` and `metrics-cadence1` respectively. + ## 0.33.0 ### Various fixes & improvements diff --git a/Cargo.lock b/Cargo.lock index dd7046bbb..d24421f70 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,11 +4,11 @@ version = 3 [[package]] name = "actix-codec" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "617a8268e3537fe1d8c9ead925fca49ef6400927ee7bc26750e90ecee14ce4b8" +checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.5.0", "bytes 1.6.0", "futures-core", "futures-sink", @@ -21,16 +21,16 @@ dependencies = [ [[package]] name = "actix-http" -version = "3.4.0" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92ef85799cba03f76e4f7c10f533e66d87c9a7e7055f3391f09000ad8351bc9" +checksum = "4eb9843d84c775696c37d9a418bbb01b932629d01870722c0f13eb3f95e2536d" dependencies = [ "actix-codec", "actix-rt", "actix-service", "actix-utils", "ahash", - "base64 0.21.7", + "base64 0.22.1", "bitflags 2.5.0", "brotli", "bytes 1.6.0", @@ -65,18 +65,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote", - "syn 2.0.58", + "syn 2.0.66", ] [[package]] name = "actix-router" -version = "0.5.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66ff4d247d2b160861fa2866457e85706833527840e4133f8f49aa423a38799" +checksum = "13d324164c51f63867b57e73ba5936ea151b8a41a1d23d1031eeb9f70d0236f8" dependencies = [ "bytestring", + "cfg-if", "http 0.2.12", "regex", + "regex-lite", "serde", "tracing", ] @@ -103,7 +105,7 @@ dependencies = [ "futures-core", "futures-util", "mio", - "socket2 0.5.6", + "socket2 0.5.7", "tokio", "tracing", ] @@ -131,9 +133,9 @@ dependencies = [ [[package]] name = "actix-web" -version = "4.4.0" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4a5b5e29603ca8c94a77c65cf874718ceb60292c5a5c3e5f4ace041af462b9" +checksum = "b1cf67dadb19d7c95e5a299e2dda24193b89d5d4f33a3b9800888ede9e19aa32" dependencies = [ "actix-codec", "actix-http", @@ -160,12 +162,13 @@ dependencies = [ "once_cell", "pin-project-lite", "regex", + "regex-lite", "serde", "serde_json", "serde_urlencoded", "smallvec", - "socket2 0.5.6", - "time 0.3.30", + "socket2 0.5.7", + "time 0.3.36", "url", ] @@ -178,14 +181,14 @@ dependencies = [ "actix-router", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.66", ] [[package]] name = "addr2line" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ "gimli", ] @@ -252,12 +255,12 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.6" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", - "getrandom 0.2.13", + "getrandom 0.2.15", "once_cell", "version_check", "zerocopy", @@ -265,9 +268,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -319,15 +322,15 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anyhow" -version = "1.0.81" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" dependencies = [ "backtrace", ] @@ -360,53 +363,51 @@ dependencies = [ [[package]] name = "async-channel" -version = "2.1.1" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ca33f4bc4ed1babef42cad36cc1f51fa88be00420404e5b1e80ab1b18f7678c" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" dependencies = [ "concurrent-queue", - "event-listener 4.0.0", - "event-listener-strategy", + "event-listener-strategy 0.5.2", "futures-core", "pin-project-lite", ] [[package]] name = "async-dup" -version = "1.2.2" +version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7427a12b8dc09291528cfb1da2447059adb4a257388c2acd6497a79d55cf6f7c" +checksum = "7c2886ab563af5038f79ec016dd7b87947ed138b794e8dd64992962c9cca0411" dependencies = [ + "async-lock 3.3.0", "futures-io", - "simple-mutex", ] [[package]] name = "async-executor" -version = "1.8.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c" +checksum = "c8828ec6e544c02b0d6691d21ed9f9218d0384a82542855073c2a3f58304aaf0" dependencies = [ - "async-lock 3.1.2", "async-task", "concurrent-queue", - "fastrand 2.0.2", - "futures-lite 2.0.1", + "fastrand 2.1.0", + "futures-lite 2.3.0", "slab", ] [[package]] name = "async-global-executor" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4353121d5644cdf2beb5726ab752e79a8db1ebb52031770ec47db31d245526" +checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" dependencies = [ - "async-channel 2.1.1", + "async-channel 2.3.1", "async-executor", - "async-io 2.2.1", - "async-lock 3.1.2", + "async-io 2.3.2", + "async-lock 3.3.0", "blocking", - "futures-lite 2.0.1", + "futures-lite 2.3.0", "once_cell", ] @@ -449,18 +450,18 @@ dependencies = [ [[package]] name = "async-io" -version = "2.2.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6d3b15875ba253d1110c740755e246537483f152fa334f91abd7fe84c88b3ff" +checksum = "dcccb0f599cfa2f8ace422d3555572f47424da5648a4382a9dd0310ff8210884" dependencies = [ - "async-lock 3.1.2", + "async-lock 3.3.0", "cfg-if", "concurrent-queue", "futures-io", - "futures-lite 2.0.1", + "futures-lite 2.3.0", "parking", - "polling 3.3.1", - "rustix 0.38.32", + "polling 3.7.0", + "rustix 0.38.34", "slab", "tracing", "windows-sys 0.52.0", @@ -477,12 +478,12 @@ dependencies = [ [[package]] name = "async-lock" -version = "3.1.2" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dea8b3453dd7cc96711834b75400d671b73e3656975fa68d9f277163b7f7e316" +checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" dependencies = [ - "event-listener 4.0.0", - "event-listener-strategy", + "event-listener 4.0.3", + "event-listener-strategy 0.4.0", "pin-project-lite", ] @@ -543,24 +544,24 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.66", ] [[package]] name = "async-task" -version = "4.5.0" +version = "4.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4eb2cdb97421e01129ccb49169d8279ed21e829929144f4a22a6e54ac549ca1" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.79" +version = "0.1.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.66", ] [[package]] @@ -571,9 +572,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "axum" @@ -597,7 +598,7 @@ dependencies = [ "pin-project-lite", "rustversion", "serde", - "sync_wrapper", + "sync_wrapper 0.1.2", "tower", "tower-layer", "tower-service", @@ -605,15 +606,15 @@ dependencies = [ [[package]] name = "axum" -version = "0.7.1" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "810a80b128d70e6ed2bdf3fe8ed72c0ae56f5f5948d01c2753282dd92a84fce8" +checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" dependencies = [ "async-trait", - "axum-core 0.4.0", + "axum-core 0.4.3", "bytes 1.6.0", "futures-util", - "http 1.0.0", + "http 1.1.0", "http-body 1.0.0", "http-body-util", "itoa", @@ -624,7 +625,7 @@ dependencies = [ "pin-project-lite", "rustversion", "serde", - "sync_wrapper", + "sync_wrapper 1.0.1", "tower", "tower-layer", "tower-service", @@ -649,29 +650,29 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.4.0" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de0ddc355eab88f4955090a823715df47acf0b7660aab7a69ad5ce6301ee3b73" +checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" dependencies = [ "async-trait", "bytes 1.6.0", "futures-util", - "http 1.0.0", + "http 1.1.0", "http-body 1.0.0", "http-body-util", "mime", "pin-project-lite", "rustversion", - "sync_wrapper", + "sync_wrapper 0.1.2", "tower-layer", "tower-service", ] [[package]] name = "backtrace" -version = "0.3.71" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +checksum = "17c6a35df3749d2e8bb1b7b21a976d82b15548788d2735b9d82f329268f71a11" dependencies = [ "addr2line", "cc", @@ -702,9 +703,9 @@ checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64" -version = "0.22.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bindgen" @@ -760,25 +761,22 @@ dependencies = [ [[package]] name = "blocking" -version = "1.5.1" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" dependencies = [ - "async-channel 2.1.1", - "async-lock 3.1.2", + "async-channel 2.3.1", "async-task", - "fastrand 2.0.2", "futures-io", - "futures-lite 2.0.1", + "futures-lite 2.3.0", "piper", - "tracing", ] [[package]] name = "brotli" -version = "3.4.0" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "516074a47ef4bce09577a3b379392300159ce5b1ba2e501ff1c819950066100f" +checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -787,9 +785,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "2.5.1" +version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" +checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -815,14 +813,14 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.66", ] [[package]] name = "bumpalo" -version = "3.15.4" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "byteorder" @@ -853,9 +851,9 @@ dependencies = [ [[package]] name = "cadence" -version = "0.29.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f39286bc075b023101dccdb79456a1334221c768b8faede0c2aff7ed29a9482d" +checksum = "2f338b979d9ebfff4bb9801ae8f3af0dc3615f7f1ca963f2e4782bcf9acb3753" dependencies = [ "crossbeam-channel", ] @@ -886,7 +884,7 @@ checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" dependencies = [ "camino", "cargo-platform", - "semver 1.0.20", + "semver 1.0.23", "serde", "serde_json", "thiserror", @@ -900,12 +898,13 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.90" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" dependencies = [ "jobserver", "libc", + "once_cell", ] [[package]] @@ -932,14 +931,14 @@ dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] name = "ciborium" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" dependencies = [ "ciborium-io", "ciborium-ll", @@ -948,15 +947,15 @@ dependencies = [ [[package]] name = "ciborium-io" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" [[package]] name = "ciborium-ll" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" dependencies = [ "ciborium-io", "half", @@ -973,9 +972,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" dependencies = [ "glob", "libc", @@ -984,18 +983,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.10" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fffed7514f420abec6d183b1d3acfd9099c79c3a10a06ade4f8203f1411272" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.4.9" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63361bae7eef3771745f02d8d892bec2fee5f6e34af316ba556e7f97a7069ff1" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" dependencies = [ "anstyle", "clap_lex", @@ -1003,9 +1002,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "cmake" @@ -1018,9 +1017,9 @@ dependencies = [ [[package]] name = "concurrent-queue" -version = "2.3.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f057a694a54f12365049b0958a1685bb52d567f5593b355fbf685838e873d400" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" dependencies = [ "crossbeam-utils", ] @@ -1038,9 +1037,9 @@ dependencies = [ [[package]] name = "const_fn" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbdcdcb6d86f71c5e97409ad45898af11cbc995b4ee8112d59095a28d376c935" +checksum = "373e9fafaa20882876db20562275ff58d50e0caa2590077fe7ce7bef90211d0d" [[package]] name = "const_format" @@ -1092,7 +1091,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" dependencies = [ "percent-encoding", - "time 0.3.30", + "time 0.3.36", "version_check", ] @@ -1114,9 +1113,9 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "cpufeatures" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] @@ -1180,56 +1179,52 @@ checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" [[package]] name = "crossbeam-channel" -version = "0.5.8" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.15" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if", "crossbeam-utils", - "memoffset", - "scopeguard", ] [[package]] name = "crossbeam-queue" -version = "0.3.8" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.16" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" -dependencies = [ - "cfg-if", -] +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-common" @@ -1262,24 +1257,24 @@ dependencies = [ [[package]] name = "curl" -version = "0.4.44" +version = "0.4.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22" +checksum = "1e2161dd6eba090ff1594084e95fd67aeccf04382ffea77999ea94ed42ec67b6" dependencies = [ "curl-sys", "libc", "openssl-probe", "openssl-sys", "schannel", - "socket2 0.4.10", - "winapi", + "socket2 0.5.7", + "windows-sys 0.52.0", ] [[package]] name = "curl-sys" -version = "0.4.68+curl-8.4.0" +version = "0.4.72+curl-8.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4a0d18d88360e374b16b2273c832b5e57258ffc1d4aa4f96b108e0738d5752f" +checksum = "29cbdc8314c447d11e8fd156dcdd031d9e02a7a976163e396b548c03153bc9ea" dependencies = [ "cc", "libc", @@ -1288,7 +1283,7 @@ dependencies = [ "openssl-sys", "pkg-config", "vcpkg", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1320,7 +1315,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.66", ] [[package]] @@ -1331,7 +1326,7 @@ checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" dependencies = [ "darling_core", "quote", - "syn 2.0.58", + "syn 2.0.66", ] [[package]] @@ -1341,7 +1336,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "lock_api", "once_cell", "parking_lot_core", @@ -1391,7 +1386,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.66", ] [[package]] @@ -1405,9 +1400,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.9" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", ] @@ -1452,9 +1447,9 @@ checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" [[package]] name = "either" -version = "1.10.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" [[package]] name = "embassy-futures" @@ -1579,9 +1574,9 @@ dependencies = [ [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] @@ -1605,14 +1600,14 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.66", ] [[package]] name = "env_logger" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" dependencies = [ "humantime", "is-terminal", @@ -1647,9 +1642,9 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -1725,9 +1720,20 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "event-listener" -version = "4.0.0" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "770d968249b5d99410d61f5bf89057f3199a077a04d087092f58e7d10692baae" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" dependencies = [ "concurrent-queue", "parking", @@ -1740,7 +1746,17 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" dependencies = [ - "event-listener 4.0.0", + "event-listener 4.0.3", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" +dependencies = [ + "event-listener 5.3.1", "pin-project-lite", ] @@ -1755,9 +1771,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "filetime" @@ -1767,7 +1783,7 @@ checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.4.1", "windows-sys 0.52.0", ] @@ -1785,9 +1801,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.28" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" dependencies = [ "crc32fast", "miniz_oxide", @@ -1850,9 +1866,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", @@ -1881,9 +1897,9 @@ checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -1913,14 +1929,13 @@ dependencies = [ [[package]] name = "futures-lite" -version = "2.0.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3831c2651acb5177cbd83943f3d9c8912c5ad03c76afcc0e9511ba568ec5ebb" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" dependencies = [ - "fastrand 2.0.2", + "fastrand 2.1.0", "futures-core", "futures-io", - "memchr", "parking", "pin-project-lite", ] @@ -1933,7 +1948,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.66", ] [[package]] @@ -1950,9 +1965,9 @@ checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-timer" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" [[package]] name = "futures-util" @@ -1995,9 +2010,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.13" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06fddc2749e0528d2813f95e050e87e52c8cbbae56223b9babf73b3e53b0cc6" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -2016,9 +2031,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "glob" @@ -2083,9 +2098,13 @@ dependencies = [ [[package]] name = "half" -version = "1.8.2" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] [[package]] name = "hash32" @@ -2104,9 +2123,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "heapless" @@ -2190,9 +2209,9 @@ dependencies = [ [[package]] name = "http" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes 1.6.0", "fnv", @@ -2217,18 +2236,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" dependencies = [ "bytes 1.6.0", - "http 1.0.0", + "http 1.1.0", ] [[package]] name = "http-body-util" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cb79eb393015dadd30fc252023adb0b2400a0caee0fa2a077e6e21a551e840" +checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" dependencies = [ "bytes 1.6.0", - "futures-util", - "http 1.0.0", + "futures-core", + "http 1.1.0", "http-body 1.0.0", "pin-project-lite", ] @@ -2309,7 +2328,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.6", + "socket2 0.5.7", "tokio", "tower-service", "tracing", @@ -2318,14 +2337,14 @@ dependencies = [ [[package]] name = "hyper" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a" +checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" dependencies = [ "bytes 1.6.0", "futures-channel", "futures-util", - "http 1.0.0", + "http 1.1.0", "http-body 1.0.0", "httparse", "itoa", @@ -2342,10 +2361,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" dependencies = [ "futures-util", - "http 1.0.0", - "hyper 1.2.0", + "http 1.1.0", + "hyper 1.3.1", "hyper-util", - "rustls 0.22.3", + "rustls", "rustls-pki-types", "tokio", "tokio-rustls", @@ -2372,7 +2391,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes 1.6.0", "http-body-util", - "hyper 1.2.0", + "hyper 1.3.1", "hyper-util", "native-tls", "tokio", @@ -2382,18 +2401,18 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +checksum = "7b875924a60b96e5d7b9ae7b066540b1dd1cbd90d1828f54c92e02a283351c56" dependencies = [ "bytes 1.6.0", "futures-channel", "futures-util", - "http 1.0.0", + "http 1.1.0", "http-body 1.0.0", - "hyper 1.2.0", + "hyper 1.3.1", "pin-project-lite", - "socket2 0.5.6", + "socket2 0.5.7", "tokio", "tower", "tower-service", @@ -2472,7 +2491,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown 0.14.5", ] [[package]] @@ -2483,9 +2502,9 @@ checksum = "64e9829a50b42bb782c1df523f78d332fe371b10c661e78b7a3c34b0198e9fac" [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", ] @@ -2509,13 +2528,13 @@ checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "is-terminal" -version = "0.4.9" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ "hermit-abi", - "rustix 0.38.32", - "windows-sys 0.48.0", + "libc", + "windows-sys 0.52.0", ] [[package]] @@ -2554,9 +2573,9 @@ dependencies = [ [[package]] name = "itertools" -version = "0.13.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" dependencies = [ "either", ] @@ -2569,9 +2588,9 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.28" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" dependencies = [ "libc", ] @@ -2627,9 +2646,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.153" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libloading" @@ -2638,14 +2657,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" dependencies = [ "cfg-if", - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] name = "libnghttp2-sys" -version = "0.1.8+1.55.1" +version = "0.1.10+1.61.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fae956c192dadcdb5dace96db71fa0b827333cce7c7b38dc71446f024d8a340" +checksum = "959c25552127d2e1fa72f0e52548ec04fc386e827ba71a7bd01db46a447dc135" dependencies = [ "cc", "libc", @@ -2653,9 +2672,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.12" +version = "1.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" +checksum = "c15da26e5af7e25c90b37a2d75cdbf940cf4a55316de9d84c679c9b8bfabf82e" dependencies = [ "cc", "libc", @@ -2671,9 +2690,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "local-channel" @@ -2694,9 +2713,9 @@ checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -2723,15 +2742,6 @@ version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - [[package]] name = "mime" version = "0.3.17" @@ -2756,9 +2766,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" dependencies = [ "adler", ] @@ -2777,11 +2787,10 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" dependencies = [ - "lazy_static", "libc", "log", "openssl", @@ -2868,11 +2877,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -2905,14 +2920,14 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.66", ] [[package]] name = "object" -version = "0.32.2" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "b8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5e" dependencies = [ "memchr", ] @@ -2931,9 +2946,9 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "opaque-debug" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" @@ -2958,7 +2973,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.66", ] [[package]] @@ -2981,13 +2996,13 @@ dependencies = [ [[package]] name = "os_info" -version = "3.7.0" +version = "3.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "006e42d5b888366f1880eda20371fedde764ed2213dc8496f49622fa0c99cd5e" +checksum = "ae99c7fa6dd38c7cafe1ec085e804f8f555a2f8659b0dbe03f1f9963a9b51092" dependencies = [ "log", "serde", - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -3004,9 +3019,9 @@ checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -3014,22 +3029,22 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.1", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.5", ] [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "peeking_take_while" @@ -3060,7 +3075,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.66", ] [[package]] @@ -3077,12 +3092,12 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "piper" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" +checksum = "464db0c665917b13ebb5d453ccdec4add5658ee1adc7affc7677615356a8afaf" dependencies = [ "atomic-waker", - "fastrand 2.0.2", + "fastrand 2.1.0", "futures-io", ] @@ -3094,9 +3109,9 @@ checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "plotters" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" +checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" dependencies = [ "num-traits", "plotters-backend", @@ -3107,15 +3122,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" +checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" [[package]] name = "plotters-svg" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" +checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" dependencies = [ "plotters-backend", ] @@ -3138,14 +3153,15 @@ dependencies = [ [[package]] name = "polling" -version = "3.3.1" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf63fa624ab313c11656b4cda960bfc46c410187ad493c41f6ba2d8c1e991c9e" +checksum = "645493cf344456ef24219d02a768cf1fb92ddf8c92161679ae3d91b91a637be3" dependencies = [ "cfg-if", "concurrent-queue", + "hermit-abi", "pin-project-lite", - "rustix 0.38.32", + "rustix 0.38.34", "tracing", "windows-sys 0.52.0", ] @@ -3224,18 +3240,18 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6" dependencies = [ "unicode-ident", ] [[package]] name = "prost" -version = "0.12.4" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0f5d036824e4761737860779c906171497f6d55681139d8312388f8fe398922" +checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" dependencies = [ "bytes 1.6.0", "prost-derive", @@ -3243,22 +3259,22 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.12.4" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19de2de2a00075bf566bee3bd4db014b11587e84184d3f7a791bc17f1a8e9e48" +checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" dependencies = [ "anyhow", - "itertools 0.10.5", + "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.66", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -3322,7 +3338,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.13", + "getrandom 0.2.15", ] [[package]] @@ -3336,9 +3352,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -3346,9 +3362,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -3363,11 +3379,20 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +dependencies = [ + "bitflags 2.5.0", +] + [[package]] name = "regex" -version = "1.10.2" +version = "1.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", @@ -3377,26 +3402,32 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", "regex-syntax", ] +[[package]] +name = "regex-lite" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b661b2f27137bdbc16f00eda72866a92bb28af1753ffbd56744fb6e2e9cd8e" + [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "relative-path" -version = "1.9.0" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c707298afce11da2efef2f600116fa93ffa7a032b5d7b628aa17711ec81383ca" +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" [[package]] name = "remove_dir_all" @@ -3416,19 +3447,19 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e6cc1e89e689536eb5aeede61520e874df5a4707df811cd5da4aa5fbb2aae19" +checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" dependencies = [ - "base64 0.22.0", + "base64 0.22.1", "bytes 1.6.0", "futures-channel", "futures-core", "futures-util", - "http 1.0.0", + "http 1.1.0", "http-body 1.0.0", "http-body-util", - "hyper 1.2.0", + "hyper 1.3.1", "hyper-rustls", "hyper-tls", "hyper-util", @@ -3440,13 +3471,13 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.22.3", + "rustls", "rustls-pemfile", "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", - "sync_wrapper", + "sync_wrapper 0.1.2", "tokio", "tokio-native-tls", "tokio-rustls", @@ -3455,7 +3486,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots 0.26.1", + "webpki-roots", "winreg", ] @@ -3467,7 +3498,7 @@ checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.13", + "getrandom 0.2.15", "libc", "spin", "untrusted", @@ -3476,9 +3507,9 @@ dependencies = [ [[package]] name = "rstest" -version = "0.18.2" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97eeab2f3c0a199bc4be135c36c924b6590b88c377d416494288c14f2db30199" +checksum = "9d5316d2a1479eeef1ea21e7f9ddc67c191d497abc8fc3ba2467857abbb68330" dependencies = [ "futures", "futures-timer", @@ -3488,9 +3519,9 @@ dependencies = [ [[package]] name = "rstest_macros" -version = "0.18.2" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d428f8247852f894ee1be110b375111b586d4fa431f6c46e64ba5a0dcccbe605" +checksum = "04a9df72cc1f67020b0d63ad9bfe4a323e459ea7eb68e03bd9824db49f9a4c25" dependencies = [ "cfg-if", "glob", @@ -3499,15 +3530,15 @@ dependencies = [ "regex", "relative-path", "rustc_version 0.4.0", - "syn 2.0.58", + "syn 2.0.66", "unicode-ident", ] [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" @@ -3530,7 +3561,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.20", + "semver 1.0.23", ] [[package]] @@ -3549,74 +3580,52 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.32" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ "bitflags 2.5.0", "errno", "libc", - "linux-raw-sys 0.4.13", + "linux-raw-sys 0.4.14", "windows-sys 0.52.0", ] [[package]] name = "rustls" -version = "0.21.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" -dependencies = [ - "log", - "ring", - "rustls-webpki 0.101.7", - "sct", -] - -[[package]] -name = "rustls" -version = "0.22.3" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99008d7ad0bbbea527ec27bddbc0e432c5b87d8175178cee68d2eec9c4a1813c" +checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" dependencies = [ "log", "ring", "rustls-pki-types", - "rustls-webpki 0.102.2", + "rustls-webpki", "subtle", "zeroize", ] [[package]] name = "rustls-pemfile" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f48172685e6ff52a556baa527774f61fcaa884f59daf3375c62a3f1cd2549dab" +checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "rustls-pki-types", ] [[package]] name = "rustls-pki-types" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd36cc4259e3e4514335c4a138c6b43171a8d61d8f5c9348f9fc7529416f247" - -[[package]] -name = "rustls-webpki" -version = "0.101.7" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" -dependencies = [ - "ring", - "untrusted", -] +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" [[package]] name = "rustls-webpki" -version = "0.102.2" +version = "0.102.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" +checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" dependencies = [ "ring", "rustls-pki-types", @@ -3625,15 +3634,15 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" @@ -3659,23 +3668,13 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "security-framework" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" +checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.5.0", "core-foundation", "core-foundation-sys", "libc", @@ -3684,9 +3683,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef" +checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" dependencies = [ "core-foundation-sys", "libc", @@ -3703,9 +3702,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.20" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" dependencies = [ "serde", ] @@ -3732,7 +3731,7 @@ dependencies = [ "native-tls", "pretty_env_logger", "reqwest", - "rustls 0.21.10", + "rustls", "sentry-anyhow", "sentry-backtrace", "sentry-contexts", @@ -3751,7 +3750,7 @@ dependencies = [ "tracing", "tracing-subscriber", "ureq", - "webpki-roots 0.25.4", + "webpki-roots", ] [[package]] @@ -3808,7 +3807,6 @@ dependencies = [ "crc32fast", "criterion", "futures", - "itertools 0.13.0", "log", "once_cell", "rand 0.8.5", @@ -3868,8 +3866,8 @@ name = "sentry-tower" version = "0.33.0" dependencies = [ "anyhow", - "axum 0.7.1", - "http 1.0.0", + "axum 0.7.5", + "http 1.1.0", "pin-project", "prost", "sentry", @@ -3908,36 +3906,36 @@ dependencies = [ "serde", "serde_json", "thiserror", - "time 0.3.30", + "time 0.3.36", "url", "uuid", ] [[package]] name = "serde" -version = "1.0.197" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.66", ] [[package]] name = "serde_json" -version = "1.0.115" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ "itoa", "ryu", @@ -4023,22 +4021,13 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] -[[package]] -name = "simple-mutex" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38aabbeafa6f6dead8cebf246fe9fae1f9215c8d29b3a69f93bd62a9e4a3dcd6" -dependencies = [ - "event-listener 2.5.3", -] - [[package]] name = "slab" version = "0.4.9" @@ -4086,9 +4075,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", "windows-sys 0.52.0", @@ -4220,7 +4209,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.58", + "syn 2.0.66", ] [[package]] @@ -4240,7 +4229,7 @@ dependencies = [ "async-trait", "cfg-if", "futures-util", - "getrandom 0.2.13", + "getrandom 0.2.15", "http-client", "http-types", "log", @@ -4264,9 +4253,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.58" +version = "2.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" dependencies = [ "proc-macro2", "quote", @@ -4279,6 +4268,12 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "sync_wrapper" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" + [[package]] name = "tempfile" version = "3.10.1" @@ -4286,45 +4281,45 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", - "fastrand 2.0.2", - "rustix 0.38.32", + "fastrand 2.1.0", + "rustix 0.38.34", "windows-sys 0.52.0", ] [[package]] name = "termcolor" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] [[package]] name = "thiserror" -version = "1.0.50" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.50" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.66", ] [[package]] name = "thread_local" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ "cfg-if", "once_cell", @@ -4347,16 +4342,17 @@ dependencies = [ [[package]] name = "time" -version = "0.3.30" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", + "num-conv", "powerfmt", "serde", "time-core", - "time-macros 0.2.15", + "time-macros 0.2.18", ] [[package]] @@ -4377,10 +4373,11 @@ dependencies = [ [[package]] name = "time-macros" -version = "0.2.15" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ + "num-conv", "time-core", ] @@ -4436,7 +4433,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.6", + "socket2 0.5.7", "tokio-macros", "windows-sys 0.48.0", ] @@ -4459,7 +4456,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.66", ] [[package]] @@ -4478,7 +4475,7 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" dependencies = [ - "rustls 0.22.3", + "rustls", "rustls-pki-types", "tokio", ] @@ -4496,16 +4493,15 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes 1.6.0", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] @@ -4604,7 +4600,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.66", ] [[package]] @@ -4736,18 +4732,19 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "2.9.1" +version = "2.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cdd25c339e200129fe4de81451814e5228c9b771d57378817d6117cc2b3f97" +checksum = "d11a831e3c0b56e438a28308e7c810799e3c118417f342d30ecec080105395cd" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "log", "native-tls", "once_cell", - "rustls 0.21.10", - "rustls-webpki 0.101.7", + "rustls", + "rustls-pki-types", + "rustls-webpki", "url", - "webpki-roots 0.25.4", + "webpki-roots", ] [[package]] @@ -4764,11 +4761,11 @@ dependencies = [ [[package]] name = "uuid" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" dependencies = [ - "getrandom 0.2.13", + "getrandom 0.2.15", "serde", ] @@ -4780,9 +4777,9 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] name = "value-bag" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74797339c3b98616c009c7c3eb53a0ce41e85c8ec66bd3db96ed132d20cfdee8" +checksum = "5a84c137d37ab0142f0f2ddfe332651fdbf252e7b7dbb4e67b6c1f1b2e925101" [[package]] name = "vcpkg" @@ -4804,15 +4801,15 @@ checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" [[package]] name = "waker-fn" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" +checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" [[package]] name = "walkdir" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -4860,7 +4857,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.66", "wasm-bindgen-shared", ] @@ -4894,7 +4891,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.66", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4915,12 +4912,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webpki-roots" -version = "0.25.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" - [[package]] name = "webpki-roots" version = "0.26.1" @@ -4939,7 +4930,7 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.32", + "rustix 0.38.34", ] [[package]] @@ -4960,11 +4951,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -4980,7 +4971,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" dependencies = [ "windows-core", - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -4989,7 +4980,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -5016,7 +5007,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -5051,17 +5042,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -5078,9 +5070,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" @@ -5096,9 +5088,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" @@ -5114,9 +5106,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" @@ -5132,9 +5130,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" @@ -5150,9 +5148,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" @@ -5168,9 +5166,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" @@ -5186,9 +5184,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winnow" @@ -5211,54 +5209,53 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.31" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c4061bedbb353041c12f413700357bec76df2c7e2ca8e4df8bac24c6bf68e3d" +checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.31" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3c129550b3e6de3fd0ba67ba5c81818f9805e58b8d7fee80a3a59d2c9fc601a" +checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.66", ] [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" [[package]] name = "zstd" -version = "0.12.4" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" +checksum = "2d789b1514203a1120ad2429eae43a7bd32b90976a7bb8a05f7ec02fa88cc23a" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "6.0.6" +version = "7.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" +checksum = "1cd99b45c6bc03a018c8b8a86025678c87e55526064e38f9df301989dce7ec0a" dependencies = [ - "libc", "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.9+zstd.1.5.5" +version = "2.0.10+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" +checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" dependencies = [ "cc", "pkg-config", diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index 758e5f762..47f653359 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -26,17 +26,16 @@ client = ["rand"] # and macros actually expand features (and extern crate) where they are used! debug-logs = ["dep:log"] test = ["client"] -UNSTABLE_metrics = ["sentry-types/UNSTABLE_metrics", "regex"] -UNSTABLE_cadence = ["dep:cadence", "UNSTABLE_metrics"] +metrics = ["sentry-types/metrics", "regex", "crc32fast"] +metrics-cadence1 = ["dep:cadence", "metrics"] [dependencies] -cadence = { version = "0.29.0", optional = true } -crc32fast = "1.4.0" -itertools = "0.13.0" +cadence = { version = "1.4.0", optional = true } +crc32fast = { version = "1.4.0", optional = true } log = { version = "0.4.8", optional = true, features = ["std"] } once_cell = "1" rand = { version = "0.8.1", optional = true } -regex = { version = "1.7.3" , optional = true} +regex = { version = "1.7.3", optional = true } sentry-types = { version = "0.33.0", path = "../sentry-types" } serde = { version = "1.0.104", features = ["derive"] } serde_json = { version = "1.0.46" } diff --git a/sentry-core/src/cadence.rs b/sentry-core/src/cadence.rs index 401f53d94..0306bd7c8 100644 --- a/sentry-core/src/cadence.rs +++ b/sentry-core/src/cadence.rs @@ -6,7 +6,7 @@ //! //! # Usage //! -//! To use the `cadence` integration, enable the `UNSTABLE_cadence` feature in your `Cargo.toml`. +//! To use the `cadence` integration, enable the `metrics-cadence1` feature in your `Cargo.toml`. //! Then, create a [`SentryMetricSink`] and pass it to your `cadence` client: //! //! ``` diff --git a/sentry-core/src/client.rs b/sentry-core/src/client.rs index ed52f05b9..46d49e676 100644 --- a/sentry-core/src/client.rs +++ b/sentry-core/src/client.rs @@ -11,7 +11,7 @@ use sentry_types::protocol::v7::SessionUpdate; use sentry_types::random_uuid; use crate::constants::SDK_INFO; -#[cfg(feature = "UNSTABLE_metrics")] +#[cfg(feature = "metrics")] use crate::metrics::{self, MetricAggregator}; use crate::protocol::{ClientSdkInfo, Event}; use crate::session::SessionFlusher; @@ -47,7 +47,7 @@ pub struct Client { options: ClientOptions, transport: TransportArc, session_flusher: RwLock>, - #[cfg(feature = "UNSTABLE_metrics")] + #[cfg(feature = "metrics")] metric_aggregator: RwLock>, integrations: Vec<(TypeId, Arc)>, pub(crate) sdk_info: ClientSdkInfo, @@ -69,7 +69,7 @@ impl Clone for Client { transport.clone(), self.options.session_mode, ))); - #[cfg(feature = "UNSTABLE_metrics")] + #[cfg(feature = "metrics")] let metric_aggregator = RwLock::new(Some(MetricAggregator::new( transport.clone(), &self.options, @@ -78,7 +78,7 @@ impl Clone for Client { options: self.options.clone(), transport, session_flusher, - #[cfg(feature = "UNSTABLE_metrics")] + #[cfg(feature = "metrics")] metric_aggregator, integrations: self.integrations.clone(), sdk_info: self.sdk_info.clone(), @@ -148,7 +148,7 @@ impl Client { options.session_mode, ))); - #[cfg(feature = "UNSTABLE_metrics")] + #[cfg(feature = "metrics")] let metric_aggregator = RwLock::new(Some(MetricAggregator::new(transport.clone(), &options))); @@ -156,7 +156,7 @@ impl Client { options, transport, session_flusher, - #[cfg(feature = "UNSTABLE_metrics")] + #[cfg(feature = "metrics")] metric_aggregator, integrations, sdk_info, @@ -327,7 +327,7 @@ impl Client { } /// Captures a metric and sends it to Sentry on the next flush. - #[cfg(feature = "UNSTABLE_metrics")] + #[cfg(feature = "metrics")] pub fn add_metric(&self, metric: metrics::Metric) { if let Some(ref aggregator) = *self.metric_aggregator.read().unwrap() { aggregator.add(metric) @@ -339,7 +339,7 @@ impl Client { if let Some(ref flusher) = *self.session_flusher.read().unwrap() { flusher.flush(); } - #[cfg(feature = "UNSTABLE_metrics")] + #[cfg(feature = "metrics")] if let Some(ref aggregator) = *self.metric_aggregator.read().unwrap() { aggregator.flush(); } @@ -359,7 +359,7 @@ impl Client { /// `shutdown_timeout` in the client options. pub fn close(&self, timeout: Option) -> bool { drop(self.session_flusher.write().unwrap().take()); - #[cfg(feature = "UNSTABLE_metrics")] + #[cfg(feature = "metrics")] drop(self.metric_aggregator.write().unwrap().take()); let transport_opt = self.transport.write().unwrap().take(); if let Some(transport) = transport_opt { diff --git a/sentry-core/src/lib.rs b/sentry-core/src/lib.rs index f29454e66..ac48eeacf 100644 --- a/sentry-core/src/lib.rs +++ b/sentry-core/src/lib.rs @@ -136,18 +136,18 @@ pub use crate::performance::*; pub use crate::scope::{Scope, ScopeGuard}; pub use crate::transport::{Transport, TransportFactory}; -#[cfg(all(feature = "client", feature = "UNSTABLE_cadence"))] +#[cfg(all(feature = "client", feature = "metrics-cadence1"))] pub mod cadence; // client feature #[cfg(feature = "client")] mod client; #[cfg(feature = "client")] mod hub_impl; -#[cfg(all(feature = "client", feature = "UNSTABLE_metrics"))] +#[cfg(all(feature = "client", feature = "metrics"))] pub mod metrics; #[cfg(feature = "client")] mod session; -#[cfg(all(feature = "client", feature = "UNSTABLE_metrics"))] +#[cfg(all(feature = "client", feature = "metrics"))] mod units; #[cfg(feature = "client")] pub use crate::client::Client; diff --git a/sentry-core/src/metrics/normalization/normalized_tags.rs b/sentry-core/src/metrics/normalization/normalized_tags.rs index f98935fb4..78cb77148 100644 --- a/sentry-core/src/metrics/normalization/normalized_tags.rs +++ b/sentry-core/src/metrics/normalization/normalized_tags.rs @@ -1,6 +1,8 @@ -use itertools::Itertools; use regex::Regex; -use std::{borrow::Cow, collections::HashMap, sync::OnceLock}; +use std::borrow::Cow; +use std::collections::BTreeMap; +use std::fmt::Write; +use std::sync::OnceLock; use crate::metrics::TagMap; @@ -20,7 +22,7 @@ pub fn normalize_tags(tags: &TagMap) -> NormalizedTags { } pub struct NormalizedTags<'a> { - tags: HashMap, String>, + tags: BTreeMap, String>, } impl<'a> NormalizedTags<'a> { @@ -62,13 +64,13 @@ impl<'a> NormalizedTags<'a> { impl std::fmt::Display for NormalizedTags<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let res = self - .tags - .iter() - .map(|(k, v)| format!("{}:{}", k, v)) - .sorted() - .join(","); - write!(f, "{res}") + for (i, (k, v)) in self.tags.iter().enumerate() { + if i > 0 { + f.write_char(',')?; + } + write!(f, "{k}:{v}")?; + } + Ok(()) } } diff --git a/sentry-types/Cargo.toml b/sentry-types/Cargo.toml index 949527622..5413c0bb0 100644 --- a/sentry-types/Cargo.toml +++ b/sentry-types/Cargo.toml @@ -19,7 +19,7 @@ all-features = true [features] default = ["protocol"] protocol = [] -UNSTABLE_metrics = [] +metrics = [] [dependencies] debugid = { version = "0.8.0", features = ["serde"] } @@ -33,4 +33,4 @@ url = { version = "2.1.1", features = ["serde"] } uuid = { version = "1.0.0", features = ["serde"] } [dev-dependencies] -rstest = "0.18.2" +rstest = "0.19.0" diff --git a/sentry-types/src/protocol/envelope.rs b/sentry-types/src/protocol/envelope.rs index c978b74f3..1a4e67ca8 100644 --- a/sentry-types/src/protocol/envelope.rs +++ b/sentry-types/src/protocol/envelope.rs @@ -65,7 +65,7 @@ enum EnvelopeItemType { #[serde(rename = "check_in")] MonitorCheckIn, /// A Metrics Item type. - #[cfg(feature = "UNSTABLE_metrics")] + #[cfg(feature = "metrics")] #[serde(rename = "statsd")] Metrics, } @@ -117,7 +117,7 @@ pub enum EnvelopeItem { /// A MonitorCheckIn item. MonitorCheckIn(MonitorCheckIn), /// A Metrics Item. - #[cfg(feature = "UNSTABLE_metrics")] + #[cfg(feature = "metrics")] Statsd(Vec), /// This is a sentinel item used to `filter` raw envelopes. Raw, @@ -359,7 +359,7 @@ impl Envelope { EnvelopeItem::MonitorCheckIn(check_in) => { serde_json::to_writer(&mut item_buf, check_in)? } - #[cfg(feature = "UNSTABLE_metrics")] + #[cfg(feature = "metrics")] EnvelopeItem::Statsd(statsd) => item_buf.extend_from_slice(statsd), EnvelopeItem::Raw => { continue; @@ -371,7 +371,7 @@ impl Envelope { EnvelopeItem::SessionAggregates(_) => "sessions", EnvelopeItem::Transaction(_) => "transaction", EnvelopeItem::MonitorCheckIn(_) => "check_in", - #[cfg(feature = "UNSTABLE_metrics")] + #[cfg(feature = "metrics")] EnvelopeItem::Statsd(_) => "statsd", EnvelopeItem::Attachment(_) | EnvelopeItem::Raw => unreachable!(), }; @@ -517,7 +517,7 @@ impl Envelope { EnvelopeItemType::MonitorCheckIn => { serde_json::from_slice(payload).map(EnvelopeItem::MonitorCheckIn) } - #[cfg(feature = "UNSTABLE_metrics")] + #[cfg(feature = "metrics")] EnvelopeItemType::Metrics => Ok(EnvelopeItem::Statsd(payload.into())), } .map_err(EnvelopeError::InvalidItemPayload)?; diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index 206751751..c593ab218 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -22,7 +22,8 @@ rustdoc-args = ["--cfg", "doc_cfg"] [features] default = ["backtrace", "contexts", "debug-images", "panic", "transport"] -UNSTABLE_metrics = ["sentry-core/UNSTABLE_metrics"] +metrics = ["sentry-core/metrics"] +metrics-cadence1 = ["sentry-core/metrics-cadence1"] # default integrations backtrace = ["sentry-backtrace", "sentry-tracing?/backtrace"] @@ -79,10 +80,8 @@ serde_json = { version = "1.0.48", optional = true } tokio = { version = "1.0", features = ["rt"], optional = true } ureq = { version = "2.7.0", optional = true, default-features = false } native-tls = { version = "0.2.8", optional = true } -rustls = { version = "0.21.2", optional = true, features = [ - "dangerous_configuration", -] } -webpki-roots = { version = "0.25.1", optional = true } +rustls = { version = "0.22.4", optional = true } +webpki-roots = { version = "0.26.1", optional = true } embedded-svc = { version = "0.27.1", optional = true } [target.'cfg(target_os = "espidf")'.dependencies] esp-idf-svc = { version = "0.48.1", optional = true } diff --git a/sentry/src/transports/ratelimit.rs b/sentry/src/transports/ratelimit.rs index a64ce3a9f..3b998ff00 100644 --- a/sentry/src/transports/ratelimit.rs +++ b/sentry/src/transports/ratelimit.rs @@ -115,7 +115,7 @@ impl RateLimiter { } EnvelopeItem::Transaction(_) => RateLimitingCategory::Transaction, EnvelopeItem::Attachment(_) => RateLimitingCategory::Attachment, - #[cfg(feature = "UNSTABLE_metrics")] + #[cfg(feature = "metrics")] EnvelopeItem::Statsd(_) => RateLimitingCategory::Statsd, _ => RateLimitingCategory::Any, }) diff --git a/sentry/src/transports/ureq.rs b/sentry/src/transports/ureq.rs index ab4f45556..ee59cd283 100644 --- a/sentry/src/transports/ureq.rs +++ b/sentry/src/transports/ureq.rs @@ -1,15 +1,16 @@ use std::sync::Arc; use std::time::Duration; -#[cfg(feature = "rustls")] -use std::time::SystemTime; #[cfg(feature = "native-tls")] use native_tls::TlsConnector; #[cfg(feature = "rustls")] -use rustls::{ - client::{ServerCertVerified, ServerCertVerifier}, - Certificate, ClientConfig, Error, OwnedTrustAnchor, RootCertStore, ServerName, -}; +use rustls::client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier}; +#[cfg(feature = "rustls")] +use rustls::crypto::{verify_tls12_signature, verify_tls13_signature}; +#[cfg(feature = "rustls")] +use rustls::pki_types::{CertificateDer, ServerName, TrustAnchor, UnixTime}; +#[cfg(feature = "rustls")] +use rustls::{ClientConfig, DigitallySignedStruct, RootCertStore}; use ureq::{Agent, AgentBuilder, Proxy}; #[cfg(feature = "rustls")] use webpki_roots::TLS_SERVER_ROOTS; @@ -57,32 +58,63 @@ impl UreqHttpTransport { if options.accept_invalid_certs { #[cfg(feature = "rustls")] { + #[derive(Debug)] struct NoVerifier; impl ServerCertVerifier for NoVerifier { fn verify_server_cert( &self, - _end_entity: &Certificate, - _intermediates: &[Certificate], - _server_name: &ServerName, - _scts: &mut dyn Iterator, - _ocsp_response: &[u8], - _now: SystemTime, - ) -> Result { + _end_entity: &CertificateDer<'_>, + _intermediates: &[CertificateDer<'_>], + _server_name: &ServerName<'_>, + _ocsp: &[u8], + _now: UnixTime, + ) -> Result { Ok(ServerCertVerified::assertion()) } + + fn verify_tls12_signature( + &self, + message: &[u8], + cert: &CertificateDer<'_>, + dss: &DigitallySignedStruct, + ) -> Result + { + verify_tls12_signature( + message, + cert, + dss, + &rustls::crypto::ring::default_provider() + .signature_verification_algorithms, + ) + } + + fn verify_tls13_signature( + &self, + message: &[u8], + cert: &CertificateDer<'_>, + dss: &DigitallySignedStruct, + ) -> Result + { + verify_tls13_signature( + message, + cert, + dss, + &rustls::crypto::ring::default_provider() + .signature_verification_algorithms, + ) + } + + fn supported_verify_schemes(&self) -> Vec { + rustls::crypto::ring::default_provider() + .signature_verification_algorithms + .supported_schemes() + } } let mut root_store = RootCertStore::empty(); - root_store.add_trust_anchors(TLS_SERVER_ROOTS.iter().map(|ta| { - OwnedTrustAnchor::from_subject_spki_name_constraints( - ta.subject, - ta.spki, - ta.name_constraints, - ) - })); + root_store.extend(TLS_SERVER_ROOTS.iter().map(TrustAnchor::to_owned)); let mut config = ClientConfig::builder() - .with_safe_defaults() .with_root_certificates(root_store) .with_no_client_auth(); config From b81348ff32972fc8c074aa067443d3e049c3dc0e Mon Sep 17 00:00:00 2001 From: elramen <158566966+elramen@users.noreply.github.com> Date: Wed, 5 Jun 2024 15:30:28 +0200 Subject: [PATCH 009/148] ref(client): Make prepare_event public (#662) Make prepare_event public so that sentry-cli can use it directly instead of via capture_event. This allows sentry-cli to do the actual transmission, enabling debug logging and non-zero exit codes on transmission failure --- sentry-core/src/client.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sentry-core/src/client.rs b/sentry-core/src/client.rs index 46d49e676..89fa0677f 100644 --- a/sentry-core/src/client.rs +++ b/sentry-core/src/client.rs @@ -172,7 +172,8 @@ impl Client { integration.as_ref().as_any().downcast_ref() } - fn prepare_event( + /// Prepares an event for transmission to sentry. + pub fn prepare_event( &self, mut event: Event<'static>, scope: Option<&Scope>, From 05d86bcbe74a327464a7bd3762056fbd481b8b64 Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Wed, 5 Jun 2024 13:38:13 +0000 Subject: [PATCH 010/148] release: 0.34.0 --- CHANGELOG.md | 2 +- sentry-actix/Cargo.toml | 4 ++-- sentry-anyhow/Cargo.toml | 6 +++--- sentry-backtrace/Cargo.toml | 4 ++-- sentry-contexts/Cargo.toml | 4 ++-- sentry-core/Cargo.toml | 4 ++-- sentry-core/README.md | 2 +- sentry-debug-images/Cargo.toml | 4 ++-- sentry-debug-images/README.md | 2 +- sentry-log/Cargo.toml | 4 ++-- sentry-panic/Cargo.toml | 6 +++--- sentry-slog/Cargo.toml | 4 ++-- sentry-tower/Cargo.toml | 4 ++-- sentry-tower/README.md | 2 +- sentry-tracing/Cargo.toml | 6 +++--- sentry-tracing/README.md | 2 +- sentry-types/Cargo.toml | 2 +- sentry/Cargo.toml | 22 +++++++++++----------- sentry/README.md | 12 ++++++------ 19 files changed, 48 insertions(+), 48 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 27e506d8d..5c7eb16a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 0.34.0 **Features**: diff --git a/sentry-actix/Cargo.toml b/sentry-actix/Cargo.toml index d5eea3460..b540bfde3 100644 --- a/sentry-actix/Cargo.toml +++ b/sentry-actix/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-actix" -version = "0.33.0" +version = "0.34.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -15,7 +15,7 @@ rust-version = "1.73" [dependencies] actix-web = { version = "4", default-features = false } futures-util = { version = "0.3.5", default-features = false } -sentry-core = { version = "0.33.0", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.34.0", path = "../sentry-core", default-features = false, features = [ "client", ] } diff --git a/sentry-anyhow/Cargo.toml b/sentry-anyhow/Cargo.toml index 849799dc7..83e31e3bb 100644 --- a/sentry-anyhow/Cargo.toml +++ b/sentry-anyhow/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-anyhow" -version = "0.33.0" +version = "0.34.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -17,8 +17,8 @@ default = ["backtrace"] backtrace = ["anyhow/backtrace"] [dependencies] -sentry-backtrace = { version = "0.33.0", path = "../sentry-backtrace" } -sentry-core = { version = "0.33.0", path = "../sentry-core" } +sentry-backtrace = { version = "0.34.0", path = "../sentry-backtrace" } +sentry-core = { version = "0.34.0", path = "../sentry-core" } anyhow = "1.0.39" [dev-dependencies] diff --git a/sentry-backtrace/Cargo.toml b/sentry-backtrace/Cargo.toml index 2becc83a6..56d84cfdb 100644 --- a/sentry-backtrace/Cargo.toml +++ b/sentry-backtrace/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-backtrace" -version = "0.33.0" +version = "0.34.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -19,4 +19,4 @@ regex = { version = "1.5.5", default-features = false, features = [ "std", "unicode-perl", ] } -sentry-core = { version = "0.33.0", path = "../sentry-core" } +sentry-core = { version = "0.34.0", path = "../sentry-core" } diff --git a/sentry-contexts/Cargo.toml b/sentry-contexts/Cargo.toml index f98af5706..42dfde9ca 100644 --- a/sentry-contexts/Cargo.toml +++ b/sentry-contexts/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-contexts" -version = "0.33.0" +version = "0.34.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -14,7 +14,7 @@ edition = "2021" rust-version = "1.73" [dependencies] -sentry-core = { version = "0.33.0", path = "../sentry-core" } +sentry-core = { version = "0.34.0", path = "../sentry-core" } libc = "0.2.66" hostname = "0.4" diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index 47f653359..beb142c2d 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-core" -version = "0.33.0" +version = "0.34.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -36,7 +36,7 @@ log = { version = "0.4.8", optional = true, features = ["std"] } once_cell = "1" rand = { version = "0.8.1", optional = true } regex = { version = "1.7.3", optional = true } -sentry-types = { version = "0.33.0", path = "../sentry-types" } +sentry-types = { version = "0.34.0", path = "../sentry-types" } serde = { version = "1.0.104", features = ["derive"] } serde_json = { version = "1.0.46" } uuid = { version = "1.0.0", features = ["v4", "serde"], optional = true } diff --git a/sentry-core/README.md b/sentry-core/README.md index b08c3e116..f72f0abd2 100644 --- a/sentry-core/README.md +++ b/sentry-core/README.md @@ -102,7 +102,7 @@ functionality. [Sentry]: https://sentry.io/ [`sentry`]: https://crates.io/crates/sentry [Unified API]: https://develop.sentry.dev/sdk/unified-api/ -[`test`]: https://docs.rs/sentry-core/0.33.0/sentry_core/test/index.html +[`test`]: https://docs.rs/sentry-core/0.34.0/sentry_core/test/index.html ## Resources diff --git a/sentry-debug-images/Cargo.toml b/sentry-debug-images/Cargo.toml index c10e59a5a..3838858a3 100644 --- a/sentry-debug-images/Cargo.toml +++ b/sentry-debug-images/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-debug-images" -version = "0.33.0" +version = "0.34.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -15,4 +15,4 @@ rust-version = "1.73" [dependencies] findshlibs = "=0.10.2" once_cell = "1" -sentry-core = { version = "0.33.0", path = "../sentry-core" } +sentry-core = { version = "0.34.0", path = "../sentry-core" } diff --git a/sentry-debug-images/README.md b/sentry-debug-images/README.md index 7c8b48099..0bf922a5d 100644 --- a/sentry-debug-images/README.md +++ b/sentry-debug-images/README.md @@ -22,7 +22,7 @@ let integration = sentry_debug_images::DebugImagesIntegration::new() .filter(|event| event.level >= Level::Warning); ``` -[`Event`]: https://docs.rs/sentry-debug-images/0.33.0/sentry_debug_images/sentry_core::protocol::Event +[`Event`]: https://docs.rs/sentry-debug-images/0.34.0/sentry_debug_images/sentry_core::protocol::Event ## Resources diff --git a/sentry-log/Cargo.toml b/sentry-log/Cargo.toml index 14960eb7c..49e84156a 100644 --- a/sentry-log/Cargo.toml +++ b/sentry-log/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-log" -version = "0.33.0" +version = "0.34.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.73" [dependencies] -sentry-core = { version = "0.33.0", path = "../sentry-core" } +sentry-core = { version = "0.34.0", path = "../sentry-core" } log = { version = "0.4.8", features = ["std"] } [dev-dependencies] diff --git a/sentry-panic/Cargo.toml b/sentry-panic/Cargo.toml index 60f19f96f..d4c5549f5 100644 --- a/sentry-panic/Cargo.toml +++ b/sentry-panic/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-panic" -version = "0.33.0" +version = "0.34.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -13,8 +13,8 @@ edition = "2021" rust-version = "1.73" [dependencies] -sentry-core = { version = "0.33.0", path = "../sentry-core" } -sentry-backtrace = { version = "0.33.0", path = "../sentry-backtrace" } +sentry-core = { version = "0.34.0", path = "../sentry-core" } +sentry-backtrace = { version = "0.34.0", path = "../sentry-backtrace" } [dev-dependencies] sentry = { path = "../sentry", default-features = false, features = ["test"] } diff --git a/sentry-slog/Cargo.toml b/sentry-slog/Cargo.toml index 06c06b28a..e92959973 100644 --- a/sentry-slog/Cargo.toml +++ b/sentry-slog/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-slog" -version = "0.33.0" +version = "0.34.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.73" [dependencies] -sentry-core = { version = "0.33.0", path = "../sentry-core" } +sentry-core = { version = "0.34.0", path = "../sentry-core" } slog = { version = "2.5.2", features = ["nested-values"] } serde_json = "1.0.46" diff --git a/sentry-tower/Cargo.toml b/sentry-tower/Cargo.toml index 93ae734d1..15b88b723 100644 --- a/sentry-tower/Cargo.toml +++ b/sentry-tower/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tower" -version = "0.33.0" +version = "0.34.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -25,7 +25,7 @@ tower-layer = "0.3" tower-service = "0.3" http = { version = "1.0.0", optional = true } pin-project = { version = "1.0.10", optional = true } -sentry-core = { version = "0.33.0", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.34.0", path = "../sentry-core", default-features = false, features = [ "client", ] } url = { version = "2.2.2", optional = true } diff --git a/sentry-tower/README.md b/sentry-tower/README.md index e314311d0..fac9f2232 100644 --- a/sentry-tower/README.md +++ b/sentry-tower/README.md @@ -103,7 +103,7 @@ feature of the `sentry` crate instead of the `tower` feature. The created transaction will automatically use the request URI as its name. This is sometimes not desirable in case the request URI contains unique IDs or similar. In this case, users should manually override the transaction name -in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.33.0/sentry_tower/sentry_core::Scope::set_transaction) +in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.34.0/sentry_tower/sentry_core::Scope::set_transaction) method. When combining both layers, take care of the ordering of both. For example diff --git a/sentry-tracing/Cargo.toml b/sentry-tracing/Cargo.toml index 5775805df..fc146712a 100644 --- a/sentry-tracing/Cargo.toml +++ b/sentry-tracing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tracing" -version = "0.33.0" +version = "0.34.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -20,14 +20,14 @@ default = [] backtrace = ["dep:sentry-backtrace"] [dependencies] -sentry-core = { version = "0.33.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.34.0", path = "../sentry-core", features = [ "client", ] } tracing-core = "0.1" tracing-subscriber = { version = "0.3.1", default-features = false, features = [ "std", ] } -sentry-backtrace = { version = "0.33.0", path = "../sentry-backtrace", optional = true } +sentry-backtrace = { version = "0.34.0", path = "../sentry-backtrace", optional = true } [dev-dependencies] log = "0.4" diff --git a/sentry-tracing/README.md b/sentry-tracing/README.md index a2376344d..15403cca8 100644 --- a/sentry-tracing/README.md +++ b/sentry-tracing/README.md @@ -83,7 +83,7 @@ tracing::error!( ); ``` -To track [error structs](https://docs.rs/sentry-tracing/0.33.0/sentry_tracing/std::error::Error), assign a reference to error trait object as field +To track [error structs](https://docs.rs/sentry-tracing/0.34.0/sentry_tracing/std::error::Error), assign a reference to error trait object as field in one of the logging macros. By convention, it is recommended to use the `ERROR` level and assign it to a field called `error`, although the integration will also work with all other levels and field names. diff --git a/sentry-types/Cargo.toml b/sentry-types/Cargo.toml index 5413c0bb0..9a9dbdeed 100644 --- a/sentry-types/Cargo.toml +++ b/sentry-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-types" -version = "0.33.0" +version = "0.34.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index c593ab218..260af7abc 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry" -version = "0.33.0" +version = "0.34.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -54,18 +54,18 @@ rustls = ["dep:rustls", "reqwest?/rustls-tls", "ureq?/tls", "webpki-roots"] embedded-svc-http = ["dep:embedded-svc", "dep:esp-idf-svc"] [dependencies] -sentry-core = { version = "0.33.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.34.0", path = "../sentry-core", features = [ "client", ] } -sentry-anyhow = { version = "0.33.0", path = "../sentry-anyhow", optional = true } -sentry-backtrace = { version = "0.33.0", path = "../sentry-backtrace", optional = true } -sentry-contexts = { version = "0.33.0", path = "../sentry-contexts", optional = true } -sentry-debug-images = { version = "0.33.0", path = "../sentry-debug-images", optional = true } -sentry-log = { version = "0.33.0", path = "../sentry-log", optional = true } -sentry-panic = { version = "0.33.0", path = "../sentry-panic", optional = true } -sentry-slog = { version = "0.33.0", path = "../sentry-slog", optional = true } -sentry-tower = { version = "0.33.0", path = "../sentry-tower", optional = true } -sentry-tracing = { version = "0.33.0", path = "../sentry-tracing", optional = true } +sentry-anyhow = { version = "0.34.0", path = "../sentry-anyhow", optional = true } +sentry-backtrace = { version = "0.34.0", path = "../sentry-backtrace", optional = true } +sentry-contexts = { version = "0.34.0", path = "../sentry-contexts", optional = true } +sentry-debug-images = { version = "0.34.0", path = "../sentry-debug-images", optional = true } +sentry-log = { version = "0.34.0", path = "../sentry-log", optional = true } +sentry-panic = { version = "0.34.0", path = "../sentry-panic", optional = true } +sentry-slog = { version = "0.34.0", path = "../sentry-slog", optional = true } +sentry-tower = { version = "0.34.0", path = "../sentry-tower", optional = true } +sentry-tracing = { version = "0.34.0", path = "../sentry-tracing", optional = true } log = { version = "0.4.8", optional = true, features = ["std"] } reqwest = { version = "0.12", optional = true, features = [ "blocking", diff --git a/sentry/README.md b/sentry/README.md index 5b5d16a50..2a810e479 100644 --- a/sentry/README.md +++ b/sentry/README.md @@ -34,8 +34,8 @@ sentry::capture_message("Hello World!", sentry::Level::Info); More complex examples on how to use sentry can also be found in [examples]. Extended instructions may also be found on [Sentry itself]. -[`sentry::init`]: https://docs.rs/sentry/0.33.0/sentry/fn.init.html -[`Hub`]: https://docs.rs/sentry/0.33.0/sentry/struct.Hub.html +[`sentry::init`]: https://docs.rs/sentry/0.34.0/sentry/fn.init.html +[`Hub`]: https://docs.rs/sentry/0.34.0/sentry/struct.Hub.html [examples]: https://github.com/getsentry/sentry-rust/tree/master/sentry/examples [Sentry itself]: https://docs.sentry.io/platforms/rust @@ -47,8 +47,8 @@ the ecosystem require a feature flag. For available integrations and how to use [integrations] and [apply_defaults]. [Features]: #features -[integrations]: https://docs.rs/sentry/0.33.0/sentry/integrations/index.html -[apply_defaults]: https://docs.rs/sentry/0.33.0/sentry/fn.apply_defaults.html +[integrations]: https://docs.rs/sentry/0.34.0/sentry/integrations/index.html +[apply_defaults]: https://docs.rs/sentry/0.34.0/sentry/fn.apply_defaults.html ## Minimal API @@ -56,8 +56,8 @@ This crate comes fully-featured. If the goal is to instrument libraries for usag with sentry, or to extend sentry with a custom [`Integration`] or a [`Transport`], one should use the [`sentry-core`] crate instead. -[`Integration`]: https://docs.rs/sentry/0.33.0/sentry/trait.Integration.html -[`Transport`]: https://docs.rs/sentry/0.33.0/sentry/trait.Transport.html +[`Integration`]: https://docs.rs/sentry/0.34.0/sentry/trait.Integration.html +[`Transport`]: https://docs.rs/sentry/0.34.0/sentry/trait.Transport.html [`sentry-core`]: https://crates.io/crates/sentry-core ## Features From 172bcd419ff04f2ed2df2b65d17dc4357affaa80 Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Thu, 27 Jun 2024 15:38:03 +0200 Subject: [PATCH 011/148] Tower and Actix: Filter out sensitive headers (#665) --- sentry-actix/src/lib.rs | 1 + sentry-tower/src/http.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/sentry-actix/src/lib.rs b/sentry-actix/src/lib.rs index 376854d4a..3232d140f 100644 --- a/sentry-actix/src/lib.rs +++ b/sentry-actix/src/lib.rs @@ -355,6 +355,7 @@ fn sentry_request_from_http(request: &ServiceRequest, with_pii: bool) -> Request headers: request .headers() .iter() + .filter(|(_, v)| !v.is_sensitive()) .map(|(k, v)| (k.to_string(), v.to_str().unwrap_or_default().to_string())) .collect(), ..Default::default() diff --git a/sentry-tower/src/http.rs b/sentry-tower/src/http.rs index 32fd69025..5ad964626 100644 --- a/sentry-tower/src/http.rs +++ b/sentry-tower/src/http.rs @@ -142,6 +142,7 @@ where headers: request .headers() .into_iter() + .filter(|(_, value)| !value.is_sensitive()) .map(|(header, value)| { ( header.to_string(), From e828ca28a53994a64ef91e72f1f6fe7e10c6ea3c Mon Sep 17 00:00:00 2001 From: Evan Purkhiser Date: Wed, 10 Jul 2024 03:16:26 -0400 Subject: [PATCH 012/148] fix(docs): Dev docs metrics link (#666) --- sentry-core/src/metrics/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sentry-core/src/metrics/mod.rs b/sentry-core/src/metrics/mod.rs index 65cd74781..96da9d4f9 100644 --- a/sentry-core/src/metrics/mod.rs +++ b/sentry-core/src/metrics/mod.rs @@ -42,7 +42,7 @@ //! [`cadence`] is a popular Statsd client for Rust and can be used to send metrics to Sentry. To //! use Sentry directly with `cadence`, see the [`sentry-cadence`](crate::cadence) documentation. //! -//! [our docs]: https://develop.sentry.dev/delightful-developer-metrics/ +//! [our docs]: https://develop.sentry.dev/services/metrics/ mod normalization; From 8a046059af20564193eae30e996eb8e48362acbd Mon Sep 17 00:00:00 2001 From: Thomas B <9094255+Ten0@users.noreply.github.com> Date: Fri, 12 Jul 2024 11:14:29 +0200 Subject: [PATCH 013/148] Don't generate a random to choose whether we should sample if sampling is fully disabled (rate = 0.0) (#667) --- sentry-core/src/client.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sentry-core/src/client.rs b/sentry-core/src/client.rs index 89fa0677f..56bd0d22f 100644 --- a/sentry-core/src/client.rs +++ b/sentry-core/src/client.rs @@ -2,8 +2,7 @@ use std::any::TypeId; use std::borrow::Cow; use std::fmt; use std::panic::RefUnwindSafe; -use std::sync::Arc; -use std::sync::RwLock; +use std::sync::{Arc, RwLock}; use std::time::Duration; use rand::random; @@ -377,6 +376,8 @@ impl Client { pub fn sample_should_send(&self, rate: f32) -> bool { if rate >= 1.0 { true + } else if rate <= 0.0 { + false } else { random::() < rate } From 36f1384d3ec5f1f7c734c63ab846fd0b974c7194 Mon Sep 17 00:00:00 2001 From: Thomas B <9094255+Ten0@users.noreply.github.com> Date: Mon, 15 Jul 2024 10:32:09 +0200 Subject: [PATCH 014/148] Reexport Url and Uuid in `protocol` (#670) These are required to construct some public types, so the good practice is to reexport them so that users can use them without specifying the dependency explicitly themselves and be less likely to break on update. --- sentry-types/src/protocol/v7.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sentry-types/src/protocol/v7.rs b/sentry-types/src/protocol/v7.rs index df1805a94..a2fc3a880 100644 --- a/sentry-types/src/protocol/v7.rs +++ b/sentry-types/src/protocol/v7.rs @@ -18,8 +18,9 @@ use std::time::SystemTime; use self::debugid::{CodeId, DebugId}; use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; use thiserror::Error; -use url::Url; -use uuid::Uuid; + +pub use url::Url; +pub use uuid::Uuid; use crate::utils::{ts_rfc3339_opt, ts_seconds_float}; From 8cc4848f115152af6f2ad66d7aeb17bd3bbe38fd Mon Sep 17 00:00:00 2001 From: Thomas B <9094255+Ten0@users.noreply.github.com> Date: Mon, 15 Jul 2024 10:42:34 +0200 Subject: [PATCH 015/148] Give access to is_sampled to allow users to dodge work in unsampled case (#669) --- sentry-core/src/performance.rs | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/sentry-core/src/performance.rs b/sentry-core/src/performance.rs index 552cc563b..062899aeb 100644 --- a/sentry-core/src/performance.rs +++ b/sentry-core/src/performance.rs @@ -84,7 +84,7 @@ impl TransactionContext { /// can be used for distributed tracing. #[must_use = "this must be used with `start_transaction`"] pub fn new(name: &str, op: &str) -> Self { - Self::continue_from_headers(name, op, vec![]) + Self::continue_from_headers(name, op, std::iter::empty()) } /// Creates a new Transaction Context based on the distributed tracing `headers`. @@ -200,7 +200,8 @@ impl TransactionContext { /// /// If the context did not have this key present, None is returned. /// - /// If the context did have this key present, the value is updated, and the old value is returned. + /// If the context did have this key present, the value is updated, and the old value is + /// returned. pub fn custom_insert( &mut self, key: String, @@ -301,6 +302,14 @@ impl TransactionOrSpan { } } + /// Get the sampling decision for this Transaction/Span. + pub fn is_sampled(&self) -> bool { + match self { + TransactionOrSpan::Transaction(transaction) => transaction.is_sampled(), + TransactionOrSpan::Span(span) => span.is_sampled(), + } + } + /// Starts a new child Span with the given `op` and `description`. /// /// The span must be explicitly finished via [`Span::finish`], as it will @@ -483,7 +492,8 @@ impl Transaction { } } - /// Returns an iterating accessor to the transaction's [`extra` field](protocol::Transaction::extra). + /// Returns an iterating accessor to the transaction's + /// [`extra` field](protocol::Transaction::extra). /// /// # Concurrency /// In order to obtain any kind of reference to the `extra` field, @@ -536,6 +546,11 @@ impl Transaction { } } + /// Get the sampling decision for this Transaction. + pub fn is_sampled(&self) -> bool { + self.inner.lock().unwrap().sampled + } + /// Finishes the Transaction. /// /// This records the end timestamp and sends the transaction together with @@ -708,6 +723,11 @@ impl Span { } } + /// Get the sampling decision for this Span. + pub fn is_sampled(&self) -> bool { + self.sampled + } + /// Finishes the Span. /// /// This will record the end timestamp and add the span to the transaction From 16cd81eebaf946f728cd4e21bfb9c38aa3ad991a Mon Sep 17 00:00:00 2001 From: Guillaume Lagrange Date: Thu, 25 Jul 2024 15:58:09 +0200 Subject: [PATCH 016/148] chore: export `BeforeCallback` type (#671) --- sentry-core/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sentry-core/src/lib.rs b/sentry-core/src/lib.rs index ac48eeacf..1f7d8c31e 100644 --- a/sentry-core/src/lib.rs +++ b/sentry-core/src/lib.rs @@ -126,7 +126,7 @@ mod transport; // public api or exports from this crate pub use crate::api::*; pub use crate::breadcrumbs::IntoBreadcrumbs; -pub use crate::clientoptions::{ClientOptions, SessionMode}; +pub use crate::clientoptions::{BeforeCallback, ClientOptions, SessionMode}; pub use crate::error::{capture_error, event_from_error, parse_type_from_debug}; pub use crate::futures::{SentryFuture, SentryFutureExt}; pub use crate::hub::Hub; From 96b35c730b3feb009e29ee25f9fb6955f3555730 Mon Sep 17 00:00:00 2001 From: Simon Hellmayr Date: Wed, 31 Jul 2024 17:46:44 +0200 Subject: [PATCH 017/148] fix(docs): grammar in Hub docs (#676) --- sentry-core/src/hub.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sentry-core/src/hub.rs b/sentry-core/src/hub.rs index cc0a9c3d1..f5ebf155c 100644 --- a/sentry-core/src/hub.rs +++ b/sentry-core/src/hub.rs @@ -8,7 +8,7 @@ use crate::protocol::{Event, Level, SessionStatus}; use crate::types::Uuid; use crate::{Integration, IntoBreadcrumbs, Scope, ScopeGuard}; -/// The central object that can manages scopes and clients. +/// The central object that can manage scopes and clients. /// /// This can be used to capture events and manage the scope. This object is [`Send`] and /// [`Sync`] so it can be used from multiple threads if needed. @@ -16,10 +16,10 @@ use crate::{Integration, IntoBreadcrumbs, Scope, ScopeGuard}; /// Each thread has its own thread-local ( see [`Hub::current`]) hub, which is /// automatically derived from the main hub ([`Hub::main`]). /// -/// In most situations developers do not need to interface with the hub directly. Instead -/// toplevel convenience functions are expose that will automatically dispatch -/// to the thread-local ([`Hub::current`]) hub. In some situations this might not be -/// possible in which case it might become necessary to manually work with the +/// In most situations, developers do not need to interface with the hub directly. Instead +/// toplevel convenience functions are exposed that will automatically dispatch +/// to the thread-local ([`Hub::current`]) hub. In some situations, this might not be +/// possible, in which case it might become necessary to manually work with the /// hub. See the main [`crate`] docs for some common use-cases and pitfalls /// related to parallel, concurrent or async code. /// From e2cfb065c7eb01de4e225692f9e72df7fa14df53 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Oct 2024 09:42:31 +0200 Subject: [PATCH 018/148] build(deps): bump openssl from 0.10.64 to 0.10.66 (#673) Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.64 to 0.10.66. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.64...openssl-v0.10.66) --- updated-dependencies: - dependency-name: openssl dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d24421f70..c9e5f3d02 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2952,9 +2952,9 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.64" +version = "0.10.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" dependencies = [ "bitflags 2.5.0", "cfg-if", @@ -2984,9 +2984,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.102" +version = "0.9.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" dependencies = [ "cc", "libc", @@ -3717,7 +3717,7 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "sentry" -version = "0.33.0" +version = "0.34.0" dependencies = [ "actix-web", "anyhow", @@ -3755,7 +3755,7 @@ dependencies = [ [[package]] name = "sentry-actix" -version = "0.33.0" +version = "0.34.0" dependencies = [ "actix-web", "futures", @@ -3767,7 +3767,7 @@ dependencies = [ [[package]] name = "sentry-anyhow" -version = "0.33.0" +version = "0.34.0" dependencies = [ "anyhow", "sentry", @@ -3777,7 +3777,7 @@ dependencies = [ [[package]] name = "sentry-backtrace" -version = "0.33.0" +version = "0.34.0" dependencies = [ "backtrace", "once_cell", @@ -3787,7 +3787,7 @@ dependencies = [ [[package]] name = "sentry-contexts" -version = "0.33.0" +version = "0.34.0" dependencies = [ "hostname", "libc", @@ -3800,7 +3800,7 @@ dependencies = [ [[package]] name = "sentry-core" -version = "0.33.0" +version = "0.34.0" dependencies = [ "anyhow", "cadence", @@ -3823,7 +3823,7 @@ dependencies = [ [[package]] name = "sentry-debug-images" -version = "0.33.0" +version = "0.34.0" dependencies = [ "findshlibs", "once_cell", @@ -3832,7 +3832,7 @@ dependencies = [ [[package]] name = "sentry-log" -version = "0.33.0" +version = "0.34.0" dependencies = [ "log", "pretty_env_logger", @@ -3842,7 +3842,7 @@ dependencies = [ [[package]] name = "sentry-panic" -version = "0.33.0" +version = "0.34.0" dependencies = [ "sentry", "sentry-backtrace", @@ -3851,7 +3851,7 @@ dependencies = [ [[package]] name = "sentry-slog" -version = "0.33.0" +version = "0.34.0" dependencies = [ "erased-serde", "sentry", @@ -3863,7 +3863,7 @@ dependencies = [ [[package]] name = "sentry-tower" -version = "0.33.0" +version = "0.34.0" dependencies = [ "anyhow", "axum 0.7.5", @@ -3883,7 +3883,7 @@ dependencies = [ [[package]] name = "sentry-tracing" -version = "0.33.0" +version = "0.34.0" dependencies = [ "log", "sentry", @@ -3897,7 +3897,7 @@ dependencies = [ [[package]] name = "sentry-types" -version = "0.33.0" +version = "0.34.0" dependencies = [ "debugid", "hex", From 0919717ea7a28f0ace8cade81bb3fd629c6b4bcc Mon Sep 17 00:00:00 2001 From: viglia Date: Thu, 3 Oct 2024 10:03:34 +0200 Subject: [PATCH 019/148] fix CI error "unexpected `cfg` condition name: `doc_cfg`" (#691) --- sentry/Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index 260af7abc..2ee7c8288 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -101,3 +101,6 @@ tokio = { version = "1.0", features = ["macros"] } tower = { version = "0.4", features = ["util"] } tracing = { version = "0.1" } tracing-subscriber = { version = "0.3", features = ["fmt", "tracing-log"] } + +[lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(doc_cfg)'] } \ No newline at end of file From 1f65ac8ab91ada293878b560f0f5ec2dd12beb53 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 3 Oct 2024 10:15:15 +0200 Subject: [PATCH 020/148] build(deps): bump tonic from 0.11.0 to 0.12.3 (#690) Bumps [tonic](https://github.com/hyperium/tonic) from 0.11.0 to 0.12.3. - [Release notes](https://github.com/hyperium/tonic/releases) - [Changelog](https://github.com/hyperium/tonic/blob/master/CHANGELOG.md) - [Commits](https://github.com/hyperium/tonic/compare/v0.11.0...v0.12.3) --- updated-dependencies: - dependency-name: tonic dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Francesco Vigliaturo --- Cargo.lock | 188 ++++++++++++++-------------------------- sentry-tower/Cargo.toml | 2 +- 2 files changed, 64 insertions(+), 126 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c9e5f3d02..22b88bc9a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -39,7 +39,7 @@ dependencies = [ "encoding_rs", "flate2", "futures-core", - "h2", + "h2 0.3.26", "http 0.2.12", "httparse", "httpdate", @@ -576,34 +576,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" -[[package]] -name = "axum" -version = "0.6.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" -dependencies = [ - "async-trait", - "axum-core 0.3.4", - "bitflags 1.3.2", - "bytes 1.6.0", - "futures-util", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.28", - "itoa", - "matchit", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "rustversion", - "serde", - "sync_wrapper 0.1.2", - "tower", - "tower-layer", - "tower-service", -] - [[package]] name = "axum" version = "0.7.5" @@ -611,11 +583,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" dependencies = [ "async-trait", - "axum-core 0.4.3", + "axum-core", "bytes 1.6.0", "futures-util", "http 1.1.0", - "http-body 1.0.0", + "http-body", "http-body-util", "itoa", "matchit", @@ -631,23 +603,6 @@ dependencies = [ "tower-service", ] -[[package]] -name = "axum-core" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" -dependencies = [ - "async-trait", - "bytes 1.6.0", - "futures-util", - "http 0.2.12", - "http-body 0.4.6", - "mime", - "rustversion", - "tower-layer", - "tower-service", -] - [[package]] name = "axum-core" version = "0.4.3" @@ -658,7 +613,7 @@ dependencies = [ "bytes 1.6.0", "futures-util", "http 1.1.0", - "http-body 1.0.0", + "http-body", "http-body-util", "mime", "pin-project-lite", @@ -695,12 +650,6 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - [[package]] name = "base64" version = "0.22.1" @@ -2096,6 +2045,25 @@ dependencies = [ "tracing", ] +[[package]] +name = "h2" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" +dependencies = [ + "atomic-waker", + "bytes 1.6.0", + "fnv", + "futures-core", + "futures-sink", + "http 1.1.0", + "indexmap 2.2.6", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "half" version = "2.4.1" @@ -2218,17 +2186,6 @@ dependencies = [ "itoa", ] -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes 1.6.0", - "http 0.2.12", - "pin-project-lite", -] - [[package]] name = "http-body" version = "1.0.0" @@ -2248,7 +2205,7 @@ dependencies = [ "bytes 1.6.0", "futures-core", "http 1.1.0", - "http-body 1.0.0", + "http-body", "pin-project-lite", ] @@ -2311,30 +2268,6 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" -[[package]] -name = "hyper" -version = "0.14.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" -dependencies = [ - "bytes 1.6.0", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http 0.2.12", - "http-body 0.4.6", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2 0.5.7", - "tokio", - "tower-service", - "tracing", - "want", -] - [[package]] name = "hyper" version = "1.3.1" @@ -2344,9 +2277,11 @@ dependencies = [ "bytes 1.6.0", "futures-channel", "futures-util", + "h2 0.4.6", "http 1.1.0", - "http-body 1.0.0", + "http-body", "httparse", + "httpdate", "itoa", "pin-project-lite", "smallvec", @@ -2362,7 +2297,7 @@ checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" dependencies = [ "futures-util", "http 1.1.0", - "hyper 1.3.1", + "hyper", "hyper-util", "rustls", "rustls-pki-types", @@ -2373,14 +2308,15 @@ dependencies = [ [[package]] name = "hyper-timeout" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +checksum = "3203a961e5c83b6f5498933e78b6b263e208c197b63e9c6c53cc82ffd3f63793" dependencies = [ - "hyper 0.14.28", + "hyper", + "hyper-util", "pin-project-lite", "tokio", - "tokio-io-timeout", + "tower-service", ] [[package]] @@ -2391,7 +2327,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes 1.6.0", "http-body-util", - "hyper 1.3.1", + "hyper", "hyper-util", "native-tls", "tokio", @@ -2409,8 +2345,8 @@ dependencies = [ "futures-channel", "futures-util", "http 1.1.0", - "http-body 1.0.0", - "hyper 1.3.1", + "http-body", + "hyper", "pin-project-lite", "socket2 0.5.7", "tokio", @@ -3257,6 +3193,15 @@ dependencies = [ "prost-derive", ] +[[package]] +name = "prost" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b0487d90e047de87f984913713b85c601c05609aad5b0df4b4573fbf69aa13f" +dependencies = [ + "bytes 1.6.0", +] + [[package]] name = "prost-derive" version = "0.12.6" @@ -3457,9 +3402,9 @@ dependencies = [ "futures-core", "futures-util", "http 1.1.0", - "http-body 1.0.0", + "http-body", "http-body-util", - "hyper 1.3.1", + "hyper", "hyper-rustls", "hyper-tls", "hyper-util", @@ -3866,10 +3811,10 @@ name = "sentry-tower" version = "0.34.0" dependencies = [ "anyhow", - "axum 0.7.5", + "axum", "http 1.1.0", "pin-project", - "prost", + "prost 0.12.6", "sentry", "sentry-anyhow", "sentry-core", @@ -4438,16 +4383,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "tokio-io-timeout" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" -dependencies = [ - "pin-project-lite", - "tokio", -] - [[package]] name = "tokio-macros" version = "2.2.0" @@ -4482,9 +4417,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" dependencies = [ "futures-core", "pin-project-lite", @@ -4523,23 +4458,26 @@ dependencies = [ [[package]] name = "tonic" -version = "0.11.0" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76c4eb7a4e9ef9d4763600161f12f5070b92a578e1b634db88a6887844c91a13" +checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" dependencies = [ "async-stream", "async-trait", - "axum 0.6.20", - "base64 0.21.7", + "axum", + "base64 0.22.1", "bytes 1.6.0", - "h2", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.28", + "h2 0.4.6", + "http 1.1.0", + "http-body", + "http-body-util", + "hyper", "hyper-timeout", + "hyper-util", "percent-encoding", "pin-project", - "prost", + "prost 0.13.3", + "socket2 0.5.7", "tokio", "tokio-stream", "tower", diff --git a/sentry-tower/Cargo.toml b/sentry-tower/Cargo.toml index 15b88b723..9102270c8 100644 --- a/sentry-tower/Cargo.toml +++ b/sentry-tower/Cargo.toml @@ -36,5 +36,5 @@ prost = "0.12.3" sentry = { path = "../sentry", default-features = false, features = ["test"] } sentry-anyhow = { path = "../sentry-anyhow" } tokio = { version = "1", features = ["macros", "rt-multi-thread"] } -tonic = { version = "0.11", features = ["transport"] } +tonic = { version = "0.12", features = ["transport"] } tower = { version = "0.4", features = ["util", "timeout"] } From 16baf61cdcc89a717062b08a571f38e3746ce616 Mon Sep 17 00:00:00 2001 From: Andrei Nesterov Date: Thu, 3 Oct 2024 11:26:59 +0300 Subject: [PATCH 021/148] Fix `Transport::flush` implementation for `TransportThread` (#678) Description for the `flush` function of the `Transport` trait states that "If the queue was successfully drained, the return value should be `true`.", but implementation of the trait on `tokio_thread::TransportThread` do the oposite. The same error for `thread::TransportThread`. Co-authored-by: Francesco Vigliaturo --- sentry/src/transports/thread.rs | 2 +- sentry/src/transports/tokio_thread.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sentry/src/transports/thread.rs b/sentry/src/transports/thread.rs index 368ecdd81..80d0e1201 100644 --- a/sentry/src/transports/thread.rs +++ b/sentry/src/transports/thread.rs @@ -80,7 +80,7 @@ impl TransportThread { pub fn flush(&self, timeout: Duration) -> bool { let (sender, receiver) = sync_channel(1); let _ = self.sender.send(Task::Flush(sender)); - receiver.recv_timeout(timeout).is_err() + receiver.recv_timeout(timeout).is_ok() } } diff --git a/sentry/src/transports/tokio_thread.rs b/sentry/src/transports/tokio_thread.rs index 5ea1ae5e4..9323e482c 100644 --- a/sentry/src/transports/tokio_thread.rs +++ b/sentry/src/transports/tokio_thread.rs @@ -96,7 +96,7 @@ impl TransportThread { pub fn flush(&self, timeout: Duration) -> bool { let (sender, receiver) = sync_channel(1); let _ = self.sender.send(Task::Flush(sender)); - receiver.recv_timeout(timeout).is_err() + receiver.recv_timeout(timeout).is_ok() } } From d0585b6023a139a2e6a0ebe1c20a978451b14da5 Mon Sep 17 00:00:00 2001 From: Andres Date: Fri, 4 Oct 2024 00:46:59 -0700 Subject: [PATCH 022/148] add server_name to transaction data (#694) --- sentry-core/src/performance.rs | 1 + sentry-types/src/protocol/v7.rs | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/sentry-core/src/performance.rs b/sentry-core/src/performance.rs index 062899aeb..a0046d304 100644 --- a/sentry-core/src/performance.rs +++ b/sentry-core/src/performance.rs @@ -570,6 +570,7 @@ impl Transaction { transaction.release.clone_from(&opts.release); transaction.environment.clone_from(&opts.environment); transaction.sdk = Some(std::borrow::Cow::Owned(client.sdk_info.clone())); + transaction.server_name.clone_from(&opts.server_name); drop(inner); diff --git a/sentry-types/src/protocol/v7.rs b/sentry-types/src/protocol/v7.rs index a2fc3a880..2aa3e0e14 100644 --- a/sentry-types/src/protocol/v7.rs +++ b/sentry-types/src/protocol/v7.rs @@ -1989,6 +1989,9 @@ pub struct Transaction<'a> { /// Optionally HTTP request data to be sent along. #[serde(default, skip_serializing_if = "Option::is_none")] pub request: Option, + /// Optionally the server (or device) name of this event. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub server_name: Option>, } impl<'a> Default for Transaction<'a> { @@ -2008,6 +2011,7 @@ impl<'a> Default for Transaction<'a> { spans: Default::default(), contexts: Default::default(), request: Default::default(), + server_name: Default::default(), } } } @@ -2035,6 +2039,7 @@ impl<'a> Transaction<'a> { spans: self.spans, contexts: self.contexts, request: self.request, + server_name: self.server_name.map(|x| Cow::Owned(x.into_owned())), } } From 2fe26e092fb6e77ee643e9140b1a4bd22a13c6a3 Mon Sep 17 00:00:00 2001 From: Mads Hougesen Date: Mon, 14 Oct 2024 10:07:13 +0200 Subject: [PATCH 023/148] fix: typos in documentation (#697) --- sentry-core/src/hub_impl.rs | 2 +- sentry-core/src/performance.rs | 2 +- sentry-core/src/scope/real.rs | 2 +- sentry-types/README.md | 4 ++-- sentry-types/src/lib.rs | 2 +- sentry-types/src/protocol/session.rs | 10 +++++----- sentry-types/src/protocol/v7.rs | 4 ++-- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/sentry-core/src/hub_impl.rs b/sentry-core/src/hub_impl.rs index 76a91c3d9..1a2de2cd2 100644 --- a/sentry-core/src/hub_impl.rs +++ b/sentry-core/src/hub_impl.rs @@ -162,7 +162,7 @@ impl Hub { /// will return the provided hub. /// /// Once the function is finished executing, including after it - /// paniced, the original hub is re-installed if one was present. + /// panicked, the original hub is re-installed if one was present. pub fn run R, R>(hub: Arc, f: F) -> R { let _guard = SwitchGuard::new(hub); f() diff --git a/sentry-core/src/performance.rs b/sentry-core/src/performance.rs index a0046d304..08c339360 100644 --- a/sentry-core/src/performance.rs +++ b/sentry-core/src/performance.rs @@ -367,7 +367,7 @@ pub(crate) struct TransactionInner { type TransactionArc = Arc>; -/// Functional implementation of how a new transation's sample rate is chosen. +/// Functional implementation of how a new transaction's sample rate is chosen. /// /// Split out from `Client.is_transaction_sampled` for testing. #[cfg(feature = "client")] diff --git a/sentry-core/src/scope/real.rs b/sentry-core/src/scope/real.rs index f38ed52da..47dec48d1 100644 --- a/sentry-core/src/scope/real.rs +++ b/sentry-core/src/scope/real.rs @@ -134,7 +134,7 @@ impl Drop for ScopeGuard { stack.pop(); popped_depth }; - // NOTE: We need to drop the `stack` lock before panicing, as the + // NOTE: We need to drop the `stack` lock before panicking, as the // `PanicIntegration` will want to lock the `stack` itself // (through `capture_event` -> `HubImpl::with`), and would thus // result in a deadlock. diff --git a/sentry-types/README.md b/sentry-types/README.md index 556fd3b37..286b44d6f 100644 --- a/sentry-types/README.md +++ b/sentry-types/README.md @@ -7,7 +7,7 @@ # Sentry Rust SDK: sentry-types This crate provides common types for working with the Sentry protocol or the -Sentry server. It's used by the Sentry Relay infrastructure as well as the +Sentry server. It's used by the Sentry Relay infrastructure as well as the rust Sentry client. Most of the types in this crate are serializable in one form or another. @@ -26,7 +26,7 @@ so later versions might be added later. ### API Concepts Most types are directly serializable or deserializable and try to implement -the `Default` type. This means that objects can be created conviently +the `Default` type. This means that objects can be created conviently and missing attributes can be filled in: ```rust diff --git a/sentry-types/src/lib.rs b/sentry-types/src/lib.rs index 321e1088b..7f662ca9d 100644 --- a/sentry-types/src/lib.rs +++ b/sentry-types/src/lib.rs @@ -18,7 +18,7 @@ //! ## API Concepts //! //! Most types are directly serializable or deserializable and try to implement -//! the `Default` type. This means that objects can be created conviently +//! the `Default` type. This means that objects can be created conveniently //! and missing attributes can be filled in: //! //! ```rust diff --git a/sentry-types/src/protocol/session.rs b/sentry-types/src/protocol/session.rs index f0feffff5..43ea9fc3e 100644 --- a/sentry-types/src/protocol/session.rs +++ b/sentry-types/src/protocol/session.rs @@ -127,7 +127,7 @@ pub struct SessionUpdate<'a> { #[serde(default)] pub status: SessionStatus, - /// The number of errors that ocurred. + /// The number of errors that occurred. #[serde(default)] pub errors: u64, @@ -150,16 +150,16 @@ pub struct SessionAggregateItem { /// The distinct identifier. #[serde(rename = "did", default, skip_serializing_if = "Option::is_none")] pub distinct_id: Option, - /// The number of exited sessions that ocurred. + /// The number of exited sessions that occurred. #[serde(default, skip_serializing_if = "is_zero")] pub exited: u32, - /// The number of errored sessions that ocurred, not including the abnormal and crashed ones. + /// The number of errored sessions that occurred, not including the abnormal and crashed ones. #[serde(default, skip_serializing_if = "is_zero")] pub errored: u32, - /// The number of abnormal sessions that ocurred. + /// The number of abnormal sessions that occurred. #[serde(default, skip_serializing_if = "is_zero")] pub abnormal: u32, - /// The number of crashed sessions that ocurred. + /// The number of crashed sessions that occurred. #[serde(default, skip_serializing_if = "is_zero")] pub crashed: u32, } diff --git a/sentry-types/src/protocol/v7.rs b/sentry-types/src/protocol/v7.rs index 2aa3e0e14..a2f228000 100644 --- a/sentry-types/src/protocol/v7.rs +++ b/sentry-types/src/protocol/v7.rs @@ -782,7 +782,7 @@ impl Default for Breadcrumb { /// An IP address, either IPv4, IPv6 or Auto. #[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash, Default)] pub enum IpAddress { - /// The IP address needs to be infered from the user's context. + /// The IP address needs to be inferred from the user's context. #[default] Auto, /// The exact given IP address (v4 or v6). @@ -1595,7 +1595,7 @@ pub struct Event<'a> { /// A release identifier. #[serde(default, skip_serializing_if = "Option::is_none")] pub release: Option>, - /// An optional distribution identifer. + /// An optional distribution identifier. #[serde(default, skip_serializing_if = "Option::is_none")] pub dist: Option>, /// An optional environment identifier. From 91de70310d80381fd2e7c9b091427ccb834a3674 Mon Sep 17 00:00:00 2001 From: qdrs Date: Mon, 14 Oct 2024 17:29:12 +0800 Subject: [PATCH 024/148] Bump rustls to 0.23.13 (#692) * Bump rustls to 0.23.13 * Update Cargo.toml * fix rustls dependency issue --------- Co-authored-by: Francesco Vigliaturo --- Cargo.lock | 178 +++++++++++++++++++++++++++++++++++----------- sentry/Cargo.toml | 6 +- 2 files changed, 139 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 22b88bc9a..f1c1a660e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,7 +65,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote", - "syn 2.0.66", + "syn 2.0.79", ] [[package]] @@ -181,7 +181,7 @@ dependencies = [ "actix-router", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.79", ] [[package]] @@ -544,7 +544,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.79", ] [[package]] @@ -561,7 +561,7 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.79", ] [[package]] @@ -576,6 +576,33 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +[[package]] +name = "aws-lc-rs" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f95446d919226d587817a7d21379e6eb099b97b45110a7f272a444ca5c54070" +dependencies = [ + "aws-lc-sys", + "mirai-annotations", + "paste", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3ddc4a5b231dd6958b140ff3151b6412b3f4321fab354f399eec8f14b06df62" +dependencies = [ + "bindgen 0.69.4", + "cc", + "cmake", + "dunce", + "fs_extra", + "libc", + "paste", +] + [[package]] name = "axum" version = "0.7.5" @@ -678,6 +705,29 @@ dependencies = [ "which", ] +[[package]] +name = "bindgen" +version = "0.69.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" +dependencies = [ + "bitflags 2.5.0", + "cexpr", + "clang-sys", + "itertools 0.12.1", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.79", + "which", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -762,7 +812,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.79", ] [[package]] @@ -847,13 +897,13 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.98" +version = "1.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" +checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938" dependencies = [ "jobserver", "libc", - "once_cell", + "shlex", ] [[package]] @@ -1264,7 +1314,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.79", ] [[package]] @@ -1275,7 +1325,7 @@ checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" dependencies = [ "darling_core", "quote", - "syn 2.0.66", + "syn 2.0.79", ] [[package]] @@ -1335,7 +1385,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.79", ] [[package]] @@ -1394,6 +1444,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "either" version = "1.12.0" @@ -1504,7 +1560,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4caa4f198bb9152a55c0103efb83fa4edfcbb8625f4c9e94ae8ec8e23827c563" dependencies = [ "anyhow", - "bindgen", + "bindgen 0.63.0", "bitflags 1.3.2", "cmake", "filetime", @@ -1549,7 +1605,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.79", ] [[package]] @@ -1648,7 +1704,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e148f97c04ed3e9181a08bcdc9560a515aad939b0ba7f50a0022e294665e0af" dependencies = [ "anyhow", - "bindgen", + "bindgen 0.63.0", "build-time", "cargo_metadata", "const_format", @@ -1813,6 +1869,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "futures" version = "0.3.30" @@ -1897,7 +1959,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.79", ] [[package]] @@ -2299,7 +2361,7 @@ dependencies = [ "http 1.1.0", "hyper", "hyper-util", - "rustls", + "rustls 0.22.4", "rustls-pki-types", "tokio", "tokio-rustls", @@ -2721,6 +2783,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "mirai-annotations" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9be0862c1b3f26a88803c4a49de6889c10e608b3ee9344e6ef5b45fb37ad3d1" + [[package]] name = "native-tls" version = "0.2.12" @@ -2856,7 +2924,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.79", ] [[package]] @@ -2909,7 +2977,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.79", ] [[package]] @@ -3011,7 +3079,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.79", ] [[package]] @@ -3135,6 +3203,16 @@ dependencies = [ "log", ] +[[package]] +name = "prettyplease" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" +dependencies = [ + "proc-macro2", + "syn 2.0.79", +] + [[package]] name = "proc-macro-crate" version = "3.1.0" @@ -3212,7 +3290,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.79", ] [[package]] @@ -3416,7 +3494,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls", + "rustls 0.22.4", "rustls-pemfile", "rustls-pki-types", "serde", @@ -3475,7 +3553,7 @@ dependencies = [ "regex", "relative-path", "rustc_version 0.4.0", - "syn 2.0.66", + "syn 2.0.79", "unicode-ident", ] @@ -3550,6 +3628,22 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls" +version = "0.23.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "415d9944693cb90382053259f89fbb077ea730ad7273047ec63b19bc9b160ba8" +dependencies = [ + "aws-lc-rs", + "log", + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + [[package]] name = "rustls-pemfile" version = "2.1.2" @@ -3562,16 +3656,17 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.7.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" +checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55" [[package]] name = "rustls-webpki" -version = "0.102.4" +version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", @@ -3676,7 +3771,7 @@ dependencies = [ "native-tls", "pretty_env_logger", "reqwest", - "rustls", + "rustls 0.23.14", "sentry-anyhow", "sentry-backtrace", "sentry-contexts", @@ -3873,7 +3968,7 @@ checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.79", ] [[package]] @@ -4154,7 +4249,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.66", + "syn 2.0.79", ] [[package]] @@ -4198,9 +4293,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.66" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", @@ -4257,7 +4352,7 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.79", ] [[package]] @@ -4391,7 +4486,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.79", ] [[package]] @@ -4410,7 +4505,7 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" dependencies = [ - "rustls", + "rustls 0.22.4", "rustls-pki-types", "tokio", ] @@ -4538,7 +4633,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.79", ] [[package]] @@ -4670,17 +4765,16 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "2.9.7" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d11a831e3c0b56e438a28308e7c810799e3c118417f342d30ecec080105395cd" +checksum = "b74fc6b57825be3373f7054754755f03ac3a8f5d70015ccad699ba2029956f4a" dependencies = [ "base64 0.22.1", "log", "native-tls", "once_cell", - "rustls", + "rustls 0.23.14", "rustls-pki-types", - "rustls-webpki", "url", "webpki-roots", ] @@ -4795,7 +4889,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.79", "wasm-bindgen-shared", ] @@ -4829,7 +4923,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.79", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -5162,7 +5256,7 @@ checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.79", ] [[package]] diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index 2ee7c8288..97222b840 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -78,9 +78,9 @@ http-client = { version = "6.5.3", optional = true } isahc = { version = "0.9.14", optional = true } serde_json = { version = "1.0.48", optional = true } tokio = { version = "1.0", features = ["rt"], optional = true } -ureq = { version = "2.7.0", optional = true, default-features = false } +ureq = { version = "2.10.1", optional = true, default-features = false } native-tls = { version = "0.2.8", optional = true } -rustls = { version = "0.22.4", optional = true } +rustls = { version = "0.23.13", optional = true } webpki-roots = { version = "0.26.1", optional = true } embedded-svc = { version = "0.27.1", optional = true } [target.'cfg(target_os = "espidf")'.dependencies] @@ -103,4 +103,4 @@ tracing = { version = "0.1" } tracing-subscriber = { version = "0.3", features = ["fmt", "tracing-log"] } [lints.rust] -unexpected_cfgs = { level = "warn", check-cfg = ['cfg(doc_cfg)'] } \ No newline at end of file +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(doc_cfg)'] } From a1481d42ae7a9a1f3f396d6948b0e61354a20ba4 Mon Sep 17 00:00:00 2001 From: Andres Date: Thu, 24 Oct 2024 08:47:32 -0700 Subject: [PATCH 025/148] allow custom tags on transactions (#699) currently the only tags added to transactions are on the scope at the time of finish, but sometimes it is useful to have tags that aren't for the scope but just for the transaction --- sentry-core/src/performance.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/sentry-core/src/performance.rs b/sentry-core/src/performance.rs index 08c339360..5f3a9a460 100644 --- a/sentry-core/src/performance.rs +++ b/sentry-core/src/performance.rs @@ -260,6 +260,14 @@ impl TransactionOrSpan { } } + /// Sets a tag to a specific value. + pub fn set_tag(&self, key: &str, value: V) { + match self { + TransactionOrSpan::Transaction(transaction) => transaction.set_tag(key, value), + TransactionOrSpan::Span(span) => span.set_tag(key, value), + } + } + /// Get the TransactionContext of the Transaction/Span. /// /// Note that this clones the underlying value. @@ -492,6 +500,14 @@ impl Transaction { } } + /// Sets a tag to a specific value. + pub fn set_tag(&self, key: &str, value: V) { + let mut inner = self.inner.lock().unwrap(); + if let Some(transaction) = inner.transaction.as_mut() { + transaction.tags.insert(key.into(), value.to_string()); + } + } + /// Returns an iterating accessor to the transaction's /// [`extra` field](protocol::Transaction::extra). /// @@ -645,6 +661,12 @@ impl Span { span.data.insert(key.into(), value); } + /// Sets a tag to a specific value. + pub fn set_tag(&self, key: &str, value: V) { + let mut span = self.span.lock().unwrap(); + span.tags.insert(key.into(), value.to_string()); + } + /// Returns a smart pointer to the span's [`data` field](protocol::Span::data). /// /// Since [`Data`] implements `Deref` and `DerefMut`, this can be used to read and mutate From d3e2ca074555f1971feed1222ebc743c53d23f10 Mon Sep 17 00:00:00 2001 From: Douman Date: Tue, 29 Oct 2024 19:29:03 +0900 Subject: [PATCH 026/148] Implement record of tagged span data in tracing integration (#696) --- sentry-core/src/performance.rs | 27 +++++++++++++++ sentry-tracing/src/converters.rs | 3 +- sentry-tracing/src/layer.rs | 57 ++++++++++++++++++++++++++++---- sentry-tracing/src/lib.rs | 2 ++ 4 files changed, 82 insertions(+), 7 deletions(-) diff --git a/sentry-core/src/performance.rs b/sentry-core/src/performance.rs index 5f3a9a460..59cca2a57 100644 --- a/sentry-core/src/performance.rs +++ b/sentry-core/src/performance.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use std::collections::BTreeMap; use std::ops::{Deref, DerefMut}; use std::sync::{Arc, Mutex, MutexGuard}; @@ -433,6 +434,20 @@ impl<'a> TransactionData<'a> { Box::new(std::iter::empty()) } } + + /// Set some extra information to be sent with this Transaction. + pub fn set_data(&mut self, key: Cow<'a, str>, value: protocol::Value) { + if let Some(transaction) = self.0.transaction.as_mut() { + transaction.extra.insert(key.into(), value); + } + } + + /// Set some extra information to be sent with this Transaction. + pub fn set_tag(&mut self, key: Cow<'_, str>, value: String) { + if let Some(transaction) = self.0.transaction.as_mut() { + transaction.tags.insert(key.into(), value); + } + } } impl Transaction { @@ -627,6 +642,18 @@ impl Transaction { /// A smart pointer to a span's [`data` field](protocol::Span::data). pub struct Data<'a>(MutexGuard<'a, protocol::Span>); +impl<'a> Data<'a> { + /// Set some extra information to be sent with this Span. + pub fn set_data(&mut self, key: String, value: protocol::Value) { + self.0.data.insert(key, value); + } + + /// Set some tag to be sent with this Span. + pub fn set_tag(&mut self, key: String, value: String) { + self.0.tags.insert(key, value); + } +} + impl<'a> Deref for Data<'a> { type Target = BTreeMap; diff --git a/sentry-tracing/src/converters.rs b/sentry-tracing/src/converters.rs index 08f329098..c71143be2 100644 --- a/sentry-tracing/src/converters.rs +++ b/sentry-tracing/src/converters.rs @@ -9,6 +9,7 @@ use tracing_subscriber::layer::Context; use tracing_subscriber::registry::LookupSpan; use super::layer::SentrySpanData; +use crate::TAGS_PREFIX; /// Converts a [`tracing_core::Level`] to a Sentry [`Level`] fn convert_tracing_level(level: &tracing_core::Level) -> Level { @@ -156,7 +157,7 @@ fn tags_from_event(fields: &mut BTreeMap) -> BTreeMap + Into>>( + span: &TransactionOrSpan, + data: BTreeMap, +) { + match span { + TransactionOrSpan::Span(span) => { + let mut span = span.data(); + for (key, value) in data { + if let Some(stripped_key) = key.as_ref().strip_prefix(TAGS_PREFIX) { + match value { + Value::Bool(value) => { + span.set_tag(stripped_key.to_owned(), value.to_string()) + } + Value::Number(value) => { + span.set_tag(stripped_key.to_owned(), value.to_string()) + } + Value::String(value) => span.set_tag(stripped_key.to_owned(), value), + _ => span.set_data(key.into().into_owned(), value), + } + } else { + span.set_data(key.into().into_owned(), value); + } + } + } + TransactionOrSpan::Transaction(transaction) => { + let mut transaction = transaction.data(); + for (key, value) in data { + if let Some(stripped_key) = key.as_ref().strip_prefix(TAGS_PREFIX) { + match value { + Value::Bool(value) => { + transaction.set_tag(stripped_key.into(), value.to_string()) + } + Value::Number(value) => { + transaction.set_tag(stripped_key.into(), value.to_string()) + } + Value::String(value) => transaction.set_tag(stripped_key.into(), value), + _ => transaction.set_data(key.into(), value), + } + } else { + transaction.set_data(key.into(), value); + } + } + } + } +} + /// Data that is attached to the tracing Spans `extensions`, in order to /// `finish` the corresponding sentry span `on_close`, and re-set its parent as /// the *current* span. @@ -217,9 +266,7 @@ where }; // Add the data from the original span to the sentry span. // This comes from typically the `fields` in `tracing::instrument`. - for (key, value) in data { - sentry_span.set_data(key, value); - } + record_fields(&sentry_span, data); sentry_core::configure_scope(|scope| scope.set_span(Some(sentry_span.clone()))); @@ -267,9 +314,7 @@ where let mut data = FieldVisitor::default(); values.record(&mut data); - for (key, value) in data.json_values { - span.set_data(&key, value); - } + record_fields(span, data.json_values); } } diff --git a/sentry-tracing/src/lib.rs b/sentry-tracing/src/lib.rs index 4f99a12f4..4defd941d 100644 --- a/sentry-tracing/src/lib.rs +++ b/sentry-tracing/src/lib.rs @@ -145,3 +145,5 @@ mod layer; pub use converters::*; pub use layer::*; + +const TAGS_PREFIX: &str = "tags."; From 1b65b5c99af975496880e7325218479e0037d097 Mon Sep 17 00:00:00 2001 From: Philip Jenvey Date: Tue, 29 Oct 2024 03:29:15 -0700 Subject: [PATCH 027/148] fix: Don't block on sending envelopes (ureq/curl transports) (#701) --- CHANGELOG.md | 6 ++++++ sentry/src/transports/thread.rs | 7 ++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c7eb16a0..6762dec3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +**Fixes**: + +- Envelopes will be discarded rather than blocking if the transport channel fills up (previously fixed in async-capable transports, now applied to the curl/ureq transports). ([#701](https://github.com/getsentry/sentry-rust/pull/701)) + ## 0.34.0 **Features**: diff --git a/sentry/src/transports/thread.rs b/sentry/src/transports/thread.rs index 80d0e1201..7f45990ff 100644 --- a/sentry/src/transports/thread.rs +++ b/sentry/src/transports/thread.rs @@ -74,7 +74,12 @@ impl TransportThread { } pub fn send(&self, envelope: Envelope) { - let _ = self.sender.send(Task::SendEnvelope(envelope)); + // Using send here would mean that when the channel fills up for whatever + // reason, trying to send an envelope would block everything. We'd rather + // drop the envelope in that case. + if let Err(e) = self.sender.try_send(Task::SendEnvelope(envelope)) { + sentry_debug!("envelope dropped: {e}"); + } } pub fn flush(&self, timeout: Duration) -> bool { From 9b82c90505763b253864e937aa6f6f0abae712a9 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 28 Nov 2024 09:01:14 +0000 Subject: [PATCH 028/148] Allow deprecate `PanicInfo` (#711) --- sentry-panic/src/lib.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sentry-panic/src/lib.rs b/sentry-panic/src/lib.rs index 4c00cab1a..87030b3ac 100644 --- a/sentry-panic/src/lib.rs +++ b/sentry-panic/src/lib.rs @@ -19,6 +19,7 @@ #![warn(missing_docs)] #![deny(unsafe_code)] +#[allow(deprecated)] // `PanicHookInfo` is only available in Rust 1.81+. use std::panic::{self, PanicInfo}; use std::sync::Once; @@ -31,6 +32,7 @@ use sentry_core::{ClientOptions, Integration}; /// This panic handler reports panics to Sentry. It also attempts to prevent /// double faults in some cases where it's known to be unsafe to invoke the /// Sentry panic handler. +#[allow(deprecated)] // `PanicHookInfo` is only available in Rust 1.81+. pub fn panic_handler(info: &PanicInfo<'_>) { sentry_core::with_integration(|integration: &PanicIntegration, hub| { hub.capture_event(integration.event_from_panic_info(info)); @@ -40,6 +42,7 @@ pub fn panic_handler(info: &PanicInfo<'_>) { }); } +#[allow(deprecated)] // `PanicHookInfo` is only available in Rust 1.81+. type PanicExtractor = dyn Fn(&PanicInfo<'_>) -> Option> + Send + Sync; /// The Sentry Panic handler Integration. @@ -75,6 +78,7 @@ impl Integration for PanicIntegration { } /// Extract the message of a panic. +#[allow(deprecated)] // `PanicHookInfo` is only available in Rust 1.81+. pub fn message_from_panic_info<'a>(info: &'a PanicInfo<'_>) -> &'a str { match info.payload().downcast_ref::<&'static str>() { Some(s) => s, @@ -93,6 +97,7 @@ impl PanicIntegration { /// Registers a new extractor. #[must_use] + #[allow(deprecated)] // `PanicHookInfo` is only available in Rust 1.81+. pub fn add_extractor(mut self, f: F) -> Self where F: Fn(&PanicInfo<'_>) -> Option> + Send + Sync + 'static, @@ -104,6 +109,7 @@ impl PanicIntegration { /// Creates an event from the given panic info. /// /// The stacktrace is calculated from the current frame. + #[allow(deprecated)] // `PanicHookInfo` is only available in Rust 1.81+. pub fn event_from_panic_info(&self, info: &PanicInfo<'_>) -> Event<'static> { for extractor in &self.extractors { if let Some(event) = extractor(info) { From b70f4c76357c5a9ff9cebdec493e30de88161b0f Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 28 Nov 2024 09:12:01 +0000 Subject: [PATCH 029/148] Disable rustls features by default (#709) --- Cargo.lock | 84 ++--------------------------------------------- sentry/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 83 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f1c1a660e..63f9668ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -576,33 +576,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" -[[package]] -name = "aws-lc-rs" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f95446d919226d587817a7d21379e6eb099b97b45110a7f272a444ca5c54070" -dependencies = [ - "aws-lc-sys", - "mirai-annotations", - "paste", - "zeroize", -] - -[[package]] -name = "aws-lc-sys" -version = "0.21.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3ddc4a5b231dd6958b140ff3151b6412b3f4321fab354f399eec8f14b06df62" -dependencies = [ - "bindgen 0.69.4", - "cc", - "cmake", - "dunce", - "fs_extra", - "libc", - "paste", -] - [[package]] name = "axum" version = "0.7.5" @@ -705,29 +678,6 @@ dependencies = [ "which", ] -[[package]] -name = "bindgen" -version = "0.69.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" -dependencies = [ - "bitflags 2.5.0", - "cexpr", - "clang-sys", - "itertools 0.12.1", - "lazy_static", - "lazycell", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn 2.0.79", - "which", -] - [[package]] name = "bitflags" version = "1.3.2" @@ -1444,12 +1394,6 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" -[[package]] -name = "dunce" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" - [[package]] name = "either" version = "1.12.0" @@ -1560,7 +1504,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4caa4f198bb9152a55c0103efb83fa4edfcbb8625f4c9e94ae8ec8e23827c563" dependencies = [ "anyhow", - "bindgen 0.63.0", + "bindgen", "bitflags 1.3.2", "cmake", "filetime", @@ -1704,7 +1648,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e148f97c04ed3e9181a08bcdc9560a515aad939b0ba7f50a0022e294665e0af" dependencies = [ "anyhow", - "bindgen 0.63.0", + "bindgen", "build-time", "cargo_metadata", "const_format", @@ -1869,12 +1813,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "fs_extra" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" - [[package]] name = "futures" version = "0.3.30" @@ -2783,12 +2721,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "mirai-annotations" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9be0862c1b3f26a88803c4a49de6889c10e608b3ee9344e6ef5b45fb37ad3d1" - [[package]] name = "native-tls" version = "0.2.12" @@ -3203,16 +3135,6 @@ dependencies = [ "log", ] -[[package]] -name = "prettyplease" -version = "0.2.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" -dependencies = [ - "proc-macro2", - "syn 2.0.79", -] - [[package]] name = "proc-macro-crate" version = "3.1.0" @@ -3634,7 +3556,6 @@ version = "0.23.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "415d9944693cb90382053259f89fbb077ea730ad7273047ec63b19bc9b160ba8" dependencies = [ - "aws-lc-rs", "log", "once_cell", "ring", @@ -3666,7 +3587,6 @@ version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ - "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index 97222b840..6adb38055 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -80,7 +80,7 @@ serde_json = { version = "1.0.48", optional = true } tokio = { version = "1.0", features = ["rt"], optional = true } ureq = { version = "2.10.1", optional = true, default-features = false } native-tls = { version = "0.2.8", optional = true } -rustls = { version = "0.23.13", optional = true } +rustls = { version = "0.23.13", optional = true, default-features = false } webpki-roots = { version = "0.26.1", optional = true } embedded-svc = { version = "0.27.1", optional = true } [target.'cfg(target_os = "espidf")'.dependencies] From 605d36d7f3ec8e42bbee30fae202f80b724a7b29 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Nov 2024 10:32:16 +0100 Subject: [PATCH 030/148] build(deps): bump rustls from 0.23.14 to 0.23.18 (#710) Bumps [rustls](https://github.com/rustls/rustls) from 0.23.14 to 0.23.18. - [Release notes](https://github.com/rustls/rustls/releases) - [Changelog](https://github.com/rustls/rustls/blob/main/CHANGELOG.md) - [Commits](https://github.com/rustls/rustls/compare/v/0.23.14...v/0.23.18) --- updated-dependencies: - dependency-name: rustls dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 12 ++++++------ sentry/Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 63f9668ee..388e3d46b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3552,9 +3552,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.14" +version = "0.23.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "415d9944693cb90382053259f89fbb077ea730ad7273047ec63b19bc9b160ba8" +checksum = "9c9cc1d47e243d655ace55ed38201c19ae02c148ae56412ab8750e8f0166ab7f" dependencies = [ "log", "once_cell", @@ -3577,9 +3577,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55" +checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" [[package]] name = "rustls-webpki" @@ -3691,7 +3691,7 @@ dependencies = [ "native-tls", "pretty_env_logger", "reqwest", - "rustls 0.23.14", + "rustls 0.23.18", "sentry-anyhow", "sentry-backtrace", "sentry-contexts", @@ -4693,7 +4693,7 @@ dependencies = [ "log", "native-tls", "once_cell", - "rustls 0.23.14", + "rustls 0.23.18", "rustls-pki-types", "url", "webpki-roots", diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index 6adb38055..a6bc24a9e 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -80,7 +80,7 @@ serde_json = { version = "1.0.48", optional = true } tokio = { version = "1.0", features = ["rt"], optional = true } ureq = { version = "2.10.1", optional = true, default-features = false } native-tls = { version = "0.2.8", optional = true } -rustls = { version = "0.23.13", optional = true, default-features = false } +rustls = { version = "0.23.18", optional = true, default-features = false } webpki-roots = { version = "0.26.1", optional = true } embedded-svc = { version = "0.27.1", optional = true } [target.'cfg(target_os = "espidf")'.dependencies] From 00cb40faa5a31d16e033e257c0d482be256923f0 Mon Sep 17 00:00:00 2001 From: Douman Date: Fri, 29 Nov 2024 17:03:56 +0900 Subject: [PATCH 031/148] Add basic test for tracing layer (#703) --- sentry-tracing/tests/tracing.rs | 76 +++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 sentry-tracing/tests/tracing.rs diff --git a/sentry-tracing/tests/tracing.rs b/sentry-tracing/tests/tracing.rs new file mode 100644 index 000000000..c77183c32 --- /dev/null +++ b/sentry-tracing/tests/tracing.rs @@ -0,0 +1,76 @@ +use sentry::{ClientOptions, Hub}; +use sentry_core::test::TestTransport; + +use std::sync::Arc; + +fn init_sentry() -> Arc { + use tracing_subscriber::prelude::*; + + let transport = TestTransport::new(); + let options = ClientOptions { + dsn: Some("https://test@sentry-tracing.com/test".parse().unwrap()), + transport: Some(Arc::new(transport.clone())), + sample_rate: 1.0, + traces_sample_rate: 1.0, + ..ClientOptions::default() + }; + Hub::current().bind_client(Some(Arc::new(options.into()))); + + let _ = tracing_subscriber::registry() + .with(sentry_tracing::layer().enable_span_attributes()) + .try_init(); + + transport +} + +#[tracing::instrument(fields(tags.tag = "key", not_tag = "value"))] +fn function_with_tags(value: i32) { + tracing::error!(value, "event"); +} + +#[test] +fn should_instrument_function_with_event() { + let transport = init_sentry(); + + function_with_tags(1); + + let data = transport.fetch_and_clear_envelopes(); + assert_eq!(data.len(), 2); + let event = data.first().expect("should have 1 event"); + let event = match event.items().next().unwrap() { + sentry::protocol::EnvelopeItem::Event(event) => event, + unexpected => panic!("Expected event, but got {:#?}", unexpected), + }; + + //Validate transaction is created + let trace = match event.contexts.get("trace").expect("to get 'trace' context") { + sentry::protocol::Context::Trace(trace) => trace, + unexpected => panic!("Expected trace context but got {:?}", unexpected), + }; + assert_eq!(trace.op.as_deref().unwrap(), "function_with_tags"); + + //Confirm transaction values + let transaction = data.get(1).expect("should have 1 transaction"); + let transaction = match transaction.items().next().unwrap() { + sentry::protocol::EnvelopeItem::Transaction(transaction) => transaction, + unexpected => panic!("Expected transaction, but got {:#?}", unexpected), + }; + assert_eq!(transaction.tags.len(), 1); + assert_eq!(transaction.extra.len(), 2); + + let tag = transaction + .tags + .get("tag") + .expect("to have tag with name 'tag'"); + assert_eq!(tag, "key"); + let not_tag = transaction + .extra + .get("not_tag") + .expect("to have extra with name 'not_tag'"); + assert_eq!(not_tag, "value"); + let value = transaction + .extra + .get("value") + .expect("to have extra with name 'value'"); + assert_eq!(value, 1); +} From 180a6b1c09b5857ee7363c3f800aa19071cdec6d Mon Sep 17 00:00:00 2001 From: Luiz Carvalho Date: Fri, 29 Nov 2024 05:07:29 -0300 Subject: [PATCH 032/148] fix(sentry-tracing): switch sentry spans on enter and exit (#686) --------- Co-authored-by: DoumanAsh --- sentry-core/src/hub_impl.rs | 9 ++++-- sentry-core/src/lib.rs | 3 +- sentry-core/src/performance.rs | 6 ++++ sentry-tracing/src/layer.rs | 50 ++++++++++++++++++++++++++++------ 4 files changed, 57 insertions(+), 11 deletions(-) diff --git a/sentry-core/src/hub_impl.rs b/sentry-core/src/hub_impl.rs index 1a2de2cd2..59c91bf97 100644 --- a/sentry-core/src/hub_impl.rs +++ b/sentry-core/src/hub_impl.rs @@ -21,12 +21,17 @@ thread_local! { ); } -pub(crate) struct SwitchGuard { +/// A Hub switch guard used to temporarily swap +/// active hub in thread local storage. +pub struct SwitchGuard { inner: Option<(Arc, bool)>, } impl SwitchGuard { - pub(crate) fn new(mut hub: Arc) -> Self { + /// Swaps the current thread's Hub by the one provided + /// and returns a guard that, when dropped, replaces it + /// to the previous one. + pub fn new(mut hub: Arc) -> Self { let inner = THREAD_HUB.with(|(thread_hub, is_process_hub)| { // SAFETY: `thread_hub` will always be a valid thread local hub, // by definition not shared between threads. diff --git a/sentry-core/src/lib.rs b/sentry-core/src/lib.rs index 1f7d8c31e..5cc39cd54 100644 --- a/sentry-core/src/lib.rs +++ b/sentry-core/src/lib.rs @@ -149,8 +149,9 @@ pub mod metrics; mod session; #[cfg(all(feature = "client", feature = "metrics"))] mod units; + #[cfg(feature = "client")] -pub use crate::client::Client; +pub use crate::{client::Client, hub_impl::SwitchGuard as HubSwitchGuard}; // test utilities #[cfg(feature = "test")] diff --git a/sentry-core/src/performance.rs b/sentry-core/src/performance.rs index 59cca2a57..140d31207 100644 --- a/sentry-core/src/performance.rs +++ b/sentry-core/src/performance.rs @@ -717,6 +717,12 @@ impl Span { transaction.context.clone() } + /// Get the current span ID. + pub fn get_span_id(&self) -> protocol::SpanId { + let span = self.span.lock().unwrap(); + span.span_id + } + /// Get the status of the Span. pub fn get_status(&self) -> Option { let span = self.span.lock().unwrap(); diff --git a/sentry-tracing/src/layer.rs b/sentry-tracing/src/layer.rs index 01930f808..0540fe764 100644 --- a/sentry-tracing/src/layer.rs +++ b/sentry-tracing/src/layer.rs @@ -1,6 +1,7 @@ use std::borrow::Cow; use std::cell::RefCell; use std::collections::BTreeMap; +use std::sync::Arc; use sentry_core::protocol::Value; use sentry_core::{Breadcrumb, TransactionOrSpan}; @@ -197,6 +198,8 @@ fn record_fields<'a, K: AsRef + Into>>( pub(super) struct SentrySpanData { pub(super) sentry_span: TransactionOrSpan, parent_sentry_span: Option, + hub: Arc, + hub_switch_guard: Option, } impl Layer for SentryLayer @@ -256,7 +259,9 @@ where } }); - let parent_sentry_span = sentry_core::configure_scope(|s| s.get_span()); + let hub = sentry_core::Hub::current(); + let parent_sentry_span = hub.configure_scope(|scope| scope.get_span()); + let sentry_span: sentry_core::TransactionOrSpan = match &parent_sentry_span { Some(parent) => parent.start_child(op, &description).into(), None => { @@ -268,15 +273,48 @@ where // This comes from typically the `fields` in `tracing::instrument`. record_fields(&sentry_span, data); - sentry_core::configure_scope(|scope| scope.set_span(Some(sentry_span.clone()))); - let mut extensions = span.extensions_mut(); extensions.insert(SentrySpanData { sentry_span, parent_sentry_span, + hub, + hub_switch_guard: None, }); } + /// Sets entered span as *current* sentry span. A tracing span can be + /// entered and existed multiple times, for example, when using a `tracing::Instrumented` future. + fn on_enter(&self, id: &span::Id, ctx: Context<'_, S>) { + let span = match ctx.span(id) { + Some(span) => span, + None => return, + }; + + let mut extensions = span.extensions_mut(); + if let Some(data) = extensions.get_mut::() { + data.hub_switch_guard = Some(sentry_core::HubSwitchGuard::new(data.hub.clone())); + data.hub.configure_scope(|scope| { + scope.set_span(Some(data.sentry_span.clone())); + }) + } + } + + /// Set exited span's parent as *current* sentry span. + fn on_exit(&self, id: &span::Id, ctx: Context<'_, S>) { + let span = match ctx.span(id) { + Some(span) => span, + None => return, + }; + + let mut extensions = span.extensions_mut(); + if let Some(data) = extensions.get_mut::() { + data.hub.configure_scope(|scope| { + scope.set_span(data.parent_sentry_span.clone()); + }); + data.hub_switch_guard.take(); + } + } + /// When a span gets closed, finish the underlying sentry span, and set back /// its parent as the *current* sentry span. fn on_close(&self, id: span::Id, ctx: Context<'_, S>) { @@ -286,16 +324,12 @@ where }; let mut extensions = span.extensions_mut(); - let SentrySpanData { - sentry_span, - parent_sentry_span, - } = match extensions.remove::() { + let SentrySpanData { sentry_span, .. } = match extensions.remove::() { Some(data) => data, None => return, }; sentry_span.finish(); - sentry_core::configure_scope(|scope| scope.set_span(parent_sentry_span)); } /// Implement the writing of extra data to span From 05fc7de25ed545bb5ff9348f586eb6ef0d535bc3 Mon Sep 17 00:00:00 2001 From: Luiz Carvalho Date: Fri, 29 Nov 2024 05:09:26 -0300 Subject: [PATCH 033/148] feat(sentry-core): add support for w3c traceparent (#687) --- sentry-core/src/performance.rs | 155 ++++++++++++++++++++++++++++++++- 1 file changed, 151 insertions(+), 4 deletions(-) diff --git a/sentry-core/src/performance.rs b/sentry-core/src/performance.rs index 140d31207..3255f5db8 100644 --- a/sentry-core/src/performance.rs +++ b/sentry-core/src/performance.rs @@ -69,12 +69,15 @@ pub struct TransactionContext { op: String, trace_id: protocol::TraceId, parent_span_id: Option, + span_id: protocol::SpanId, sampled: Option, custom: Option, } impl TransactionContext { - /// Creates a new Transaction Context with the given `name` and `op`. + /// Creates a new Transaction Context with the given `name` and `op`. A random + /// `trace_id` is assigned. Use [`TransactionContext::new_with_trace_id`] to + /// specify a custom trace ID. /// /// See /// for an explanation of a Transaction's `name`, and @@ -85,13 +88,33 @@ impl TransactionContext { /// can be used for distributed tracing. #[must_use = "this must be used with `start_transaction`"] pub fn new(name: &str, op: &str) -> Self { - Self::continue_from_headers(name, op, std::iter::empty()) + Self::new_with_trace_id(name, op, protocol::TraceId::default()) + } + + /// Creates a new Transaction Context with the given `name`, `op`, and `trace_id`. + /// + /// See + /// for an explanation of a Transaction's `name`, and + /// for conventions + /// around an `operation`'s value. + #[must_use = "this must be used with `start_transaction`"] + pub fn new_with_trace_id(name: &str, op: &str, trace_id: protocol::TraceId) -> Self { + Self { + name: name.into(), + op: op.into(), + trace_id, + parent_span_id: None, + span_id: Default::default(), + sampled: None, + custom: None, + } } /// Creates a new Transaction Context based on the distributed tracing `headers`. /// - /// The `headers` in particular need to include the `sentry-trace` header, - /// which is used to associate the transaction with a distributed trace. + /// The `headers` in particular need to include either the `sentry-trace` or W3C + /// `traceparent` header, which is used to associate the transaction with a distributed + /// trace. If both are present, `sentry-trace` takes precedence. #[must_use = "this must be used with `start_transaction`"] pub fn continue_from_headers<'a, I: IntoIterator>( name: &str, @@ -102,6 +125,11 @@ impl TransactionContext { for (k, v) in headers.into_iter() { if k.eq_ignore_ascii_case("sentry-trace") { trace = parse_sentry_trace(v); + break; + } + + if k.eq_ignore_ascii_case("traceparent") { + trace = parse_w3c_traceparent(v); } } @@ -115,6 +143,7 @@ impl TransactionContext { op: op.into(), trace_id, parent_span_id, + span_id: Default::default(), sampled, custom: None, } @@ -152,6 +181,7 @@ impl TransactionContext { op: op.into(), trace_id, parent_span_id: Some(parent_span_id), + span_id: protocol::SpanId::default(), sampled, custom: None, } @@ -185,6 +215,11 @@ impl TransactionContext { self.trace_id } + /// Get the Span ID of this Transaction. + pub fn span_id(&self) -> protocol::SpanId { + self.span_id + } + /// Get the custom context of this Transaction. pub fn custom(&self) -> Option<&CustomTransactionContext> { self.custom.as_ref() @@ -220,6 +255,80 @@ impl TransactionContext { std::mem::swap(&mut self.custom, &mut Some(custom)); existing_value } + + /// Creates a transaction context builder initialized with the given `name` and `op`. + /// + /// See + /// for an explanation of a Transaction's `name`, and + /// for conventions + /// around an `operation`'s value. + #[must_use] + pub fn builder(name: &str, op: &str) -> TransactionContextBuilder { + TransactionContextBuilder { + ctx: TransactionContext::new(name, op), + } + } +} + +/// A transaction context builder created by [`TransactionContext::builder`]. +pub struct TransactionContextBuilder { + ctx: TransactionContext, +} + +impl TransactionContextBuilder { + /// Defines the name of the transaction. + #[must_use] + pub fn with_name(mut self, name: String) -> Self { + self.ctx.name = name; + self + } + + /// Defines the operation of the transaction. + #[must_use] + pub fn with_op(mut self, op: String) -> Self { + self.ctx.op = op; + self + } + + /// Defines the trace ID. + #[must_use] + pub fn with_trace_id(mut self, trace_id: protocol::TraceId) -> Self { + self.ctx.trace_id = trace_id; + self + } + + /// Defines a parent span ID for the created transaction. + #[must_use] + pub fn with_parent_span_id(mut self, parent_span_id: Option) -> Self { + self.ctx.parent_span_id = parent_span_id; + self + } + + /// Defines the span ID to be used when creating the transaction. + #[must_use] + pub fn with_span_id(mut self, span_id: protocol::SpanId) -> Self { + self.ctx.span_id = span_id; + self + } + + /// Defines whether the transaction will be sampled. + #[must_use] + pub fn with_sampled(mut self, sampled: Option) -> Self { + self.ctx.sampled = sampled; + self + } + + /// Adds a custom key and value to the transaction context. + #[must_use] + pub fn with_custom(mut self, key: String, value: serde_json::Value) -> Self { + self.ctx.custom_insert(key, value); + self + } + + /// Finishes building a transaction. + pub fn finish(self) -> TransactionContext { + self.ctx + } } /// A function to be run for each new transaction, to determine the rate at which @@ -467,6 +576,7 @@ impl Transaction { let context = protocol::TraceContext { trace_id: ctx.trace_id, parent_span_id: ctx.parent_span_id, + span_id: ctx.span_id, op: Some(ctx.op), ..Default::default() }; @@ -864,6 +974,23 @@ fn parse_sentry_trace(header: &str) -> Option { Some(SentryTrace(trace_id, parent_span_id, parent_sampled)) } +/// Parses a W3C traceparent header. +/// Reference: +fn parse_w3c_traceparent(header: &str) -> Option { + let header = header.trim(); + let mut parts = header.splitn(4, '-'); + + let _version = parts.next()?; + let trace_id = parts.next()?.parse().ok()?; + let parent_span_id = parts.next()?.parse().ok()?; + let parent_sampled = parts + .next() + .and_then(|sampled| u8::from_str_radix(sampled, 16).ok()) + .map(|flag| flag & 1 != 0); + + Some(SentryTrace(trace_id, parent_span_id, parent_sampled)) +} + impl std::fmt::Display for SentryTrace { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}-{}", self.0, self.1)?; @@ -896,6 +1023,26 @@ mod tests { assert_eq!(parsed, Some(trace)); } + #[test] + fn parses_traceparent() { + let trace_id = protocol::TraceId::from_str("4bf92f3577b34da6a3ce929d0e0e4736").unwrap(); + let parent_trace_id = protocol::SpanId::from_str("00f067aa0ba902b7").unwrap(); + + let trace = + parse_w3c_traceparent("00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"); + assert_eq!( + trace, + Some(SentryTrace(trace_id, parent_trace_id, Some(true))) + ); + + let trace = + parse_w3c_traceparent("00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00"); + assert_eq!( + trace, + Some(SentryTrace(trace_id, parent_trace_id, Some(false))) + ); + } + #[test] fn disabled_forwards_trace_id() { let headers = [( From eb902e09ebaf9a18e60be6c83324899f28c66ab9 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 29 Nov 2024 08:46:17 +0000 Subject: [PATCH 034/148] feat(sentry-tracing): add span fields to breadcrumbs (#708) --- Cargo.lock | 1 + sentry-tracing/Cargo.toml | 1 + sentry-tracing/src/converters.rs | 10 ++++-- sentry-tracing/src/layer.rs | 2 +- sentry-tracing/tests/README.md | 3 ++ sentry-tracing/tests/breadcrumbs.rs | 34 +++++++++++++++++++ sentry-tracing/tests/shared.rs | 24 +++++++++++++ sentry-tracing/tests/{tracing.rs => smoke.rs} | 27 ++------------- 8 files changed, 74 insertions(+), 28 deletions(-) create mode 100644 sentry-tracing/tests/README.md create mode 100644 sentry-tracing/tests/breadcrumbs.rs create mode 100644 sentry-tracing/tests/shared.rs rename sentry-tracing/tests/{tracing.rs => smoke.rs} (70%) diff --git a/Cargo.lock b/Cargo.lock index 388e3d46b..9971c7dfa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3849,6 +3849,7 @@ dependencies = [ "sentry", "sentry-backtrace", "sentry-core", + "serde_json", "tokio", "tracing", "tracing-core", diff --git a/sentry-tracing/Cargo.toml b/sentry-tracing/Cargo.toml index fc146712a..ded852626 100644 --- a/sentry-tracing/Cargo.toml +++ b/sentry-tracing/Cargo.toml @@ -32,6 +32,7 @@ sentry-backtrace = { version = "0.34.0", path = "../sentry-backtrace", optional [dev-dependencies] log = "0.4" sentry = { path = "../sentry", default-features = false, features = ["test"] } +serde_json = "1" tracing = "0.1" tracing-subscriber = { version = "0.3.1", features = ["fmt", "registry"] } tokio = { version = "1.8", features = ["rt-multi-thread", "macros", "time"] } diff --git a/sentry-tracing/src/converters.rs b/sentry-tracing/src/converters.rs index c71143be2..acce10552 100644 --- a/sentry-tracing/src/converters.rs +++ b/sentry-tracing/src/converters.rs @@ -141,8 +141,14 @@ impl Visit for FieldVisitor { } /// Creates a [`Breadcrumb`] from a given [`tracing_core::Event`] -pub fn breadcrumb_from_event(event: &tracing_core::Event) -> Breadcrumb { - let (message, visitor) = extract_event_data(event); +pub fn breadcrumb_from_event<'context, S>( + event: &tracing_core::Event, + ctx: impl Into>>, +) -> Breadcrumb +where + S: Subscriber + for<'a> LookupSpan<'a>, +{ + let (message, visitor) = extract_event_data_with_context(event, ctx.into()); Breadcrumb { category: Some(event.metadata().target().to_owned()), ty: "log".into(), diff --git a/sentry-tracing/src/layer.rs b/sentry-tracing/src/layer.rs index 0540fe764..a2f94d176 100644 --- a/sentry-tracing/src/layer.rs +++ b/sentry-tracing/src/layer.rs @@ -214,7 +214,7 @@ where match (self.event_filter)(event.metadata()) { EventFilter::Ignore => EventMapping::Ignore, EventFilter::Breadcrumb => { - EventMapping::Breadcrumb(breadcrumb_from_event(event)) + EventMapping::Breadcrumb(breadcrumb_from_event(event, span_ctx)) } EventFilter::Event => EventMapping::Event(event_from_event(event, span_ctx)), EventFilter::Exception => { diff --git a/sentry-tracing/tests/README.md b/sentry-tracing/tests/README.md new file mode 100644 index 000000000..a5c57a9e2 --- /dev/null +++ b/sentry-tracing/tests/README.md @@ -0,0 +1,3 @@ +# Integration tests for `sentry-tracing` + +These tests are split up into 1 file per test to ensure they don't run concurrently. diff --git a/sentry-tracing/tests/breadcrumbs.rs b/sentry-tracing/tests/breadcrumbs.rs new file mode 100644 index 000000000..f62e13b65 --- /dev/null +++ b/sentry-tracing/tests/breadcrumbs.rs @@ -0,0 +1,34 @@ +mod shared; + +#[test] +fn breadcrumbs_should_capture_span_fields() { + let transport = shared::init_sentry(); + + foo(); + + let data = transport.fetch_and_clear_envelopes(); + assert_eq!(data.len(), 2); + + let event = data.first().expect("should have 1 event"); + let event = match event.items().next().unwrap() { + sentry::protocol::EnvelopeItem::Event(event) => event, + unexpected => panic!("Expected event, but got {:#?}", unexpected), + }; + + assert_eq!(event.breadcrumbs.len(), 1); + assert_eq!( + event.breadcrumbs[0].data["foo:contextual_value"], + serde_json::Value::from(42) + ); + assert_eq!( + event.breadcrumbs[0].message, + Some("executing foo".to_owned()) + ); +} + +#[tracing::instrument(fields(contextual_value = 42))] +fn foo() { + tracing::info!("executing foo"); + + tracing::error!("boom!"); +} diff --git a/sentry-tracing/tests/shared.rs b/sentry-tracing/tests/shared.rs new file mode 100644 index 000000000..9b4409edc --- /dev/null +++ b/sentry-tracing/tests/shared.rs @@ -0,0 +1,24 @@ +use sentry::{ClientOptions, Hub}; +use sentry_core::test::TestTransport; + +use std::sync::Arc; + +pub fn init_sentry() -> Arc { + use tracing_subscriber::prelude::*; + + let transport = TestTransport::new(); + let options = ClientOptions { + dsn: Some("https://test@sentry-tracing.com/test".parse().unwrap()), + transport: Some(Arc::new(transport.clone())), + sample_rate: 1.0, + traces_sample_rate: 1.0, + ..ClientOptions::default() + }; + Hub::current().bind_client(Some(Arc::new(options.into()))); + + let _ = tracing_subscriber::registry() + .with(sentry_tracing::layer().enable_span_attributes()) + .try_init(); + + transport +} diff --git a/sentry-tracing/tests/tracing.rs b/sentry-tracing/tests/smoke.rs similarity index 70% rename from sentry-tracing/tests/tracing.rs rename to sentry-tracing/tests/smoke.rs index c77183c32..05c3f9b50 100644 --- a/sentry-tracing/tests/tracing.rs +++ b/sentry-tracing/tests/smoke.rs @@ -1,27 +1,4 @@ -use sentry::{ClientOptions, Hub}; -use sentry_core::test::TestTransport; - -use std::sync::Arc; - -fn init_sentry() -> Arc { - use tracing_subscriber::prelude::*; - - let transport = TestTransport::new(); - let options = ClientOptions { - dsn: Some("https://test@sentry-tracing.com/test".parse().unwrap()), - transport: Some(Arc::new(transport.clone())), - sample_rate: 1.0, - traces_sample_rate: 1.0, - ..ClientOptions::default() - }; - Hub::current().bind_client(Some(Arc::new(options.into()))); - - let _ = tracing_subscriber::registry() - .with(sentry_tracing::layer().enable_span_attributes()) - .try_init(); - - transport -} +mod shared; #[tracing::instrument(fields(tags.tag = "key", not_tag = "value"))] fn function_with_tags(value: i32) { @@ -30,7 +7,7 @@ fn function_with_tags(value: i32) { #[test] fn should_instrument_function_with_event() { - let transport = init_sentry(); + let transport = shared::init_sentry(); function_with_tags(1); From 80bcc288c5b286676a4cb798f2d61ae02a43c3bb Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Fri, 29 Nov 2024 08:55:26 +0000 Subject: [PATCH 035/148] release: 0.35.0 --- CHANGELOG.md | 2 +- sentry-actix/Cargo.toml | 4 ++-- sentry-anyhow/Cargo.toml | 6 +++--- sentry-backtrace/Cargo.toml | 4 ++-- sentry-contexts/Cargo.toml | 4 ++-- sentry-core/Cargo.toml | 4 ++-- sentry-core/README.md | 2 +- sentry-debug-images/Cargo.toml | 4 ++-- sentry-debug-images/README.md | 2 +- sentry-log/Cargo.toml | 4 ++-- sentry-panic/Cargo.toml | 6 +++--- sentry-slog/Cargo.toml | 4 ++-- sentry-tower/Cargo.toml | 4 ++-- sentry-tower/README.md | 2 +- sentry-tracing/Cargo.toml | 6 +++--- sentry-tracing/README.md | 2 +- sentry-types/Cargo.toml | 2 +- sentry-types/README.md | 4 ++-- sentry/Cargo.toml | 22 +++++++++++----------- sentry/README.md | 12 ++++++------ 20 files changed, 50 insertions(+), 50 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6762dec3d..45d4444cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 0.35.0 **Fixes**: diff --git a/sentry-actix/Cargo.toml b/sentry-actix/Cargo.toml index b540bfde3..cc80eaff2 100644 --- a/sentry-actix/Cargo.toml +++ b/sentry-actix/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-actix" -version = "0.34.0" +version = "0.35.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -15,7 +15,7 @@ rust-version = "1.73" [dependencies] actix-web = { version = "4", default-features = false } futures-util = { version = "0.3.5", default-features = false } -sentry-core = { version = "0.34.0", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.35.0", path = "../sentry-core", default-features = false, features = [ "client", ] } diff --git a/sentry-anyhow/Cargo.toml b/sentry-anyhow/Cargo.toml index 83e31e3bb..82315702e 100644 --- a/sentry-anyhow/Cargo.toml +++ b/sentry-anyhow/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-anyhow" -version = "0.34.0" +version = "0.35.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -17,8 +17,8 @@ default = ["backtrace"] backtrace = ["anyhow/backtrace"] [dependencies] -sentry-backtrace = { version = "0.34.0", path = "../sentry-backtrace" } -sentry-core = { version = "0.34.0", path = "../sentry-core" } +sentry-backtrace = { version = "0.35.0", path = "../sentry-backtrace" } +sentry-core = { version = "0.35.0", path = "../sentry-core" } anyhow = "1.0.39" [dev-dependencies] diff --git a/sentry-backtrace/Cargo.toml b/sentry-backtrace/Cargo.toml index 56d84cfdb..1bd8b2257 100644 --- a/sentry-backtrace/Cargo.toml +++ b/sentry-backtrace/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-backtrace" -version = "0.34.0" +version = "0.35.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -19,4 +19,4 @@ regex = { version = "1.5.5", default-features = false, features = [ "std", "unicode-perl", ] } -sentry-core = { version = "0.34.0", path = "../sentry-core" } +sentry-core = { version = "0.35.0", path = "../sentry-core" } diff --git a/sentry-contexts/Cargo.toml b/sentry-contexts/Cargo.toml index 42dfde9ca..e8e702303 100644 --- a/sentry-contexts/Cargo.toml +++ b/sentry-contexts/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-contexts" -version = "0.34.0" +version = "0.35.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -14,7 +14,7 @@ edition = "2021" rust-version = "1.73" [dependencies] -sentry-core = { version = "0.34.0", path = "../sentry-core" } +sentry-core = { version = "0.35.0", path = "../sentry-core" } libc = "0.2.66" hostname = "0.4" diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index beb142c2d..670a70814 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-core" -version = "0.34.0" +version = "0.35.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -36,7 +36,7 @@ log = { version = "0.4.8", optional = true, features = ["std"] } once_cell = "1" rand = { version = "0.8.1", optional = true } regex = { version = "1.7.3", optional = true } -sentry-types = { version = "0.34.0", path = "../sentry-types" } +sentry-types = { version = "0.35.0", path = "../sentry-types" } serde = { version = "1.0.104", features = ["derive"] } serde_json = { version = "1.0.46" } uuid = { version = "1.0.0", features = ["v4", "serde"], optional = true } diff --git a/sentry-core/README.md b/sentry-core/README.md index f72f0abd2..a4782e615 100644 --- a/sentry-core/README.md +++ b/sentry-core/README.md @@ -102,7 +102,7 @@ functionality. [Sentry]: https://sentry.io/ [`sentry`]: https://crates.io/crates/sentry [Unified API]: https://develop.sentry.dev/sdk/unified-api/ -[`test`]: https://docs.rs/sentry-core/0.34.0/sentry_core/test/index.html +[`test`]: https://docs.rs/sentry-core/0.35.0/sentry_core/test/index.html ## Resources diff --git a/sentry-debug-images/Cargo.toml b/sentry-debug-images/Cargo.toml index 3838858a3..efbeffe4d 100644 --- a/sentry-debug-images/Cargo.toml +++ b/sentry-debug-images/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-debug-images" -version = "0.34.0" +version = "0.35.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -15,4 +15,4 @@ rust-version = "1.73" [dependencies] findshlibs = "=0.10.2" once_cell = "1" -sentry-core = { version = "0.34.0", path = "../sentry-core" } +sentry-core = { version = "0.35.0", path = "../sentry-core" } diff --git a/sentry-debug-images/README.md b/sentry-debug-images/README.md index 0bf922a5d..eff206526 100644 --- a/sentry-debug-images/README.md +++ b/sentry-debug-images/README.md @@ -22,7 +22,7 @@ let integration = sentry_debug_images::DebugImagesIntegration::new() .filter(|event| event.level >= Level::Warning); ``` -[`Event`]: https://docs.rs/sentry-debug-images/0.34.0/sentry_debug_images/sentry_core::protocol::Event +[`Event`]: https://docs.rs/sentry-debug-images/0.35.0/sentry_debug_images/sentry_core::protocol::Event ## Resources diff --git a/sentry-log/Cargo.toml b/sentry-log/Cargo.toml index 49e84156a..d1de1ed8c 100644 --- a/sentry-log/Cargo.toml +++ b/sentry-log/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-log" -version = "0.34.0" +version = "0.35.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.73" [dependencies] -sentry-core = { version = "0.34.0", path = "../sentry-core" } +sentry-core = { version = "0.35.0", path = "../sentry-core" } log = { version = "0.4.8", features = ["std"] } [dev-dependencies] diff --git a/sentry-panic/Cargo.toml b/sentry-panic/Cargo.toml index d4c5549f5..bbc5a0998 100644 --- a/sentry-panic/Cargo.toml +++ b/sentry-panic/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-panic" -version = "0.34.0" +version = "0.35.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -13,8 +13,8 @@ edition = "2021" rust-version = "1.73" [dependencies] -sentry-core = { version = "0.34.0", path = "../sentry-core" } -sentry-backtrace = { version = "0.34.0", path = "../sentry-backtrace" } +sentry-core = { version = "0.35.0", path = "../sentry-core" } +sentry-backtrace = { version = "0.35.0", path = "../sentry-backtrace" } [dev-dependencies] sentry = { path = "../sentry", default-features = false, features = ["test"] } diff --git a/sentry-slog/Cargo.toml b/sentry-slog/Cargo.toml index e92959973..4bbbeba7e 100644 --- a/sentry-slog/Cargo.toml +++ b/sentry-slog/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-slog" -version = "0.34.0" +version = "0.35.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.73" [dependencies] -sentry-core = { version = "0.34.0", path = "../sentry-core" } +sentry-core = { version = "0.35.0", path = "../sentry-core" } slog = { version = "2.5.2", features = ["nested-values"] } serde_json = "1.0.46" diff --git a/sentry-tower/Cargo.toml b/sentry-tower/Cargo.toml index 9102270c8..53258b322 100644 --- a/sentry-tower/Cargo.toml +++ b/sentry-tower/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tower" -version = "0.34.0" +version = "0.35.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -25,7 +25,7 @@ tower-layer = "0.3" tower-service = "0.3" http = { version = "1.0.0", optional = true } pin-project = { version = "1.0.10", optional = true } -sentry-core = { version = "0.34.0", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.35.0", path = "../sentry-core", default-features = false, features = [ "client", ] } url = { version = "2.2.2", optional = true } diff --git a/sentry-tower/README.md b/sentry-tower/README.md index fac9f2232..fb711ec4a 100644 --- a/sentry-tower/README.md +++ b/sentry-tower/README.md @@ -103,7 +103,7 @@ feature of the `sentry` crate instead of the `tower` feature. The created transaction will automatically use the request URI as its name. This is sometimes not desirable in case the request URI contains unique IDs or similar. In this case, users should manually override the transaction name -in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.34.0/sentry_tower/sentry_core::Scope::set_transaction) +in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.35.0/sentry_tower/sentry_core::Scope::set_transaction) method. When combining both layers, take care of the ordering of both. For example diff --git a/sentry-tracing/Cargo.toml b/sentry-tracing/Cargo.toml index ded852626..2cdbb60f5 100644 --- a/sentry-tracing/Cargo.toml +++ b/sentry-tracing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tracing" -version = "0.34.0" +version = "0.35.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -20,14 +20,14 @@ default = [] backtrace = ["dep:sentry-backtrace"] [dependencies] -sentry-core = { version = "0.34.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.35.0", path = "../sentry-core", features = [ "client", ] } tracing-core = "0.1" tracing-subscriber = { version = "0.3.1", default-features = false, features = [ "std", ] } -sentry-backtrace = { version = "0.34.0", path = "../sentry-backtrace", optional = true } +sentry-backtrace = { version = "0.35.0", path = "../sentry-backtrace", optional = true } [dev-dependencies] log = "0.4" diff --git a/sentry-tracing/README.md b/sentry-tracing/README.md index 15403cca8..303df9144 100644 --- a/sentry-tracing/README.md +++ b/sentry-tracing/README.md @@ -83,7 +83,7 @@ tracing::error!( ); ``` -To track [error structs](https://docs.rs/sentry-tracing/0.34.0/sentry_tracing/std::error::Error), assign a reference to error trait object as field +To track [error structs](https://docs.rs/sentry-tracing/0.35.0/sentry_tracing/std::error::Error), assign a reference to error trait object as field in one of the logging macros. By convention, it is recommended to use the `ERROR` level and assign it to a field called `error`, although the integration will also work with all other levels and field names. diff --git a/sentry-types/Cargo.toml b/sentry-types/Cargo.toml index 9a9dbdeed..b5ee8bc7e 100644 --- a/sentry-types/Cargo.toml +++ b/sentry-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-types" -version = "0.34.0" +version = "0.35.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" diff --git a/sentry-types/README.md b/sentry-types/README.md index 286b44d6f..0b03d7b78 100644 --- a/sentry-types/README.md +++ b/sentry-types/README.md @@ -7,7 +7,7 @@ # Sentry Rust SDK: sentry-types This crate provides common types for working with the Sentry protocol or the -Sentry server. It's used by the Sentry Relay infrastructure as well as the +Sentry server. It's used by the Sentry Relay infrastructure as well as the rust Sentry client. Most of the types in this crate are serializable in one form or another. @@ -26,7 +26,7 @@ so later versions might be added later. ### API Concepts Most types are directly serializable or deserializable and try to implement -the `Default` type. This means that objects can be created conviently +the `Default` type. This means that objects can be created conveniently and missing attributes can be filled in: ```rust diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index a6bc24a9e..cd48ea690 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry" -version = "0.34.0" +version = "0.35.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -54,18 +54,18 @@ rustls = ["dep:rustls", "reqwest?/rustls-tls", "ureq?/tls", "webpki-roots"] embedded-svc-http = ["dep:embedded-svc", "dep:esp-idf-svc"] [dependencies] -sentry-core = { version = "0.34.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.35.0", path = "../sentry-core", features = [ "client", ] } -sentry-anyhow = { version = "0.34.0", path = "../sentry-anyhow", optional = true } -sentry-backtrace = { version = "0.34.0", path = "../sentry-backtrace", optional = true } -sentry-contexts = { version = "0.34.0", path = "../sentry-contexts", optional = true } -sentry-debug-images = { version = "0.34.0", path = "../sentry-debug-images", optional = true } -sentry-log = { version = "0.34.0", path = "../sentry-log", optional = true } -sentry-panic = { version = "0.34.0", path = "../sentry-panic", optional = true } -sentry-slog = { version = "0.34.0", path = "../sentry-slog", optional = true } -sentry-tower = { version = "0.34.0", path = "../sentry-tower", optional = true } -sentry-tracing = { version = "0.34.0", path = "../sentry-tracing", optional = true } +sentry-anyhow = { version = "0.35.0", path = "../sentry-anyhow", optional = true } +sentry-backtrace = { version = "0.35.0", path = "../sentry-backtrace", optional = true } +sentry-contexts = { version = "0.35.0", path = "../sentry-contexts", optional = true } +sentry-debug-images = { version = "0.35.0", path = "../sentry-debug-images", optional = true } +sentry-log = { version = "0.35.0", path = "../sentry-log", optional = true } +sentry-panic = { version = "0.35.0", path = "../sentry-panic", optional = true } +sentry-slog = { version = "0.35.0", path = "../sentry-slog", optional = true } +sentry-tower = { version = "0.35.0", path = "../sentry-tower", optional = true } +sentry-tracing = { version = "0.35.0", path = "../sentry-tracing", optional = true } log = { version = "0.4.8", optional = true, features = ["std"] } reqwest = { version = "0.12", optional = true, features = [ "blocking", diff --git a/sentry/README.md b/sentry/README.md index 2a810e479..d64e834e1 100644 --- a/sentry/README.md +++ b/sentry/README.md @@ -34,8 +34,8 @@ sentry::capture_message("Hello World!", sentry::Level::Info); More complex examples on how to use sentry can also be found in [examples]. Extended instructions may also be found on [Sentry itself]. -[`sentry::init`]: https://docs.rs/sentry/0.34.0/sentry/fn.init.html -[`Hub`]: https://docs.rs/sentry/0.34.0/sentry/struct.Hub.html +[`sentry::init`]: https://docs.rs/sentry/0.35.0/sentry/fn.init.html +[`Hub`]: https://docs.rs/sentry/0.35.0/sentry/struct.Hub.html [examples]: https://github.com/getsentry/sentry-rust/tree/master/sentry/examples [Sentry itself]: https://docs.sentry.io/platforms/rust @@ -47,8 +47,8 @@ the ecosystem require a feature flag. For available integrations and how to use [integrations] and [apply_defaults]. [Features]: #features -[integrations]: https://docs.rs/sentry/0.34.0/sentry/integrations/index.html -[apply_defaults]: https://docs.rs/sentry/0.34.0/sentry/fn.apply_defaults.html +[integrations]: https://docs.rs/sentry/0.35.0/sentry/integrations/index.html +[apply_defaults]: https://docs.rs/sentry/0.35.0/sentry/fn.apply_defaults.html ## Minimal API @@ -56,8 +56,8 @@ This crate comes fully-featured. If the goal is to instrument libraries for usag with sentry, or to extend sentry with a custom [`Integration`] or a [`Transport`], one should use the [`sentry-core`] crate instead. -[`Integration`]: https://docs.rs/sentry/0.34.0/sentry/trait.Integration.html -[`Transport`]: https://docs.rs/sentry/0.34.0/sentry/trait.Transport.html +[`Integration`]: https://docs.rs/sentry/0.35.0/sentry/trait.Integration.html +[`Transport`]: https://docs.rs/sentry/0.35.0/sentry/trait.Transport.html [`sentry-core`]: https://crates.io/crates/sentry-core ## Features From caa746df4e5362f7be341e21cb186bb1ea351cd3 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 29 Nov 2024 13:50:57 +0000 Subject: [PATCH 036/148] Delay sampling of span to `finish` (#712) --- sentry-core/src/performance.rs | 17 ++++++++--------- sentry-tracing/tests/breadcrumbs.rs | 4 ++-- sentry-tracing/tests/shared.rs | 4 ++-- sentry-tracing/tests/smoke.rs | 2 +- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/sentry-core/src/performance.rs b/sentry-core/src/performance.rs index 3255f5db8..c95f83863 100644 --- a/sentry-core/src/performance.rs +++ b/sentry-core/src/performance.rs @@ -561,8 +561,8 @@ impl<'a> TransactionData<'a> { impl Transaction { #[cfg(feature = "client")] - fn new(mut client: Option>, ctx: TransactionContext) -> Self { - let (sampled, mut transaction) = match client.as_ref() { + fn new(client: Option>, ctx: TransactionContext) -> Self { + let (sampled, transaction) = match client.as_ref() { Some(client) => ( client.is_transaction_sampled(&ctx), Some(protocol::Transaction { @@ -581,13 +581,6 @@ impl Transaction { ..Default::default() }; - // throw away the transaction here, which means there is nothing to send - // on `finish`. - if !sampled { - transaction = None; - client = None; - } - Self { inner: Arc::new(Mutex::new(TransactionInner { client, @@ -699,6 +692,12 @@ impl Transaction { pub fn finish(self) { with_client_impl! {{ let mut inner = self.inner.lock().unwrap(); + + // Discard `Transaction` unless sampled. + if !inner.sampled { + return; + } + if let Some(mut transaction) = inner.transaction.take() { if let Some(client) = inner.client.take() { transaction.finish(); diff --git a/sentry-tracing/tests/breadcrumbs.rs b/sentry-tracing/tests/breadcrumbs.rs index f62e13b65..f1eab18d1 100644 --- a/sentry-tracing/tests/breadcrumbs.rs +++ b/sentry-tracing/tests/breadcrumbs.rs @@ -2,12 +2,12 @@ mod shared; #[test] fn breadcrumbs_should_capture_span_fields() { - let transport = shared::init_sentry(); + let transport = shared::init_sentry(0.0); // This test should work even if we are not sampling transactions. foo(); let data = transport.fetch_and_clear_envelopes(); - assert_eq!(data.len(), 2); + assert_eq!(data.len(), 1); let event = data.first().expect("should have 1 event"); let event = match event.items().next().unwrap() { diff --git a/sentry-tracing/tests/shared.rs b/sentry-tracing/tests/shared.rs index 9b4409edc..4deadac5c 100644 --- a/sentry-tracing/tests/shared.rs +++ b/sentry-tracing/tests/shared.rs @@ -3,7 +3,7 @@ use sentry_core::test::TestTransport; use std::sync::Arc; -pub fn init_sentry() -> Arc { +pub fn init_sentry(traces_sample_rate: f32) -> Arc { use tracing_subscriber::prelude::*; let transport = TestTransport::new(); @@ -11,7 +11,7 @@ pub fn init_sentry() -> Arc { dsn: Some("https://test@sentry-tracing.com/test".parse().unwrap()), transport: Some(Arc::new(transport.clone())), sample_rate: 1.0, - traces_sample_rate: 1.0, + traces_sample_rate, ..ClientOptions::default() }; Hub::current().bind_client(Some(Arc::new(options.into()))); diff --git a/sentry-tracing/tests/smoke.rs b/sentry-tracing/tests/smoke.rs index 05c3f9b50..5eb19c0f2 100644 --- a/sentry-tracing/tests/smoke.rs +++ b/sentry-tracing/tests/smoke.rs @@ -7,7 +7,7 @@ fn function_with_tags(value: i32) { #[test] fn should_instrument_function_with_event() { - let transport = shared::init_sentry(); + let transport = shared::init_sentry(1.0); // Sample all spans. function_with_tags(1); From 6de0bb6e240c82973df486ab31c94b9d053e2985 Mon Sep 17 00:00:00 2001 From: Jeffrey Hung <17494876+Jeffreyhung@users.noreply.github.com> Date: Wed, 11 Dec 2024 04:08:26 -0800 Subject: [PATCH 037/148] Replace release bot with GH app (#714) --- .github/workflows/release.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bde0e7b5a..fe9fe02ab 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,9 +15,16 @@ jobs: runs-on: ubuntu-latest name: "Release a new version" steps: + - name: Get auth token + id: token + uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0 + with: + app-id: ${{ vars.SENTRY_RELEASE_BOT_CLIENT_ID }} + private-key: ${{ secrets.SENTRY_RELEASE_BOT_PRIVATE_KEY }} + - uses: actions/checkout@v3 with: - token: ${{ secrets.GH_RELEASE_PAT }} + token: ${{ steps.token.outputs.token }} fetch-depth: 0 - run: cargo install cargo-readme @@ -25,7 +32,7 @@ jobs: - name: Prepare release uses: getsentry/action-prepare-release@v1 env: - GITHUB_TOKEN: ${{ secrets.GH_RELEASE_PAT }} + GITHUB_TOKEN: ${{ steps.token.outputs.token }} with: version: ${{ github.event.inputs.version }} force: ${{ github.event.inputs.force }} From a2bdeca4aa98a3bbee820a79f39eb63fae32684f Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 19 Dec 2024 16:21:58 +0100 Subject: [PATCH 038/148] Elide lifetimes where possible (#716) --- sentry-core/src/intodsn.rs | 8 ++++---- sentry-core/src/performance.rs | 6 +++--- sentry-slog/src/converters.rs | 2 +- sentry-types/src/protocol/v7.rs | 8 ++++---- sentry-types/src/utils.rs | 4 ++-- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/sentry-core/src/intodsn.rs b/sentry-core/src/intodsn.rs index 3e5b5ebf5..276d6789d 100644 --- a/sentry-core/src/intodsn.rs +++ b/sentry-core/src/intodsn.rs @@ -27,7 +27,7 @@ impl IntoDsn for () { } } -impl<'a> IntoDsn for &'a str { +impl IntoDsn for &'_ str { fn into_dsn(self) -> Result, ParseDsnError> { if self.is_empty() { Ok(None) @@ -37,14 +37,14 @@ impl<'a> IntoDsn for &'a str { } } -impl<'a> IntoDsn for Cow<'a, str> { +impl IntoDsn for Cow<'_, str> { fn into_dsn(self) -> Result, ParseDsnError> { let x: &str = &self; x.into_dsn() } } -impl<'a> IntoDsn for &'a OsStr { +impl IntoDsn for &'_ OsStr { fn into_dsn(self) -> Result, ParseDsnError> { self.to_string_lossy().into_dsn() } @@ -62,7 +62,7 @@ impl IntoDsn for String { } } -impl<'a> IntoDsn for &'a Dsn { +impl IntoDsn for &'_ Dsn { fn into_dsn(self) -> Result, ParseDsnError> { Ok(Some(self.clone())) } diff --git a/sentry-core/src/performance.rs b/sentry-core/src/performance.rs index c95f83863..0ebefd2ea 100644 --- a/sentry-core/src/performance.rs +++ b/sentry-core/src/performance.rs @@ -751,7 +751,7 @@ impl Transaction { /// A smart pointer to a span's [`data` field](protocol::Span::data). pub struct Data<'a>(MutexGuard<'a, protocol::Span>); -impl<'a> Data<'a> { +impl Data<'_> { /// Set some extra information to be sent with this Span. pub fn set_data(&mut self, key: String, value: protocol::Value) { self.0.data.insert(key, value); @@ -763,7 +763,7 @@ impl<'a> Data<'a> { } } -impl<'a> Deref for Data<'a> { +impl Deref for Data<'_> { type Target = BTreeMap; fn deref(&self) -> &Self::Target { @@ -771,7 +771,7 @@ impl<'a> Deref for Data<'a> { } } -impl<'a> DerefMut for Data<'a> { +impl DerefMut for Data<'_> { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0.data } diff --git a/sentry-slog/src/converters.rs b/sentry-slog/src/converters.rs index 8fafadfbe..3dcfbf365 100644 --- a/sentry-slog/src/converters.rs +++ b/sentry-slog/src/converters.rs @@ -22,7 +22,7 @@ macro_rules! impl_into { } }; } -impl<'a> Serializer for MapSerializer<'a> { +impl Serializer for MapSerializer<'_> { fn emit_arguments(&mut self, key: Key, val: &fmt::Arguments) -> slog::Result { self.0.insert(key.into(), val.to_string().into()); Ok(()) diff --git a/sentry-types/src/protocol/v7.rs b/sentry-types/src/protocol/v7.rs index a2f228000..bdbb2fc10 100644 --- a/sentry-types/src/protocol/v7.rs +++ b/sentry-types/src/protocol/v7.rs @@ -1643,7 +1643,7 @@ pub struct Event<'a> { pub sdk: Option>, } -impl<'a> Default for Event<'a> { +impl Default for Event<'_> { fn default() -> Self { Event { event_id: event::default_id(), @@ -1722,7 +1722,7 @@ impl<'a> Event<'a> { } } -impl<'a> fmt::Display for Event<'a> { +impl fmt::Display for Event<'_> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, @@ -1994,7 +1994,7 @@ pub struct Transaction<'a> { pub server_name: Option>, } -impl<'a> Default for Transaction<'a> { +impl Default for Transaction<'_> { fn default() -> Self { Transaction { event_id: event::default_id(), @@ -2049,7 +2049,7 @@ impl<'a> Transaction<'a> { } } -impl<'a> fmt::Display for Transaction<'a> { +impl fmt::Display for Transaction<'_> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, diff --git a/sentry-types/src/utils.rs b/sentry-types/src/utils.rs index aa3cd2a05..f5edfb575 100644 --- a/sentry-types/src/utils.rs +++ b/sentry-types/src/utils.rs @@ -60,7 +60,7 @@ pub mod ts_seconds_float { struct SecondsTimestampVisitor; - impl<'de> de::Visitor<'de> for SecondsTimestampVisitor { + impl de::Visitor<'_> for SecondsTimestampVisitor { type Value = SystemTime; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { @@ -144,7 +144,7 @@ pub mod ts_rfc3339 { pub(super) struct Rfc3339Deserializer; - impl<'de> de::Visitor<'de> for Rfc3339Deserializer { + impl de::Visitor<'_> for Rfc3339Deserializer { type Value = SystemTime; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { From fd92a324630069138d079959367b8ad0bf7c642b Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 19 Dec 2024 16:33:09 +0100 Subject: [PATCH 039/148] Allow retrieving user of scope (#715) --- sentry-core/src/scope/real.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sentry-core/src/scope/real.rs b/sentry-core/src/scope/real.rs index 47dec48d1..ed033fb00 100644 --- a/sentry-core/src/scope/real.rs +++ b/sentry-core/src/scope/real.rs @@ -197,6 +197,11 @@ impl Scope { self.user = user.map(Arc::new); } + /// Retrieves the user of the current scope. + pub fn user(&self) -> Option<&User> { + self.user.as_deref() + } + /// Sets a tag to a specific value. pub fn set_tag(&mut self, key: &str, value: V) { Arc::make_mut(&mut self.tags).insert(key.to_string(), value.to_string()); From 5cdf7fc85e8dc23f3246da91179811f135aacf76 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Tue, 7 Jan 2025 11:00:18 +0100 Subject: [PATCH 040/148] sentry-tower: Update `axum` dependency to v0.8 (#718) --- Cargo.lock | 117 +++++++++++++++++++++++++++++++--------- sentry-tower/Cargo.toml | 2 +- 2 files changed, 92 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9971c7dfa..f8ccfa4e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -583,14 +583,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" dependencies = [ "async-trait", - "axum-core", + "axum-core 0.4.3", "bytes 1.6.0", "futures-util", "http 1.1.0", "http-body", "http-body-util", "itoa", - "matchit", + "matchit 0.7.3", "memchr", "mime", "percent-encoding", @@ -598,7 +598,33 @@ dependencies = [ "rustversion", "serde", "sync_wrapper 1.0.1", - "tower", + "tower 0.4.13", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d6fd624c75e18b3b4c6b9caf42b1afe24437daaee904069137d8bab077be8b8" +dependencies = [ + "axum-core 0.5.0", + "bytes 1.6.0", + "futures-util", + "http 1.1.0", + "http-body", + "http-body-util", + "itoa", + "matchit 0.8.4", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper 1.0.1", + "tower 0.5.2", "tower-layer", "tower-service", ] @@ -623,6 +649,25 @@ dependencies = [ "tower-service", ] +[[package]] +name = "axum-core" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1362f362fd16024ae199c1970ce98f9661bf5ef94b9808fee734bc3698b733" +dependencies = [ + "bytes 1.6.0", + "futures-util", + "http 1.1.0", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper 1.0.1", + "tower-layer", + "tower-service", +] + [[package]] name = "backtrace" version = "0.3.72" @@ -2350,7 +2395,7 @@ dependencies = [ "pin-project-lite", "socket2 0.5.7", "tokio", - "tower", + "tower 0.4.13", "tower-service", "tracing", ] @@ -2672,6 +2717,12 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" +[[package]] +name = "matchit" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" + [[package]] name = "memchr" version = "2.7.2" @@ -3677,7 +3728,7 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "sentry" -version = "0.34.0" +version = "0.35.0" dependencies = [ "actix-web", "anyhow", @@ -3706,7 +3757,7 @@ dependencies = [ "slog", "surf", "tokio", - "tower", + "tower 0.4.13", "tracing", "tracing-subscriber", "ureq", @@ -3715,7 +3766,7 @@ dependencies = [ [[package]] name = "sentry-actix" -version = "0.34.0" +version = "0.35.0" dependencies = [ "actix-web", "futures", @@ -3727,7 +3778,7 @@ dependencies = [ [[package]] name = "sentry-anyhow" -version = "0.34.0" +version = "0.35.0" dependencies = [ "anyhow", "sentry", @@ -3737,7 +3788,7 @@ dependencies = [ [[package]] name = "sentry-backtrace" -version = "0.34.0" +version = "0.35.0" dependencies = [ "backtrace", "once_cell", @@ -3747,7 +3798,7 @@ dependencies = [ [[package]] name = "sentry-contexts" -version = "0.34.0" +version = "0.35.0" dependencies = [ "hostname", "libc", @@ -3760,7 +3811,7 @@ dependencies = [ [[package]] name = "sentry-core" -version = "0.34.0" +version = "0.35.0" dependencies = [ "anyhow", "cadence", @@ -3783,7 +3834,7 @@ dependencies = [ [[package]] name = "sentry-debug-images" -version = "0.34.0" +version = "0.35.0" dependencies = [ "findshlibs", "once_cell", @@ -3792,7 +3843,7 @@ dependencies = [ [[package]] name = "sentry-log" -version = "0.34.0" +version = "0.35.0" dependencies = [ "log", "pretty_env_logger", @@ -3802,7 +3853,7 @@ dependencies = [ [[package]] name = "sentry-panic" -version = "0.34.0" +version = "0.35.0" dependencies = [ "sentry", "sentry-backtrace", @@ -3811,7 +3862,7 @@ dependencies = [ [[package]] name = "sentry-slog" -version = "0.34.0" +version = "0.35.0" dependencies = [ "erased-serde", "sentry", @@ -3823,10 +3874,10 @@ dependencies = [ [[package]] name = "sentry-tower" -version = "0.34.0" +version = "0.35.0" dependencies = [ "anyhow", - "axum", + "axum 0.8.1", "http 1.1.0", "pin-project", "prost 0.12.6", @@ -3835,7 +3886,7 @@ dependencies = [ "sentry-core", "tokio", "tonic", - "tower", + "tower 0.4.13", "tower-layer", "tower-service", "url", @@ -3843,7 +3894,7 @@ dependencies = [ [[package]] name = "sentry-tracing" -version = "0.34.0" +version = "0.35.0" dependencies = [ "log", "sentry", @@ -3858,7 +3909,7 @@ dependencies = [ [[package]] name = "sentry-types" -version = "0.34.0" +version = "0.35.0" dependencies = [ "debugid", "hex", @@ -4480,7 +4531,7 @@ checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" dependencies = [ "async-stream", "async-trait", - "axum", + "axum 0.7.5", "base64 0.22.1", "bytes 1.6.0", "h2 0.4.6", @@ -4496,7 +4547,7 @@ dependencies = [ "socket2 0.5.7", "tokio", "tokio-stream", - "tower", + "tower 0.4.13", "tower-layer", "tower-service", "tracing", @@ -4522,17 +4573,31 @@ dependencies = [ "tracing", ] +[[package]] +name = "tower" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper 1.0.1", + "tower-layer", + "tower-service", +] + [[package]] name = "tower-layer" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" diff --git a/sentry-tower/Cargo.toml b/sentry-tower/Cargo.toml index 53258b322..98835feab 100644 --- a/sentry-tower/Cargo.toml +++ b/sentry-tower/Cargo.toml @@ -20,7 +20,7 @@ http = ["dep:http", "pin-project", "url"] axum-matched-path = ["http", "axum/matched-path"] [dependencies] -axum = { version = "0.7", optional = true, default-features = false } +axum = { version = "0.8", optional = true, default-features = false } tower-layer = "0.3" tower-service = "0.3" http = { version = "1.0.0", optional = true } From c97ba6c38707215879e57f1f5d4c4b1b0bc93ef4 Mon Sep 17 00:00:00 2001 From: Denis Cornehl Date: Tue, 7 Jan 2025 11:09:55 +0100 Subject: [PATCH 041/148] feat(sentry-tower) Make SentryLayer and SentryService `Sync` if request isn't (#721) --- sentry-tower/src/lib.rs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/sentry-tower/src/lib.rs b/sentry-tower/src/lib.rs index 4cd9818da..cccf2e8fb 100644 --- a/sentry-tower/src/lib.rs +++ b/sentry-tower/src/lib.rs @@ -196,7 +196,7 @@ where H: Into>, { provider: P, - _hub: PhantomData<(H, Request)>, + _hub: PhantomData<(H, fn() -> Request)>, } impl Layer for SentryLayer @@ -250,7 +250,7 @@ where { service: S, provider: P, - _hub: PhantomData<(H, Request)>, + _hub: PhantomData<(H, fn() -> Request)>, } impl Service for SentryService @@ -326,3 +326,21 @@ impl NewSentryService { } } } + +#[cfg(test)] +mod tests { + use super::*; + use std::rc::Rc; + + fn assert_sync() {} + + #[test] + fn test_layer_is_sync_when_request_isnt() { + assert_sync::>>(); // Rc<()> is not Sync + } + + #[test] + fn test_service_is_sync_when_request_isnt() { + assert_sync::>>(); // Rc<()> is not Sync + } +} From 83e5f4d7a029cc2b186b117075b5fc9718a7e45f Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Tue, 7 Jan 2025 15:29:05 +0000 Subject: [PATCH 042/148] release: 0.36.0 --- CHANGELOG.md | 11 +++++++++++ sentry-actix/Cargo.toml | 4 ++-- sentry-anyhow/Cargo.toml | 6 +++--- sentry-backtrace/Cargo.toml | 4 ++-- sentry-contexts/Cargo.toml | 4 ++-- sentry-core/Cargo.toml | 4 ++-- sentry-core/README.md | 2 +- sentry-debug-images/Cargo.toml | 4 ++-- sentry-debug-images/README.md | 2 +- sentry-log/Cargo.toml | 4 ++-- sentry-panic/Cargo.toml | 6 +++--- sentry-slog/Cargo.toml | 4 ++-- sentry-tower/Cargo.toml | 4 ++-- sentry-tower/README.md | 2 +- sentry-tracing/Cargo.toml | 6 +++--- sentry-tracing/README.md | 2 +- sentry-types/Cargo.toml | 2 +- sentry/Cargo.toml | 22 +++++++++++----------- sentry/README.md | 12 ++++++------ 19 files changed, 58 insertions(+), 47 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45d4444cd..fdaf63cc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## 0.36.0 + +### Various fixes & improvements + +- feat(sentry-tower) Make SentryLayer and SentryService `Sync` if request isn't (#721) by @syphar +- sentry-tower: Update `axum` dependency to v0.8 (#718) by @Turbo87 +- Allow retrieving user of scope (#715) by @thomaseizinger +- Elide lifetimes where possible (#716) by @thomaseizinger +- Replace release bot with GH app (#714) by @Jeffreyhung +- Delay sampling of span to `finish` (#712) by @thomaseizinger + ## 0.35.0 **Fixes**: diff --git a/sentry-actix/Cargo.toml b/sentry-actix/Cargo.toml index cc80eaff2..4f2231e97 100644 --- a/sentry-actix/Cargo.toml +++ b/sentry-actix/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-actix" -version = "0.35.0" +version = "0.36.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -15,7 +15,7 @@ rust-version = "1.73" [dependencies] actix-web = { version = "4", default-features = false } futures-util = { version = "0.3.5", default-features = false } -sentry-core = { version = "0.35.0", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.36.0", path = "../sentry-core", default-features = false, features = [ "client", ] } diff --git a/sentry-anyhow/Cargo.toml b/sentry-anyhow/Cargo.toml index 82315702e..b958273c8 100644 --- a/sentry-anyhow/Cargo.toml +++ b/sentry-anyhow/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-anyhow" -version = "0.35.0" +version = "0.36.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -17,8 +17,8 @@ default = ["backtrace"] backtrace = ["anyhow/backtrace"] [dependencies] -sentry-backtrace = { version = "0.35.0", path = "../sentry-backtrace" } -sentry-core = { version = "0.35.0", path = "../sentry-core" } +sentry-backtrace = { version = "0.36.0", path = "../sentry-backtrace" } +sentry-core = { version = "0.36.0", path = "../sentry-core" } anyhow = "1.0.39" [dev-dependencies] diff --git a/sentry-backtrace/Cargo.toml b/sentry-backtrace/Cargo.toml index 1bd8b2257..35e6cbed4 100644 --- a/sentry-backtrace/Cargo.toml +++ b/sentry-backtrace/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-backtrace" -version = "0.35.0" +version = "0.36.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -19,4 +19,4 @@ regex = { version = "1.5.5", default-features = false, features = [ "std", "unicode-perl", ] } -sentry-core = { version = "0.35.0", path = "../sentry-core" } +sentry-core = { version = "0.36.0", path = "../sentry-core" } diff --git a/sentry-contexts/Cargo.toml b/sentry-contexts/Cargo.toml index e8e702303..ce0165cb6 100644 --- a/sentry-contexts/Cargo.toml +++ b/sentry-contexts/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-contexts" -version = "0.35.0" +version = "0.36.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -14,7 +14,7 @@ edition = "2021" rust-version = "1.73" [dependencies] -sentry-core = { version = "0.35.0", path = "../sentry-core" } +sentry-core = { version = "0.36.0", path = "../sentry-core" } libc = "0.2.66" hostname = "0.4" diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index 670a70814..c61ff93a9 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-core" -version = "0.35.0" +version = "0.36.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -36,7 +36,7 @@ log = { version = "0.4.8", optional = true, features = ["std"] } once_cell = "1" rand = { version = "0.8.1", optional = true } regex = { version = "1.7.3", optional = true } -sentry-types = { version = "0.35.0", path = "../sentry-types" } +sentry-types = { version = "0.36.0", path = "../sentry-types" } serde = { version = "1.0.104", features = ["derive"] } serde_json = { version = "1.0.46" } uuid = { version = "1.0.0", features = ["v4", "serde"], optional = true } diff --git a/sentry-core/README.md b/sentry-core/README.md index a4782e615..5bfb3d313 100644 --- a/sentry-core/README.md +++ b/sentry-core/README.md @@ -102,7 +102,7 @@ functionality. [Sentry]: https://sentry.io/ [`sentry`]: https://crates.io/crates/sentry [Unified API]: https://develop.sentry.dev/sdk/unified-api/ -[`test`]: https://docs.rs/sentry-core/0.35.0/sentry_core/test/index.html +[`test`]: https://docs.rs/sentry-core/0.36.0/sentry_core/test/index.html ## Resources diff --git a/sentry-debug-images/Cargo.toml b/sentry-debug-images/Cargo.toml index efbeffe4d..7c82f1e70 100644 --- a/sentry-debug-images/Cargo.toml +++ b/sentry-debug-images/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-debug-images" -version = "0.35.0" +version = "0.36.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -15,4 +15,4 @@ rust-version = "1.73" [dependencies] findshlibs = "=0.10.2" once_cell = "1" -sentry-core = { version = "0.35.0", path = "../sentry-core" } +sentry-core = { version = "0.36.0", path = "../sentry-core" } diff --git a/sentry-debug-images/README.md b/sentry-debug-images/README.md index eff206526..27218122d 100644 --- a/sentry-debug-images/README.md +++ b/sentry-debug-images/README.md @@ -22,7 +22,7 @@ let integration = sentry_debug_images::DebugImagesIntegration::new() .filter(|event| event.level >= Level::Warning); ``` -[`Event`]: https://docs.rs/sentry-debug-images/0.35.0/sentry_debug_images/sentry_core::protocol::Event +[`Event`]: https://docs.rs/sentry-debug-images/0.36.0/sentry_debug_images/sentry_core::protocol::Event ## Resources diff --git a/sentry-log/Cargo.toml b/sentry-log/Cargo.toml index d1de1ed8c..76d582a39 100644 --- a/sentry-log/Cargo.toml +++ b/sentry-log/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-log" -version = "0.35.0" +version = "0.36.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.73" [dependencies] -sentry-core = { version = "0.35.0", path = "../sentry-core" } +sentry-core = { version = "0.36.0", path = "../sentry-core" } log = { version = "0.4.8", features = ["std"] } [dev-dependencies] diff --git a/sentry-panic/Cargo.toml b/sentry-panic/Cargo.toml index bbc5a0998..ed31f817e 100644 --- a/sentry-panic/Cargo.toml +++ b/sentry-panic/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-panic" -version = "0.35.0" +version = "0.36.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -13,8 +13,8 @@ edition = "2021" rust-version = "1.73" [dependencies] -sentry-core = { version = "0.35.0", path = "../sentry-core" } -sentry-backtrace = { version = "0.35.0", path = "../sentry-backtrace" } +sentry-core = { version = "0.36.0", path = "../sentry-core" } +sentry-backtrace = { version = "0.36.0", path = "../sentry-backtrace" } [dev-dependencies] sentry = { path = "../sentry", default-features = false, features = ["test"] } diff --git a/sentry-slog/Cargo.toml b/sentry-slog/Cargo.toml index 4bbbeba7e..4e7994cd9 100644 --- a/sentry-slog/Cargo.toml +++ b/sentry-slog/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-slog" -version = "0.35.0" +version = "0.36.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.73" [dependencies] -sentry-core = { version = "0.35.0", path = "../sentry-core" } +sentry-core = { version = "0.36.0", path = "../sentry-core" } slog = { version = "2.5.2", features = ["nested-values"] } serde_json = "1.0.46" diff --git a/sentry-tower/Cargo.toml b/sentry-tower/Cargo.toml index 98835feab..50653bc39 100644 --- a/sentry-tower/Cargo.toml +++ b/sentry-tower/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tower" -version = "0.35.0" +version = "0.36.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -25,7 +25,7 @@ tower-layer = "0.3" tower-service = "0.3" http = { version = "1.0.0", optional = true } pin-project = { version = "1.0.10", optional = true } -sentry-core = { version = "0.35.0", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.36.0", path = "../sentry-core", default-features = false, features = [ "client", ] } url = { version = "2.2.2", optional = true } diff --git a/sentry-tower/README.md b/sentry-tower/README.md index fb711ec4a..9e7e68627 100644 --- a/sentry-tower/README.md +++ b/sentry-tower/README.md @@ -103,7 +103,7 @@ feature of the `sentry` crate instead of the `tower` feature. The created transaction will automatically use the request URI as its name. This is sometimes not desirable in case the request URI contains unique IDs or similar. In this case, users should manually override the transaction name -in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.35.0/sentry_tower/sentry_core::Scope::set_transaction) +in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.36.0/sentry_tower/sentry_core::Scope::set_transaction) method. When combining both layers, take care of the ordering of both. For example diff --git a/sentry-tracing/Cargo.toml b/sentry-tracing/Cargo.toml index 2cdbb60f5..0ac9e9f4e 100644 --- a/sentry-tracing/Cargo.toml +++ b/sentry-tracing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tracing" -version = "0.35.0" +version = "0.36.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -20,14 +20,14 @@ default = [] backtrace = ["dep:sentry-backtrace"] [dependencies] -sentry-core = { version = "0.35.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.36.0", path = "../sentry-core", features = [ "client", ] } tracing-core = "0.1" tracing-subscriber = { version = "0.3.1", default-features = false, features = [ "std", ] } -sentry-backtrace = { version = "0.35.0", path = "../sentry-backtrace", optional = true } +sentry-backtrace = { version = "0.36.0", path = "../sentry-backtrace", optional = true } [dev-dependencies] log = "0.4" diff --git a/sentry-tracing/README.md b/sentry-tracing/README.md index 303df9144..d53770079 100644 --- a/sentry-tracing/README.md +++ b/sentry-tracing/README.md @@ -83,7 +83,7 @@ tracing::error!( ); ``` -To track [error structs](https://docs.rs/sentry-tracing/0.35.0/sentry_tracing/std::error::Error), assign a reference to error trait object as field +To track [error structs](https://docs.rs/sentry-tracing/0.36.0/sentry_tracing/std::error::Error), assign a reference to error trait object as field in one of the logging macros. By convention, it is recommended to use the `ERROR` level and assign it to a field called `error`, although the integration will also work with all other levels and field names. diff --git a/sentry-types/Cargo.toml b/sentry-types/Cargo.toml index b5ee8bc7e..48bb4d20a 100644 --- a/sentry-types/Cargo.toml +++ b/sentry-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-types" -version = "0.35.0" +version = "0.36.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index cd48ea690..9c4a5a3a6 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry" -version = "0.35.0" +version = "0.36.0" authors = ["Sentry "] license = "Apache-2.0" readme = "README.md" @@ -54,18 +54,18 @@ rustls = ["dep:rustls", "reqwest?/rustls-tls", "ureq?/tls", "webpki-roots"] embedded-svc-http = ["dep:embedded-svc", "dep:esp-idf-svc"] [dependencies] -sentry-core = { version = "0.35.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.36.0", path = "../sentry-core", features = [ "client", ] } -sentry-anyhow = { version = "0.35.0", path = "../sentry-anyhow", optional = true } -sentry-backtrace = { version = "0.35.0", path = "../sentry-backtrace", optional = true } -sentry-contexts = { version = "0.35.0", path = "../sentry-contexts", optional = true } -sentry-debug-images = { version = "0.35.0", path = "../sentry-debug-images", optional = true } -sentry-log = { version = "0.35.0", path = "../sentry-log", optional = true } -sentry-panic = { version = "0.35.0", path = "../sentry-panic", optional = true } -sentry-slog = { version = "0.35.0", path = "../sentry-slog", optional = true } -sentry-tower = { version = "0.35.0", path = "../sentry-tower", optional = true } -sentry-tracing = { version = "0.35.0", path = "../sentry-tracing", optional = true } +sentry-anyhow = { version = "0.36.0", path = "../sentry-anyhow", optional = true } +sentry-backtrace = { version = "0.36.0", path = "../sentry-backtrace", optional = true } +sentry-contexts = { version = "0.36.0", path = "../sentry-contexts", optional = true } +sentry-debug-images = { version = "0.36.0", path = "../sentry-debug-images", optional = true } +sentry-log = { version = "0.36.0", path = "../sentry-log", optional = true } +sentry-panic = { version = "0.36.0", path = "../sentry-panic", optional = true } +sentry-slog = { version = "0.36.0", path = "../sentry-slog", optional = true } +sentry-tower = { version = "0.36.0", path = "../sentry-tower", optional = true } +sentry-tracing = { version = "0.36.0", path = "../sentry-tracing", optional = true } log = { version = "0.4.8", optional = true, features = ["std"] } reqwest = { version = "0.12", optional = true, features = [ "blocking", diff --git a/sentry/README.md b/sentry/README.md index d64e834e1..5b383e8c1 100644 --- a/sentry/README.md +++ b/sentry/README.md @@ -34,8 +34,8 @@ sentry::capture_message("Hello World!", sentry::Level::Info); More complex examples on how to use sentry can also be found in [examples]. Extended instructions may also be found on [Sentry itself]. -[`sentry::init`]: https://docs.rs/sentry/0.35.0/sentry/fn.init.html -[`Hub`]: https://docs.rs/sentry/0.35.0/sentry/struct.Hub.html +[`sentry::init`]: https://docs.rs/sentry/0.36.0/sentry/fn.init.html +[`Hub`]: https://docs.rs/sentry/0.36.0/sentry/struct.Hub.html [examples]: https://github.com/getsentry/sentry-rust/tree/master/sentry/examples [Sentry itself]: https://docs.sentry.io/platforms/rust @@ -47,8 +47,8 @@ the ecosystem require a feature flag. For available integrations and how to use [integrations] and [apply_defaults]. [Features]: #features -[integrations]: https://docs.rs/sentry/0.35.0/sentry/integrations/index.html -[apply_defaults]: https://docs.rs/sentry/0.35.0/sentry/fn.apply_defaults.html +[integrations]: https://docs.rs/sentry/0.36.0/sentry/integrations/index.html +[apply_defaults]: https://docs.rs/sentry/0.36.0/sentry/fn.apply_defaults.html ## Minimal API @@ -56,8 +56,8 @@ This crate comes fully-featured. If the goal is to instrument libraries for usag with sentry, or to extend sentry with a custom [`Integration`] or a [`Transport`], one should use the [`sentry-core`] crate instead. -[`Integration`]: https://docs.rs/sentry/0.35.0/sentry/trait.Integration.html -[`Transport`]: https://docs.rs/sentry/0.35.0/sentry/trait.Transport.html +[`Integration`]: https://docs.rs/sentry/0.36.0/sentry/trait.Integration.html +[`Transport`]: https://docs.rs/sentry/0.36.0/sentry/trait.Transport.html [`sentry-core`]: https://crates.io/crates/sentry-core ## Features From 1908678b47ad56bb0fda540619492cc1d56f2e09 Mon Sep 17 00:00:00 2001 From: Michi Hoffmann Date: Tue, 28 Jan 2025 08:16:30 +0100 Subject: [PATCH 043/148] Switch to MIT license (#724) --- LICENSE | 224 ++++----------------------------- sentry-actix/Cargo.toml | 2 +- sentry-actix/LICENSE | 224 ++++----------------------------- sentry-actix/README.md | 2 +- sentry-anyhow/Cargo.toml | 2 +- sentry-anyhow/LICENSE | 224 ++++----------------------------- sentry-anyhow/README.md | 2 +- sentry-backtrace/Cargo.toml | 2 +- sentry-backtrace/LICENSE | 224 ++++----------------------------- sentry-backtrace/README.md | 2 +- sentry-contexts/Cargo.toml | 2 +- sentry-contexts/LICENSE | 224 ++++----------------------------- sentry-contexts/README.md | 2 +- sentry-core/Cargo.toml | 2 +- sentry-core/LICENSE | 224 ++++----------------------------- sentry-core/README.md | 2 +- sentry-debug-images/Cargo.toml | 2 +- sentry-debug-images/LICENSE | 224 ++++----------------------------- sentry-debug-images/README.md | 2 +- sentry-log/Cargo.toml | 2 +- sentry-log/LICENSE | 224 ++++----------------------------- sentry-log/README.md | 2 +- sentry-panic/Cargo.toml | 2 +- sentry-panic/LICENSE | 224 ++++----------------------------- sentry-panic/README.md | 2 +- sentry-slog/Cargo.toml | 2 +- sentry-slog/LICENSE | 224 ++++----------------------------- sentry-slog/README.md | 2 +- sentry-tower/Cargo.toml | 2 +- sentry-tower/LICENSE | 224 ++++----------------------------- sentry-tower/README.md | 2 +- sentry-tracing/Cargo.toml | 2 +- sentry-tracing/LICENSE | 224 ++++----------------------------- sentry-tracing/README.md | 2 +- sentry-types/Cargo.toml | 2 +- sentry-types/LICENSE | 224 ++++----------------------------- sentry-types/README.md | 2 +- sentry/Cargo.toml | 2 +- sentry/LICENSE | 224 ++++----------------------------- sentry/README.md | 2 +- 40 files changed, 320 insertions(+), 2868 deletions(-) diff --git a/LICENSE b/LICENSE index d97d9399c..3e4988928 100644 --- a/LICENSE +++ b/LICENSE @@ -1,203 +1,21 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2021 Functional Software, Inc. dba Sentry (https://sentry.io) - and individual contributors. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +MIT License + +Copyright (c) 2021 Functional Software, Inc. dba Sentry + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/sentry-actix/Cargo.toml b/sentry-actix/Cargo.toml index 4f2231e97..3a7e94e41 100644 --- a/sentry-actix/Cargo.toml +++ b/sentry-actix/Cargo.toml @@ -2,7 +2,7 @@ name = "sentry-actix" version = "0.36.0" authors = ["Sentry "] -license = "Apache-2.0" +license = "MIT" readme = "README.md" repository = "https://github.com/getsentry/sentry-rust" homepage = "https://sentry.io/welcome/" diff --git a/sentry-actix/LICENSE b/sentry-actix/LICENSE index d97d9399c..3e4988928 100644 --- a/sentry-actix/LICENSE +++ b/sentry-actix/LICENSE @@ -1,203 +1,21 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2021 Functional Software, Inc. dba Sentry (https://sentry.io) - and individual contributors. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +MIT License + +Copyright (c) 2021 Functional Software, Inc. dba Sentry + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/sentry-actix/README.md b/sentry-actix/README.md index 6255da8a3..a4bbd2982 100644 --- a/sentry-actix/README.md +++ b/sentry-actix/README.md @@ -75,7 +75,7 @@ sentry::capture_message("Something is not well", sentry::Level::Warning); ## Resources -License: Apache-2.0 +License: MIT - [Discord](https://discord.gg/ez5KZN7) server for project discussions. - Follow [@getsentry](https://twitter.com/getsentry) on Twitter for updates diff --git a/sentry-anyhow/Cargo.toml b/sentry-anyhow/Cargo.toml index b958273c8..769340bc9 100644 --- a/sentry-anyhow/Cargo.toml +++ b/sentry-anyhow/Cargo.toml @@ -2,7 +2,7 @@ name = "sentry-anyhow" version = "0.36.0" authors = ["Sentry "] -license = "Apache-2.0" +license = "MIT" readme = "README.md" repository = "https://github.com/getsentry/sentry-rust" homepage = "https://sentry.io/welcome/" diff --git a/sentry-anyhow/LICENSE b/sentry-anyhow/LICENSE index d97d9399c..3e4988928 100644 --- a/sentry-anyhow/LICENSE +++ b/sentry-anyhow/LICENSE @@ -1,203 +1,21 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2021 Functional Software, Inc. dba Sentry (https://sentry.io) - and individual contributors. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +MIT License + +Copyright (c) 2021 Functional Software, Inc. dba Sentry + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/sentry-anyhow/README.md b/sentry-anyhow/README.md index 6a8312fb4..4ad56f57e 100644 --- a/sentry-anyhow/README.md +++ b/sentry-anyhow/README.md @@ -46,7 +46,7 @@ capture backtraces with your events. It is enabled by default. ## Resources -License: Apache-2.0 +License: MIT - [Discord](https://discord.gg/ez5KZN7) server for project discussions. - Follow [@getsentry](https://twitter.com/getsentry) on Twitter for updates diff --git a/sentry-backtrace/Cargo.toml b/sentry-backtrace/Cargo.toml index 35e6cbed4..e29b32636 100644 --- a/sentry-backtrace/Cargo.toml +++ b/sentry-backtrace/Cargo.toml @@ -2,7 +2,7 @@ name = "sentry-backtrace" version = "0.36.0" authors = ["Sentry "] -license = "Apache-2.0" +license = "MIT" readme = "README.md" repository = "https://github.com/getsentry/sentry-rust" homepage = "https://sentry.io/welcome/" diff --git a/sentry-backtrace/LICENSE b/sentry-backtrace/LICENSE index d97d9399c..3e4988928 100644 --- a/sentry-backtrace/LICENSE +++ b/sentry-backtrace/LICENSE @@ -1,203 +1,21 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2021 Functional Software, Inc. dba Sentry (https://sentry.io) - and individual contributors. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +MIT License + +Copyright (c) 2021 Functional Software, Inc. dba Sentry + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/sentry-backtrace/README.md b/sentry-backtrace/README.md index 1cbd8340f..ca4e43607 100644 --- a/sentry-backtrace/README.md +++ b/sentry-backtrace/README.md @@ -13,7 +13,7 @@ as integrations to process event stacktraces. ## Resources -License: Apache-2.0 +License: MIT - [Discord](https://discord.gg/ez5KZN7) server for project discussions. - Follow [@getsentry](https://twitter.com/getsentry) on Twitter for updates diff --git a/sentry-contexts/Cargo.toml b/sentry-contexts/Cargo.toml index ce0165cb6..90f25de10 100644 --- a/sentry-contexts/Cargo.toml +++ b/sentry-contexts/Cargo.toml @@ -2,7 +2,7 @@ name = "sentry-contexts" version = "0.36.0" authors = ["Sentry "] -license = "Apache-2.0" +license = "MIT" readme = "README.md" repository = "https://github.com/getsentry/sentry-rust" homepage = "https://sentry.io/welcome/" diff --git a/sentry-contexts/LICENSE b/sentry-contexts/LICENSE index d97d9399c..3e4988928 100644 --- a/sentry-contexts/LICENSE +++ b/sentry-contexts/LICENSE @@ -1,203 +1,21 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2021 Functional Software, Inc. dba Sentry (https://sentry.io) - and individual contributors. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +MIT License + +Copyright (c) 2021 Functional Software, Inc. dba Sentry + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/sentry-contexts/README.md b/sentry-contexts/README.md index 31a85585b..f2abcbb78 100644 --- a/sentry-contexts/README.md +++ b/sentry-contexts/README.md @@ -25,7 +25,7 @@ let _sentry = sentry::init(sentry::ClientOptions::new().add_integration(integrat ## Resources -License: Apache-2.0 +License: MIT - [Discord](https://discord.gg/ez5KZN7) server for project discussions. - Follow [@getsentry](https://twitter.com/getsentry) on Twitter for updates diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index c61ff93a9..fa52ee12e 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -2,7 +2,7 @@ name = "sentry-core" version = "0.36.0" authors = ["Sentry "] -license = "Apache-2.0" +license = "MIT" readme = "README.md" repository = "https://github.com/getsentry/sentry-rust" homepage = "https://sentry.io/welcome/" diff --git a/sentry-core/LICENSE b/sentry-core/LICENSE index d97d9399c..3e4988928 100644 --- a/sentry-core/LICENSE +++ b/sentry-core/LICENSE @@ -1,203 +1,21 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2021 Functional Software, Inc. dba Sentry (https://sentry.io) - and individual contributors. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +MIT License + +Copyright (c) 2021 Functional Software, Inc. dba Sentry + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/sentry-core/README.md b/sentry-core/README.md index 5bfb3d313..19d992b70 100644 --- a/sentry-core/README.md +++ b/sentry-core/README.md @@ -106,7 +106,7 @@ functionality. ## Resources -License: Apache-2.0 +License: MIT - [Discord](https://discord.gg/ez5KZN7) server for project discussions. - Follow [@getsentry](https://twitter.com/getsentry) on Twitter for updates diff --git a/sentry-debug-images/Cargo.toml b/sentry-debug-images/Cargo.toml index 7c82f1e70..1025d50bc 100644 --- a/sentry-debug-images/Cargo.toml +++ b/sentry-debug-images/Cargo.toml @@ -2,7 +2,7 @@ name = "sentry-debug-images" version = "0.36.0" authors = ["Sentry "] -license = "Apache-2.0" +license = "MIT" readme = "README.md" repository = "https://github.com/getsentry/sentry-rust" homepage = "https://sentry.io/welcome/" diff --git a/sentry-debug-images/LICENSE b/sentry-debug-images/LICENSE index d97d9399c..3e4988928 100644 --- a/sentry-debug-images/LICENSE +++ b/sentry-debug-images/LICENSE @@ -1,203 +1,21 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2021 Functional Software, Inc. dba Sentry (https://sentry.io) - and individual contributors. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +MIT License + +Copyright (c) 2021 Functional Software, Inc. dba Sentry + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/sentry-debug-images/README.md b/sentry-debug-images/README.md index 27218122d..b280e304d 100644 --- a/sentry-debug-images/README.md +++ b/sentry-debug-images/README.md @@ -26,7 +26,7 @@ let integration = sentry_debug_images::DebugImagesIntegration::new() ## Resources -License: Apache-2.0 +License: MIT - [Discord](https://discord.gg/ez5KZN7) server for project discussions. - Follow [@getsentry](https://twitter.com/getsentry) on Twitter for updates diff --git a/sentry-log/Cargo.toml b/sentry-log/Cargo.toml index 76d582a39..59bba3571 100644 --- a/sentry-log/Cargo.toml +++ b/sentry-log/Cargo.toml @@ -2,7 +2,7 @@ name = "sentry-log" version = "0.36.0" authors = ["Sentry "] -license = "Apache-2.0" +license = "MIT" readme = "README.md" repository = "https://github.com/getsentry/sentry-rust" homepage = "https://sentry.io/welcome/" diff --git a/sentry-log/LICENSE b/sentry-log/LICENSE index d97d9399c..3e4988928 100644 --- a/sentry-log/LICENSE +++ b/sentry-log/LICENSE @@ -1,203 +1,21 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2021 Functional Software, Inc. dba Sentry (https://sentry.io) - and individual contributors. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +MIT License + +Copyright (c) 2021 Functional Software, Inc. dba Sentry + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/sentry-log/README.md b/sentry-log/README.md index 03865c7c1..6466bd45f 100644 --- a/sentry-log/README.md +++ b/sentry-log/README.md @@ -43,7 +43,7 @@ let logger = sentry_log::SentryLogger::new().filter(|md| match md.level() { ## Resources -License: Apache-2.0 +License: MIT - [Discord](https://discord.gg/ez5KZN7) server for project discussions. - Follow [@getsentry](https://twitter.com/getsentry) on Twitter for updates diff --git a/sentry-panic/Cargo.toml b/sentry-panic/Cargo.toml index ed31f817e..17d6e8959 100644 --- a/sentry-panic/Cargo.toml +++ b/sentry-panic/Cargo.toml @@ -2,7 +2,7 @@ name = "sentry-panic" version = "0.36.0" authors = ["Sentry "] -license = "Apache-2.0" +license = "MIT" readme = "README.md" repository = "https://github.com/getsentry/sentry-rust" homepage = "https://sentry.io/welcome/" diff --git a/sentry-panic/LICENSE b/sentry-panic/LICENSE index d97d9399c..3e4988928 100644 --- a/sentry-panic/LICENSE +++ b/sentry-panic/LICENSE @@ -1,203 +1,21 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2021 Functional Software, Inc. dba Sentry (https://sentry.io) - and individual contributors. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +MIT License + +Copyright (c) 2021 Functional Software, Inc. dba Sentry + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/sentry-panic/README.md b/sentry-panic/README.md index 5d7d7a9f8..6b9860857 100644 --- a/sentry-panic/README.md +++ b/sentry-panic/README.md @@ -24,7 +24,7 @@ let integration = sentry_panic::PanicIntegration::default().add_extractor(|info| ## Resources -License: Apache-2.0 +License: MIT - [Discord](https://discord.gg/ez5KZN7) server for project discussions. - Follow [@getsentry](https://twitter.com/getsentry) on Twitter for updates diff --git a/sentry-slog/Cargo.toml b/sentry-slog/Cargo.toml index 4e7994cd9..4d64bbd3a 100644 --- a/sentry-slog/Cargo.toml +++ b/sentry-slog/Cargo.toml @@ -2,7 +2,7 @@ name = "sentry-slog" version = "0.36.0" authors = ["Sentry "] -license = "Apache-2.0" +license = "MIT" readme = "README.md" repository = "https://github.com/getsentry/sentry-rust" homepage = "https://sentry.io/welcome/" diff --git a/sentry-slog/LICENSE b/sentry-slog/LICENSE index d97d9399c..3e4988928 100644 --- a/sentry-slog/LICENSE +++ b/sentry-slog/LICENSE @@ -1,203 +1,21 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2021 Functional Software, Inc. dba Sentry (https://sentry.io) - and individual contributors. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +MIT License + +Copyright (c) 2021 Functional Software, Inc. dba Sentry + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/sentry-slog/README.md b/sentry-slog/README.md index 8f1d28c77..718bb9f28 100644 --- a/sentry-slog/README.md +++ b/sentry-slog/README.md @@ -74,7 +74,7 @@ provided. ## Resources -License: Apache-2.0 +License: MIT - [Discord](https://discord.gg/ez5KZN7) server for project discussions. - Follow [@getsentry](https://twitter.com/getsentry) on Twitter for updates diff --git a/sentry-tower/Cargo.toml b/sentry-tower/Cargo.toml index 50653bc39..77f3c6ee2 100644 --- a/sentry-tower/Cargo.toml +++ b/sentry-tower/Cargo.toml @@ -2,7 +2,7 @@ name = "sentry-tower" version = "0.36.0" authors = ["Sentry "] -license = "Apache-2.0" +license = "MIT" readme = "README.md" repository = "https://github.com/getsentry/sentry-rust" homepage = "https://sentry.io/welcome/" diff --git a/sentry-tower/LICENSE b/sentry-tower/LICENSE index d97d9399c..3e4988928 100644 --- a/sentry-tower/LICENSE +++ b/sentry-tower/LICENSE @@ -1,203 +1,21 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2021 Functional Software, Inc. dba Sentry (https://sentry.io) - and individual contributors. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +MIT License + +Copyright (c) 2021 Functional Software, Inc. dba Sentry + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/sentry-tower/README.md b/sentry-tower/README.md index 9e7e68627..fd25c050d 100644 --- a/sentry-tower/README.md +++ b/sentry-tower/README.md @@ -120,7 +120,7 @@ let layer = tower::ServiceBuilder::new() ## Resources -License: Apache-2.0 +License: MIT - [Discord](https://discord.gg/ez5KZN7) server for project discussions. - Follow [@getsentry](https://twitter.com/getsentry) on Twitter for updates diff --git a/sentry-tracing/Cargo.toml b/sentry-tracing/Cargo.toml index 0ac9e9f4e..50d65bf19 100644 --- a/sentry-tracing/Cargo.toml +++ b/sentry-tracing/Cargo.toml @@ -2,7 +2,7 @@ name = "sentry-tracing" version = "0.36.0" authors = ["Sentry "] -license = "Apache-2.0" +license = "MIT" readme = "README.md" repository = "https://github.com/getsentry/sentry-rust" homepage = "https://sentry.io/welcome/" diff --git a/sentry-tracing/LICENSE b/sentry-tracing/LICENSE index d97d9399c..3e4988928 100644 --- a/sentry-tracing/LICENSE +++ b/sentry-tracing/LICENSE @@ -1,203 +1,21 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2021 Functional Software, Inc. dba Sentry (https://sentry.io) - and individual contributors. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +MIT License + +Copyright (c) 2021 Functional Software, Inc. dba Sentry + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/sentry-tracing/README.md b/sentry-tracing/README.md index d53770079..00ad63c7b 100644 --- a/sentry-tracing/README.md +++ b/sentry-tracing/README.md @@ -146,7 +146,7 @@ async fn inner(i: u32) { ## Resources -License: Apache-2.0 +License: MIT - [Discord](https://discord.gg/ez5KZN7) server for project discussions. - Follow [@getsentry](https://twitter.com/getsentry) on Twitter for updates diff --git a/sentry-types/Cargo.toml b/sentry-types/Cargo.toml index 48bb4d20a..2f981db64 100644 --- a/sentry-types/Cargo.toml +++ b/sentry-types/Cargo.toml @@ -2,7 +2,7 @@ name = "sentry-types" version = "0.36.0" authors = ["Sentry "] -license = "Apache-2.0" +license = "MIT" readme = "README.md" repository = "https://github.com/getsentry/sentry-rust" homepage = "https://sentry.io/welcome/" diff --git a/sentry-types/LICENSE b/sentry-types/LICENSE index d97d9399c..3e4988928 100644 --- a/sentry-types/LICENSE +++ b/sentry-types/LICENSE @@ -1,203 +1,21 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2021 Functional Software, Inc. dba Sentry (https://sentry.io) - and individual contributors. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +MIT License + +Copyright (c) 2021 Functional Software, Inc. dba Sentry + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/sentry-types/README.md b/sentry-types/README.md index 0b03d7b78..b9a61db2f 100644 --- a/sentry-types/README.md +++ b/sentry-types/README.md @@ -42,7 +42,7 @@ let event = v7::Event { ## Resources -License: Apache-2.0 +License: MIT - [Discord](https://discord.gg/ez5KZN7) server for project discussions. - Follow [@getsentry](https://twitter.com/getsentry) on Twitter for updates diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index 9c4a5a3a6..79d83ee65 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -2,7 +2,7 @@ name = "sentry" version = "0.36.0" authors = ["Sentry "] -license = "Apache-2.0" +license = "MIT" readme = "README.md" repository = "https://github.com/getsentry/sentry-rust" homepage = "https://sentry.io/welcome/" diff --git a/sentry/LICENSE b/sentry/LICENSE index d97d9399c..3e4988928 100644 --- a/sentry/LICENSE +++ b/sentry/LICENSE @@ -1,203 +1,21 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2021 Functional Software, Inc. dba Sentry (https://sentry.io) - and individual contributors. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +MIT License + +Copyright (c) 2021 Functional Software, Inc. dba Sentry + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/sentry/README.md b/sentry/README.md index 5b383e8c1..54a275e4d 100644 --- a/sentry/README.md +++ b/sentry/README.md @@ -122,7 +122,7 @@ extra setup to function properly. ## Resources -License: Apache-2.0 +License: MIT - [Discord](https://discord.gg/ez5KZN7) server for project discussions. - Follow [@getsentry](https://twitter.com/getsentry) on Twitter for updates From 135f2be116f6a9b5b7903dad29cf0163cfce84b6 Mon Sep 17 00:00:00 2001 From: Michi Hoffmann Date: Tue, 28 Jan 2025 10:32:43 +0100 Subject: [PATCH 044/148] Fix CS (#726) --- sentry-actix/src/lib.rs | 4 ++-- sentry-core/src/client.rs | 5 +---- sentry-core/src/hub_impl.rs | 6 +----- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/sentry-actix/src/lib.rs b/sentry-actix/src/lib.rs index 3232d140f..faf332419 100644 --- a/sentry-actix/src/lib.rs +++ b/sentry-actix/src/lib.rs @@ -225,7 +225,7 @@ where inner.hub.clone().unwrap_or_else(Hub::main), )); let client = hub.client(); - let track_sessions = client.as_ref().map_or(false, |client| { + let track_sessions = client.as_ref().is_some_and(|client| { let options = client.options(); options.auto_session_tracking && options.session_mode == sentry_core::SessionMode::Request @@ -235,7 +235,7 @@ where } let with_pii = client .as_ref() - .map_or(false, |client| client.options().send_default_pii); + .is_some_and(|client| client.options().send_default_pii); let sentry_req = sentry_request_from_http(&req, with_pii); let name = transaction_name_from_http(&req); diff --git a/sentry-core/src/client.rs b/sentry-core/src/client.rs index 56bd0d22f..7a6f6d65e 100644 --- a/sentry-core/src/client.rs +++ b/sentry-core/src/client.rs @@ -189,10 +189,7 @@ impl Client { } if let Some(scope) = scope { - event = match scope.apply_to_event(event) { - Some(event) => event, - None => return None, - }; + event = scope.apply_to_event(event)?; } for (_, integration) in self.integrations.iter() { diff --git a/sentry-core/src/hub_impl.rs b/sentry-core/src/hub_impl.rs index 59c91bf97..42d1fa6b3 100644 --- a/sentry-core/src/hub_impl.rs +++ b/sentry-core/src/hub_impl.rs @@ -90,11 +90,7 @@ impl HubImpl { Ok(guard) => guard, }; - guard - .top() - .client - .as_ref() - .map_or(false, |c| c.is_enabled()) + guard.top().client.as_ref().is_some_and(|c| c.is_enabled()) } } From 19bd8990c691fbc4c387f04b936b775752da739d Mon Sep 17 00:00:00 2001 From: David Herberth Date: Wed, 29 Jan 2025 09:10:13 +0100 Subject: [PATCH 045/148] fix(http): Finish transaction on drop (#727) --- sentry-tower/src/http.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/sentry-tower/src/http.rs b/sentry-tower/src/http.rs index 5ad964626..ee159a99a 100644 --- a/sentry-tower/src/http.rs +++ b/sentry-tower/src/http.rs @@ -4,6 +4,7 @@ use std::pin::Pin; use std::task::{Context, Poll}; use http::{header, uri, Request, Response, StatusCode}; +use pin_project::pinned_drop; use sentry_core::protocol; use tower_layer::Layer; use tower_service::Service; @@ -62,7 +63,7 @@ impl Layer for SentryHttpLayer { } /// The Future returned from [`SentryHttpService`]. -#[pin_project::pin_project] +#[pin_project::pin_project(PinnedDrop)] pub struct SentryHttpFuture { on_first_poll: Option<( sentry_core::protocol::Request, @@ -123,6 +124,23 @@ where } } +#[pinned_drop] +impl PinnedDrop for SentryHttpFuture { + fn drop(self: Pin<&mut Self>) { + let slf = self.project(); + + // If the future gets dropped without being polled to completion, + // still finish the transaction to make sure this is not lost. + if let Some((transaction, parent_span)) = slf.transaction.take() { + if transaction.get_status().is_none() { + transaction.set_status(protocol::SpanStatus::Aborted); + } + transaction.finish(); + sentry_core::configure_scope(|scope| scope.set_span(parent_span)); + } + } +} + impl Service> for SentryHttpService where S: Service, Response = Response>, From 1d3212a8beb8006131aaa1070dcdafb116e3d9fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9F=D0=B0=D0=B2=D0=B5=D0=BB=20=D0=A0=D0=BE=D1=81=D0=BF?= =?UTF-8?q?=D1=83=D1=82=D1=8C=D0=BA=D0=BE?= <2090529+pavel-rosputko@users.noreply.github.com> Date: Tue, 4 Feb 2025 16:01:55 +0400 Subject: [PATCH 046/148] follow https://github.com/getsentry/sentry-rust/pull/439 for actix-web. fix https://github.com/getsentry/sentry-rust/issues/680 (#737) --- sentry-actix/src/lib.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sentry-actix/src/lib.rs b/sentry-actix/src/lib.rs index faf332419..59dbf0707 100644 --- a/sentry-actix/src/lib.rs +++ b/sentry-actix/src/lib.rs @@ -250,7 +250,10 @@ where "http.server", headers, ); - Some(hub.start_transaction(ctx)) + + let transaction = hub.start_transaction(ctx); + transaction.set_request(sentry_req.clone()); + Some(transaction) } else { None }; From 3bcdda39ba4c0ad3e6cdce60a0ce1f8e224ce644 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Thu, 6 Feb 2025 19:26:16 +0100 Subject: [PATCH 047/148] feat(core): `transaction.set_data` sets data on `TraceContext` (#739) * change types that provide access to Transaction data to also access data attributes instead of extra * change tests to reflect new API --- sentry-core/src/performance.rs | 36 ++++++++++++++++++++------------- sentry-tracing/tests/smoke.rs | 14 ++++++------- sentry-types/src/protocol/v7.rs | 3 +++ 3 files changed, 32 insertions(+), 21 deletions(-) diff --git a/sentry-core/src/performance.rs b/sentry-core/src/performance.rs index 0ebefd2ea..740cd0ba2 100644 --- a/sentry-core/src/performance.rs +++ b/sentry-core/src/performance.rs @@ -526,32 +526,32 @@ pub struct Transaction { pub(crate) inner: TransactionArc, } -/// Iterable for a transaction's [`extra` field](protocol::Transaction::extra). +/// Iterable for a transaction's [data attributes](protocol::TraceContext::data). pub struct TransactionData<'a>(MutexGuard<'a, TransactionInner>); impl<'a> TransactionData<'a> { - /// Iterate over the `extra` map - /// of the [transaction][protocol::Transaction]. + /// Iterate over the [data attributes](protocol::TraceContext::data) + /// associated with this [transaction][protocol::Transaction]. /// - /// If the transaction not sampled for sending, - /// the metadata will not be populated at all + /// If the transaction is not sampled for sending, + /// the metadata will not be populated at all, /// so the produced iterator is empty. pub fn iter(&self) -> Box + '_> { - if let Some(ref rx) = self.0.transaction { - Box::new(rx.extra.iter()) + if self.0.transaction.is_some() { + Box::new(self.0.context.data.iter()) } else { Box::new(std::iter::empty()) } } - /// Set some extra information to be sent with this Transaction. + /// Set a data attribute to be sent with this Transaction. pub fn set_data(&mut self, key: Cow<'a, str>, value: protocol::Value) { - if let Some(transaction) = self.0.transaction.as_mut() { - transaction.extra.insert(key.into(), value); + if self.0.transaction.is_some() { + self.0.context.data.insert(key.into(), value); } } - /// Set some extra information to be sent with this Transaction. + /// Set a tag to be sent with this Transaction. pub fn set_tag(&mut self, key: Cow<'_, str>, value: String) { if let Some(transaction) = self.0.transaction.as_mut() { transaction.tags.insert(key.into(), value); @@ -610,8 +610,16 @@ impl Transaction { } } - /// Set some extra information to be sent with this Transaction. + /// Set a data attribute to be sent with this Transaction. pub fn set_data(&self, key: &str, value: protocol::Value) { + let mut inner = self.inner.lock().unwrap(); + if inner.transaction.is_some() { + inner.context.data.insert(key.into(), value); + } + } + + /// Set some extra information to be sent with this Transaction. + pub fn set_extra(&self, key: &str, value: protocol::Value) { let mut inner = self.inner.lock().unwrap(); if let Some(transaction) = inner.transaction.as_mut() { transaction.extra.insert(key.into(), value); @@ -627,10 +635,10 @@ impl Transaction { } /// Returns an iterating accessor to the transaction's - /// [`extra` field](protocol::Transaction::extra). + /// [data attributes](protocol::TraceContext::data). /// /// # Concurrency - /// In order to obtain any kind of reference to the `extra` field, + /// In order to obtain any kind of reference to the `TraceContext::data` field, /// a `Mutex` needs to be locked. The returned `TransactionData` holds on to this lock /// for as long as it lives. Therefore you must take care not to keep the returned /// `TransactionData` around too long or it will never relinquish the lock and you may run into diff --git a/sentry-tracing/tests/smoke.rs b/sentry-tracing/tests/smoke.rs index 5eb19c0f2..22b3ad26e 100644 --- a/sentry-tracing/tests/smoke.rs +++ b/sentry-tracing/tests/smoke.rs @@ -33,21 +33,21 @@ fn should_instrument_function_with_event() { unexpected => panic!("Expected transaction, but got {:#?}", unexpected), }; assert_eq!(transaction.tags.len(), 1); - assert_eq!(transaction.extra.len(), 2); + assert_eq!(trace.data.len(), 2); let tag = transaction .tags .get("tag") .expect("to have tag with name 'tag'"); assert_eq!(tag, "key"); - let not_tag = transaction - .extra + let not_tag = trace + .data .get("not_tag") - .expect("to have extra with name 'not_tag'"); + .expect("to have data attribute with name 'not_tag'"); assert_eq!(not_tag, "value"); - let value = transaction - .extra + let value = trace + .data .get("value") - .expect("to have extra with name 'value'"); + .expect("to have data attribute with name 'value'"); assert_eq!(value, 1); } diff --git a/sentry-types/src/protocol/v7.rs b/sentry-types/src/protocol/v7.rs index bdbb2fc10..badeaa0b5 100644 --- a/sentry-types/src/protocol/v7.rs +++ b/sentry-types/src/protocol/v7.rs @@ -1435,6 +1435,9 @@ pub struct TraceContext { /// Describes the status of the span (e.g. `ok`, `cancelled`, etc.) #[serde(default, skip_serializing_if = "Option::is_none")] pub status: Option, + /// Optional data attributes to be associated with the transaction. + #[serde(default, skip_serializing_if = "Map::is_empty")] + pub data: Map, } macro_rules! into_context { From e1fc51072f06a1a17f3cd1dbf5b866445ce8815b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Feb 2025 14:26:58 +0100 Subject: [PATCH 048/148] build(deps): bump openssl from 0.10.66 to 0.10.70 (#732) Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.66 to 0.10.70. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.66...openssl-v0.10.70) --- updated-dependencies: - dependency-name: openssl dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Lorenzo Cian --- Cargo.lock | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f8ccfa4e8..33161a319 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2939,9 +2939,9 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.66" +version = "0.10.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +checksum = "61cfb4e166a8bb8c9b55c500bc2308550148ece889be90f609377e58140f42c6" dependencies = [ "bitflags 2.5.0", "cfg-if", @@ -2971,9 +2971,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.103" +version = "0.9.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +checksum = "8b22d5b84be05a8d6947c7cb71f7c849aa0f112acd4bf51c2a7c1c988ac0a9dc" dependencies = [ "cc", "libc", @@ -3728,7 +3728,7 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "sentry" -version = "0.35.0" +version = "0.36.0" dependencies = [ "actix-web", "anyhow", @@ -3766,7 +3766,7 @@ dependencies = [ [[package]] name = "sentry-actix" -version = "0.35.0" +version = "0.36.0" dependencies = [ "actix-web", "futures", @@ -3778,7 +3778,7 @@ dependencies = [ [[package]] name = "sentry-anyhow" -version = "0.35.0" +version = "0.36.0" dependencies = [ "anyhow", "sentry", @@ -3788,7 +3788,7 @@ dependencies = [ [[package]] name = "sentry-backtrace" -version = "0.35.0" +version = "0.36.0" dependencies = [ "backtrace", "once_cell", @@ -3798,7 +3798,7 @@ dependencies = [ [[package]] name = "sentry-contexts" -version = "0.35.0" +version = "0.36.0" dependencies = [ "hostname", "libc", @@ -3811,7 +3811,7 @@ dependencies = [ [[package]] name = "sentry-core" -version = "0.35.0" +version = "0.36.0" dependencies = [ "anyhow", "cadence", @@ -3834,7 +3834,7 @@ dependencies = [ [[package]] name = "sentry-debug-images" -version = "0.35.0" +version = "0.36.0" dependencies = [ "findshlibs", "once_cell", @@ -3843,7 +3843,7 @@ dependencies = [ [[package]] name = "sentry-log" -version = "0.35.0" +version = "0.36.0" dependencies = [ "log", "pretty_env_logger", @@ -3853,7 +3853,7 @@ dependencies = [ [[package]] name = "sentry-panic" -version = "0.35.0" +version = "0.36.0" dependencies = [ "sentry", "sentry-backtrace", @@ -3862,7 +3862,7 @@ dependencies = [ [[package]] name = "sentry-slog" -version = "0.35.0" +version = "0.36.0" dependencies = [ "erased-serde", "sentry", @@ -3874,7 +3874,7 @@ dependencies = [ [[package]] name = "sentry-tower" -version = "0.35.0" +version = "0.36.0" dependencies = [ "anyhow", "axum 0.8.1", @@ -3894,7 +3894,7 @@ dependencies = [ [[package]] name = "sentry-tracing" -version = "0.35.0" +version = "0.36.0" dependencies = [ "log", "sentry", @@ -3909,7 +3909,7 @@ dependencies = [ [[package]] name = "sentry-types" -version = "0.35.0" +version = "0.36.0" dependencies = [ "debugid", "hex", From 1ea3664ee1102f6b28e7c8d7532749f0a876ea07 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Thu, 13 Feb 2025 13:39:50 +0100 Subject: [PATCH 049/148] ref(metrics): remove features and code related to the old metrics beta (#740) * ref(metrics): remove features and code related to the old metrics beta * remove statsd thing --- sentry-core/Cargo.toml | 2 - sentry-core/src/cadence.rs | 163 --- sentry-core/src/client.rs | 31 - sentry-core/src/lib.rs | 6 - sentry-core/src/metrics/mod.rs | 1275 ----------------- sentry-core/src/metrics/normalization/mod.rs | 28 - .../metrics/normalization/normalized_name.rs | 33 - .../metrics/normalization/normalized_tags.rs | 181 --- .../metrics/normalization/normalized_unit.rs | 57 - sentry-core/src/units.rs | 266 ---- sentry-types/Cargo.toml | 1 - sentry-types/src/protocol/envelope.rs | 13 - sentry/Cargo.toml | 2 - sentry/src/transports/ratelimit.rs | 8 - 14 files changed, 2066 deletions(-) delete mode 100644 sentry-core/src/cadence.rs delete mode 100644 sentry-core/src/metrics/mod.rs delete mode 100644 sentry-core/src/metrics/normalization/mod.rs delete mode 100644 sentry-core/src/metrics/normalization/normalized_name.rs delete mode 100644 sentry-core/src/metrics/normalization/normalized_tags.rs delete mode 100644 sentry-core/src/metrics/normalization/normalized_unit.rs delete mode 100644 sentry-core/src/units.rs diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index fa52ee12e..ecb3c37d5 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -26,8 +26,6 @@ client = ["rand"] # and macros actually expand features (and extern crate) where they are used! debug-logs = ["dep:log"] test = ["client"] -metrics = ["sentry-types/metrics", "regex", "crc32fast"] -metrics-cadence1 = ["dep:cadence", "metrics"] [dependencies] cadence = { version = "1.4.0", optional = true } diff --git a/sentry-core/src/cadence.rs b/sentry-core/src/cadence.rs deleted file mode 100644 index 0306bd7c8..000000000 --- a/sentry-core/src/cadence.rs +++ /dev/null @@ -1,163 +0,0 @@ -//! [`cadence`] integration for Sentry. -//! -//! [`cadence`] is a popular Statsd client for Rust. The [`SentryMetricSink`] provides a drop-in -//! integration to send metrics captured via `cadence` to Sentry. For direct usage of Sentry -//! metrics, see the [`metrics`](crate::metrics) module. -//! -//! # Usage -//! -//! To use the `cadence` integration, enable the `metrics-cadence1` feature in your `Cargo.toml`. -//! Then, create a [`SentryMetricSink`] and pass it to your `cadence` client: -//! -//! ``` -//! use cadence::StatsdClient; -//! use sentry::cadence::SentryMetricSink; -//! -//! let client = StatsdClient::from_sink("sentry.test", SentryMetricSink::new()); -//! ``` -//! -//! # Side-by-side Usage -//! -//! If you want to send metrics to Sentry and another backend at the same time, you can use -//! [`SentryMetricSink::wrap`] to wrap another [`MetricSink`]: -//! -//! ``` -//! use cadence::{StatsdClient, NopMetricSink}; -//! use sentry::cadence::SentryMetricSink; -//! -//! let sink = SentryMetricSink::wrap(NopMetricSink); -//! let client = StatsdClient::from_sink("sentry.test", sink); -//! ``` - -use std::sync::Arc; - -use cadence::{MetricSink, NopMetricSink}; - -use crate::metrics::Metric; -use crate::{Client, Hub}; - -/// A [`MetricSink`] that sends metrics to Sentry. -/// -/// This metric sends all metrics to Sentry. The Sentry client is internally buffered, so submission -/// will be delayed. -/// -/// Optionally, this sink can also forward metrics to another [`MetricSink`]. This is useful if you -/// want to send metrics to Sentry and another backend at the same time. Use -/// [`SentryMetricSink::wrap`] to construct such a sink. -#[derive(Debug)] -pub struct SentryMetricSink { - client: Option>, - sink: S, -} - -impl SentryMetricSink -where - S: MetricSink, -{ - /// Creates a new [`SentryMetricSink`], wrapping the given [`MetricSink`]. - pub fn wrap(sink: S) -> Self { - Self { client: None, sink } - } - - /// Creates a new [`SentryMetricSink`] sending data to the given [`Client`]. - pub fn with_client(mut self, client: Arc) -> Self { - self.client = Some(client); - self - } -} - -impl SentryMetricSink { - /// Creates a new [`SentryMetricSink`]. - /// - /// It is not required that a client is available when this sink is created. The sink sends - /// metrics to the client of the Sentry hub that is registered when the metrics are emitted. - pub fn new() -> Self { - Self { - client: None, - sink: NopMetricSink, - } - } -} - -impl Default for SentryMetricSink { - fn default() -> Self { - Self::new() - } -} - -impl MetricSink for SentryMetricSink { - fn emit(&self, string: &str) -> std::io::Result { - if let Ok(metric) = Metric::parse_statsd(string) { - if let Some(ref client) = self.client { - client.add_metric(metric); - } else if let Some(client) = Hub::current().client() { - client.add_metric(metric); - } - } - - // NopMetricSink returns `0`, which is correct as Sentry is buffering the metrics. - self.sink.emit(string) - } - - fn flush(&self) -> std::io::Result<()> { - let flushed = if let Some(ref client) = self.client { - client.flush(None) - } else if let Some(client) = Hub::current().client() { - client.flush(None) - } else { - true - }; - - let sink_result = self.sink.flush(); - - if !flushed { - Err(std::io::Error::new( - std::io::ErrorKind::Other, - "failed to flush metrics to Sentry", - )) - } else { - sink_result - } - } -} - -#[cfg(test)] -mod tests { - use cadence::{Counted, Distributed}; - use sentry_types::protocol::latest::EnvelopeItem; - - use crate::test::with_captured_envelopes; - - use super::*; - - #[test] - fn test_basic_metrics() { - let envelopes = with_captured_envelopes(|| { - let client = cadence::StatsdClient::from_sink("sentry.test", SentryMetricSink::new()); - client.count("some.count", 1).unwrap(); - client.count("some.count", 10).unwrap(); - client - .count_with_tags("count.with.tags", 1) - .with_tag("foo", "bar") - .send(); - client.distribution("some.distr", 1).unwrap(); - client.distribution("some.distr", 2).unwrap(); - client.distribution("some.distr", 3).unwrap(); - }); - assert_eq!(envelopes.len(), 1); - - let mut items = envelopes[0].items(); - let Some(EnvelopeItem::Statsd(metrics)) = items.next() else { - panic!("expected metrics"); - }; - let metrics = std::str::from_utf8(metrics).unwrap(); - - println!("{metrics}"); - - assert!(metrics - .contains("sentry.test.count.with.tags@none:1|c|#environment:production,foo:bar|T")); - assert!(metrics.contains("sentry.test.some.count@none:11|c|#environment:production|T")); - assert!(metrics.contains("sentry.test.some.distr@none:1:2:3|d|#environment:production|T")); - assert_eq!(items.next(), None); - } -} diff --git a/sentry-core/src/client.rs b/sentry-core/src/client.rs index 7a6f6d65e..f95154dea 100644 --- a/sentry-core/src/client.rs +++ b/sentry-core/src/client.rs @@ -10,8 +10,6 @@ use sentry_types::protocol::v7::SessionUpdate; use sentry_types::random_uuid; use crate::constants::SDK_INFO; -#[cfg(feature = "metrics")] -use crate::metrics::{self, MetricAggregator}; use crate::protocol::{ClientSdkInfo, Event}; use crate::session::SessionFlusher; use crate::types::{Dsn, Uuid}; @@ -46,8 +44,6 @@ pub struct Client { options: ClientOptions, transport: TransportArc, session_flusher: RwLock>, - #[cfg(feature = "metrics")] - metric_aggregator: RwLock>, integrations: Vec<(TypeId, Arc)>, pub(crate) sdk_info: ClientSdkInfo, } @@ -68,17 +64,10 @@ impl Clone for Client { transport.clone(), self.options.session_mode, ))); - #[cfg(feature = "metrics")] - let metric_aggregator = RwLock::new(Some(MetricAggregator::new( - transport.clone(), - &self.options, - ))); Client { options: self.options.clone(), transport, session_flusher, - #[cfg(feature = "metrics")] - metric_aggregator, integrations: self.integrations.clone(), sdk_info: self.sdk_info.clone(), } @@ -147,16 +136,10 @@ impl Client { options.session_mode, ))); - #[cfg(feature = "metrics")] - let metric_aggregator = - RwLock::new(Some(MetricAggregator::new(transport.clone(), &options))); - Client { options, transport, session_flusher, - #[cfg(feature = "metrics")] - metric_aggregator, integrations, sdk_info, } @@ -323,23 +306,11 @@ impl Client { } } - /// Captures a metric and sends it to Sentry on the next flush. - #[cfg(feature = "metrics")] - pub fn add_metric(&self, metric: metrics::Metric) { - if let Some(ref aggregator) = *self.metric_aggregator.read().unwrap() { - aggregator.add(metric) - } - } - /// Drains all pending events without shutting down. pub fn flush(&self, timeout: Option) -> bool { if let Some(ref flusher) = *self.session_flusher.read().unwrap() { flusher.flush(); } - #[cfg(feature = "metrics")] - if let Some(ref aggregator) = *self.metric_aggregator.read().unwrap() { - aggregator.flush(); - } if let Some(ref transport) = *self.transport.read().unwrap() { transport.flush(timeout.unwrap_or(self.options.shutdown_timeout)) } else { @@ -356,8 +327,6 @@ impl Client { /// `shutdown_timeout` in the client options. pub fn close(&self, timeout: Option) -> bool { drop(self.session_flusher.write().unwrap().take()); - #[cfg(feature = "metrics")] - drop(self.metric_aggregator.write().unwrap().take()); let transport_opt = self.transport.write().unwrap().take(); if let Some(transport) = transport_opt { sentry_debug!("client close; request transport to shut down"); diff --git a/sentry-core/src/lib.rs b/sentry-core/src/lib.rs index 5cc39cd54..8ea9bcbd2 100644 --- a/sentry-core/src/lib.rs +++ b/sentry-core/src/lib.rs @@ -136,19 +136,13 @@ pub use crate::performance::*; pub use crate::scope::{Scope, ScopeGuard}; pub use crate::transport::{Transport, TransportFactory}; -#[cfg(all(feature = "client", feature = "metrics-cadence1"))] -pub mod cadence; // client feature #[cfg(feature = "client")] mod client; #[cfg(feature = "client")] mod hub_impl; -#[cfg(all(feature = "client", feature = "metrics"))] -pub mod metrics; #[cfg(feature = "client")] mod session; -#[cfg(all(feature = "client", feature = "metrics"))] -mod units; #[cfg(feature = "client")] pub use crate::{client::Client, hub_impl::SwitchGuard as HubSwitchGuard}; diff --git a/sentry-core/src/metrics/mod.rs b/sentry-core/src/metrics/mod.rs deleted file mode 100644 index 96da9d4f9..000000000 --- a/sentry-core/src/metrics/mod.rs +++ /dev/null @@ -1,1275 +0,0 @@ -//! Utilities to track metrics in Sentry. -//! -//! Metrics are numerical values that can track anything about your environment over time, from -//! latency to error rates to user signups. -//! -//! Metrics at Sentry come in different flavors, in order to help you track your data in the most -//! efficient and cost-effective way. The types of metrics we currently support are: -//! -//! - **Counters** track a value that can only be incremented. -//! - **Distributions** track a list of values over time in on which you can perform aggregations -//! like max, min, avg. -//! - **Gauges** track a value that can go up and down. -//! - **Sets** track a set of values on which you can perform aggregations such as count_unique. -//! -//! For more information on metrics in Sentry, see [our docs]. -//! -//! # Usage -//! -//! To collect a metric, use the [`Metric`] struct to capture all relevant properties of your -//! metric. Then, use [`send`](Metric::send) to send the metric to Sentry: -//! -//! ``` -//! use std::time::Duration; -//! use sentry::metrics::Metric; -//! -//! Metric::count("requests") -//! .with_tag("method", "GET") -//! .send(); -//! -//! Metric::timing("request.duration", Duration::from_millis(17)) -//! .with_tag("status_code", "200") -//! // unit is added automatically by timing -//! .send(); -//! -//! Metric::set("site.visitors", "user1") -//! .with_unit("user") -//! .send(); -//! ``` -//! -//! # Usage with Cadence -//! -//! [`cadence`] is a popular Statsd client for Rust and can be used to send metrics to Sentry. To -//! use Sentry directly with `cadence`, see the [`sentry-cadence`](crate::cadence) documentation. -//! -//! [our docs]: https://develop.sentry.dev/services/metrics/ - -mod normalization; - -use std::borrow::Cow; -use std::collections::hash_map::Entry; -use std::collections::{BTreeMap, BTreeSet, HashMap}; -use std::fmt::{self, Display}; -use std::sync::{Arc, Mutex}; -use std::thread::{self, JoinHandle}; -use std::time::{Duration, SystemTime, UNIX_EPOCH}; - -use sentry_types::protocol::latest::{Envelope, EnvelopeItem}; - -use crate::client::TransportArc; -use crate::{ClientOptions, Hub}; - -pub use crate::units::*; - -const BUCKET_INTERVAL: Duration = Duration::from_secs(10); -const FLUSH_INTERVAL: Duration = Duration::from_secs(5); -const MAX_WEIGHT: usize = 100_000; - -/// Type alias for strings used in [`Metric`] for names and tags. -pub type MetricStr = Cow<'static, str>; - -/// Type used for [`MetricValue::Counter`]. -pub type CounterValue = f64; - -/// Type used for [`MetricValue::Distribution`]. -pub type DistributionValue = f64; - -/// Type used for [`MetricValue::Set`]. -pub type SetValue = u32; - -/// Type used for [`MetricValue::Gauge`]. -pub type GaugeValue = f64; - -/// The value of a [`Metric`], indicating its type. -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum MetricValue { - /// Counts instances of an event. - /// - /// Counters can be incremented and decremented. The default operation is to increment a counter - /// by `1`, although increments by larger values and even floating point values are possible. - /// - /// # Example - /// - /// ``` - /// use sentry::metrics::{Metric, MetricValue}; - /// - /// Metric::build("my.counter", MetricValue::Counter(1.0)).send(); - /// ``` - Counter(CounterValue), - - /// Builds a statistical distribution over values reported. - /// - /// Based on individual reported values, distributions allow to query the maximum, minimum, or - /// average of the reported values, as well as statistical quantiles. With an increasing number - /// of values in the distribution, its accuracy becomes approximate. - /// - /// # Example - /// - /// ``` - /// use sentry::metrics::{Metric, MetricValue}; - /// - /// Metric::build("my.distribution", MetricValue::Distribution(42.0)).send(); - /// ``` - Distribution(DistributionValue), - - /// Counts the number of unique reported values. - /// - /// Sets allow sending arbitrary discrete values, including strings, and store the deduplicated - /// count. With an increasing number of unique values in the set, its accuracy becomes - /// approximate. It is not possible to query individual values from a set. - /// - /// # Example - /// - /// To create a set value, use [`MetricValue::set_from_str`] or - /// [`MetricValue::set_from_display`]. These functions convert the provided argument into a - /// unique hash value, which is then used as the set value. - /// - /// ``` - /// use sentry::metrics::{Metric, MetricValue}; - /// - /// Metric::build("my.set", MetricValue::set_from_str("foo")).send(); - /// ``` - Set(SetValue), - - /// Stores absolute snapshots of values. - /// - /// In addition to plain [counters](Self::Counter), gauges store a snapshot of the maximum, - /// minimum and sum of all values, as well as the last reported value. Note that the "last" - /// component of this aggregation is not commutative. Which value is preserved as last value is - /// implementation-defined. - /// - /// # Example - /// - /// ``` - /// use sentry::metrics::{Metric, MetricValue}; - /// - /// Metric::build("my.gauge", MetricValue::Gauge(42.0)).send(); - /// ``` - Gauge(GaugeValue), -} - -impl MetricValue { - /// Returns a set value representing the given string. - pub fn set_from_str(string: &str) -> Self { - Self::Set(hash_set_value(string)) - } - - /// Returns a set value representing the given argument. - pub fn set_from_display(display: impl fmt::Display) -> Self { - Self::Set(hash_set_value(&display.to_string())) - } - - /// Returns the type of the metric value. - fn ty(&self) -> MetricType { - match self { - Self::Counter(_) => MetricType::Counter, - Self::Distribution(_) => MetricType::Distribution, - Self::Gauge(_) => MetricType::Gauge, - Self::Set(_) => MetricType::Set, - } - } -} - -impl Display for MetricValue { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Counter(v) => write!(f, "{}", v), - Self::Distribution(v) => write!(f, "{}", v), - Self::Gauge(v) => write!(f, "{}", v), - Self::Set(v) => write!(f, "{}", v), - } - } -} - -/// Hashes the given set value. -/// -/// Sets only guarantee 32-bit accuracy, but arbitrary strings are allowed on the protocol. Upon -/// parsing, they are hashed and only used as hashes subsequently. -fn hash_set_value(string: &str) -> u32 { - crc32fast::hash(string.as_bytes()) -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] -enum MetricType { - Counter, - Distribution, - Set, - Gauge, -} - -impl MetricType { - /// Return the shortcode for this metric type. - pub fn as_str(&self) -> &'static str { - match self { - MetricType::Counter => "c", - MetricType::Distribution => "d", - MetricType::Set => "s", - MetricType::Gauge => "g", - } - } -} - -impl fmt::Display for MetricType { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.as_str()) - } -} - -impl std::str::FromStr for MetricType { - type Err = (); - - fn from_str(s: &str) -> Result { - Ok(match s { - "c" | "m" => Self::Counter, - "h" | "d" | "ms" => Self::Distribution, - "s" => Self::Set, - "g" => Self::Gauge, - _ => return Err(()), - }) - } -} - -/// A snapshot of values. -#[derive(Clone, Copy, Debug, PartialEq)] -struct GaugeSummary { - /// The last value reported in the bucket. - /// - /// This aggregation is not commutative. - pub last: GaugeValue, - /// The minimum value reported in the bucket. - pub min: GaugeValue, - /// The maximum value reported in the bucket. - pub max: GaugeValue, - /// The sum of all values reported in the bucket. - pub sum: GaugeValue, - /// The number of times this bucket was updated with a new value. - pub count: u64, -} - -impl GaugeSummary { - /// Creates a gauge snapshot from a single value. - pub fn single(value: GaugeValue) -> Self { - Self { - last: value, - min: value, - max: value, - sum: value, - count: 1, - } - } - - /// Inserts a new value into the gauge. - pub fn insert(&mut self, value: GaugeValue) { - self.last = value; - self.min = self.min.min(value); - self.max = self.max.max(value); - self.sum += value; - self.count += 1; - } -} - -/// The aggregated value of a [`Metric`] bucket. -#[derive(Debug)] -enum BucketValue { - Counter(CounterValue), - Distribution(Vec), - Set(BTreeSet), - Gauge(GaugeSummary), -} - -impl BucketValue { - /// Inserts a new value into the bucket and returns the added weight. - pub fn insert(&mut self, value: MetricValue) -> usize { - match (self, value) { - (Self::Counter(c1), MetricValue::Counter(c2)) => { - *c1 += c2; - 0 - } - (Self::Distribution(d1), MetricValue::Distribution(d2)) => { - d1.push(d2); - 1 - } - (Self::Set(s1), MetricValue::Set(s2)) => { - if s1.insert(s2) { - 1 - } else { - 0 - } - } - (Self::Gauge(g1), MetricValue::Gauge(g2)) => { - g1.insert(g2); - 0 - } - _ => panic!("invalid metric type"), - } - } - - /// Returns the number of values stored in this bucket. - pub fn weight(&self) -> usize { - match self { - BucketValue::Counter(_) => 1, - BucketValue::Distribution(v) => v.len(), - BucketValue::Set(v) => v.len(), - BucketValue::Gauge(_) => 5, - } - } -} - -impl From for BucketValue { - fn from(value: MetricValue) -> Self { - match value { - MetricValue::Counter(v) => Self::Counter(v), - MetricValue::Distribution(v) => Self::Distribution(vec![v]), - MetricValue::Gauge(v) => Self::Gauge(GaugeSummary::single(v)), - MetricValue::Set(v) => Self::Set(BTreeSet::from([v])), - } - } -} - -/// A metric value that contains a numeric value and metadata to be sent to Sentry. -/// -/// # Units -/// -/// To make the most out of metrics in Sentry, consider assigning a unit during construction. This -/// can be achieved using the [`with_unit`](MetricBuilder::with_unit) builder method. See the -/// documentation for more examples on units. -/// -/// ``` -/// use sentry::metrics::{Metric, InformationUnit}; -/// -/// Metric::distribution("request.size", 47.2) -/// .with_unit(InformationUnit::Byte) -/// .send(); -/// ``` -/// -/// # Sending Metrics -/// -/// Metrics can be sent to Sentry directly using the [`send`](MetricBuilder::send) method on the -/// constructor. This will send the metric to the [`Client`](crate::Client) on the current [`Hub`]. -/// If there is no client on the current hub, the metric is dropped. -/// -/// ``` -/// use sentry::metrics::Metric; -/// -/// Metric::count("requests") -/// .with_tag("method", "GET") -/// .send(); -/// ``` -/// -/// # Sending to a Custom Client -/// -/// Metrics can also be sent to a custom client. This is useful if you want to send metrics to a -/// different Sentry project or with different configuration. To do so, finish building the metric -/// and then call [`add_metric`](crate::Client::add_metric) to the client: -/// -/// ``` -/// use sentry::Hub; -/// use sentry::metrics::Metric; -/// -/// let metric = Metric::count("requests") -/// .with_tag("method", "GET") -/// .finish(); -/// -/// // Obtain a client from somewhere -/// if let Some(client) = Hub::current().client() { -/// client.add_metric(metric); -/// } -/// ``` -#[derive(Debug)] -pub struct Metric { - /// The name of the metric, identifying it in Sentry. - /// - /// The name should consist of - name: MetricStr, - unit: MetricUnit, - value: MetricValue, - tags: BTreeMap, - time: Option, -} - -impl Metric { - /// Creates a new metric with the stated name and value. - /// - /// The provided name identifies the metric in Sentry. It should consist of alphanumeric - /// characters and `_`, `-`, and `.`. While a single forward slash (`/`) is also allowed in - /// metric names, it has a special meaning and should not be used in regular metric names. All - /// characters that do not match this criteria are sanitized. - /// - /// The value of the metric determines its type. See the [struct-level](self) docs and - /// constructor methods for examples on how to build metrics. - pub fn build(name: impl Into, value: MetricValue) -> MetricBuilder { - let metric = Metric { - name: name.into(), - unit: MetricUnit::None, - value, - tags: BTreeMap::new(), - time: None, - }; - - MetricBuilder { metric } - } - - /// Parses a metric from a StatsD string. - /// - /// This supports regular StatsD payloads with an extension for tags. In the below example, tags - /// are optional: - /// - /// ```plain - /// :||#:,: - /// ``` - /// - /// Units are encoded into the metric name, separated by an `@`: - /// - /// ```plain - /// @:||#:,: - /// ``` - pub fn parse_statsd(string: &str) -> Result { - parse_metric_opt(string).ok_or(ParseMetricError(())) - } - - /// Builds a metric that increments a [counter](MetricValue::Counter) by the given value. - /// - /// # Example - /// - /// ``` - /// use sentry::metrics::{Metric}; - /// - /// Metric::incr("operation.total_values", 7.0).send(); - /// ``` - pub fn incr(name: impl Into, value: f64) -> MetricBuilder { - Self::build(name, MetricValue::Counter(value)) - } - - /// Builds a metric that [counts](MetricValue::Counter) the single occurrence of an event. - /// - /// # Example - /// - /// ``` - /// use sentry::metrics::{Metric}; - /// - /// Metric::count("requests").send(); - /// ``` - pub fn count(name: impl Into) -> MetricBuilder { - Self::build(name, MetricValue::Counter(1.0)) - } - - /// Builds a metric that tracks the duration of an operation. - /// - /// This is a [distribution](MetricValue::Distribution) metric that is tracked in seconds. - /// - /// # Example - /// - /// ``` - /// use std::time::Duration; - /// use sentry::metrics::{Metric}; - /// - /// Metric::timing("operation", Duration::from_secs(1)).send(); - /// ``` - pub fn timing(name: impl Into, timing: Duration) -> MetricBuilder { - Self::build(name, MetricValue::Distribution(timing.as_secs_f64())) - .with_unit(DurationUnit::Second) - } - - /// Builds a metric that tracks the [distribution](MetricValue::Distribution) of values. - /// - /// # Example - /// - /// ``` - /// use sentry::metrics::{Metric}; - /// - /// Metric::distribution("operation.batch_size", 42.0).send(); - /// ``` - pub fn distribution(name: impl Into, value: f64) -> MetricBuilder { - Self::build(name, MetricValue::Distribution(value)) - } - - /// Builds a metric that tracks the [unique number](MetricValue::Set) of values provided. - /// - /// See [`MetricValue`] for more ways to construct sets. - /// - /// # Example - /// - /// ``` - /// use sentry::metrics::{Metric}; - /// - /// Metric::set("users", "user1").send(); - /// ``` - pub fn set(name: impl Into, string: &str) -> MetricBuilder { - Self::build(name, MetricValue::set_from_str(string)) - } - - /// Builds a metric that tracks the [snapshot](MetricValue::Gauge) of provided values. - /// - /// # Example - /// - /// ``` - /// use sentry::metrics::{Metric}; - /// - /// Metric::gauge("cache.size", 42.0).send(); - /// ``` - pub fn gauge(name: impl Into, value: f64) -> MetricBuilder { - Self::build(name, MetricValue::Gauge(value)) - } - - /// Sends the metric to the current client. - /// - /// When building a metric, you can use [`MetricBuilder::send`] to send the metric directly. If - /// there is no client on the current [`Hub`], the metric is dropped. - pub fn send(self) { - if let Some(client) = Hub::current().client() { - client.add_metric(self); - } - } - - /// Convert the metric into an [`Envelope`] containing a single [`EnvelopeItem::Statsd`]. - pub fn to_envelope(self) -> Envelope { - let timestamp = self - .time - .unwrap_or(SystemTime::now()) - .duration_since(UNIX_EPOCH) - .unwrap_or_default() - .as_secs(); - let data = format!( - "{}@{}:{}|{}|#{}|T{}", - normalization::normalize_name(self.name.as_ref()), - normalization::normalize_unit(self.unit.to_string().as_ref()), - self.value, - self.value.ty(), - normalization::normalize_tags(&self.tags), - timestamp - ); - EnvelopeItem::Statsd(data.into_bytes()).into() - } -} - -/// A builder for metrics. -/// -/// Use one of the [`Metric`] constructors to create a new builder. See the struct-level docs for -/// examples of how to build metrics. -#[must_use] -#[derive(Debug)] -pub struct MetricBuilder { - metric: Metric, -} - -impl MetricBuilder { - /// Sets the unit for the metric. - /// - /// The unit augments the metric value by giving it a magnitude and semantics. Some units have - /// special support when rendering metrics or their values in Sentry, such as for timings. See - /// [`MetricUnit`] for more information on the supported units. The unit can be set to - /// [`MetricUnit::None`] to indicate that the metric has no unit, or to [`MetricUnit::Custom`] - /// to indicate a user-defined unit. - /// - /// By default, the unit is set to [`MetricUnit::None`]. - pub fn with_unit(mut self, unit: impl Into) -> Self { - self.metric.unit = unit.into(); - self - } - - /// Adds a tag to the metric. - /// - /// Tags allow you to add dimensions to metrics. They are key-value pairs that can be filtered - /// or grouped by in Sentry. - /// - /// When sent to Sentry via [`MetricBuilder::send`] or when added to a - /// [`Client`](crate::Client), the client may add default tags to the metrics, such as the - /// `release` or the `environment` from the Scope. - pub fn with_tag(mut self, name: impl Into, value: impl Into) -> Self { - self.metric.tags.insert(name.into(), value.into()); - self - } - - /// Adds multiple tags to the metric. - /// - /// Tags allow you to add dimensions to metrics. They are key-value pairs that can be filtered - /// or grouped by in Sentry. - /// - /// When sent to Sentry via [`MetricBuilder::send`] or when added to a - /// [`Client`](crate::Client), the client may add default tags to the metrics, such as the - /// `release` or the `environment` from the Scope. - pub fn with_tags(mut self, tags: T) -> Self - where - T: IntoIterator, - K: Into, - V: Into, - { - for (k, v) in tags { - self.metric.tags.insert(k.into(), v.into()); - } - self - } - - /// Sets the timestamp for the metric. - /// - /// By default, the timestamp is set to the current time when the metric is built or sent. - pub fn with_time(mut self, time: SystemTime) -> Self { - self.metric.time = Some(time); - self - } - - /// Builds the metric. - pub fn finish(self) -> Metric { - self.metric - } - - /// Sends the metric to the current client. - /// - /// This is a shorthand for `.finish().send()`. If there is no client on the current [`Hub`], - /// the metric is dropped. - pub fn send(self) { - self.finish().send() - } -} - -/// Error emitted from [`Metric::parse_statsd`] for invalid metric strings. -#[derive(Debug)] -pub struct ParseMetricError(()); - -impl std::error::Error for ParseMetricError {} - -impl fmt::Display for ParseMetricError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("invalid metric string") - } -} - -fn parse_metric_opt(string: &str) -> Option { - let mut components = string.split('|'); - - let (mri_str, value_str) = components.next()?.split_once(':')?; - let (name, unit) = match mri_str.split_once('@') { - Some((name, unit_str)) => (name, unit_str.parse().ok()?), - None => (mri_str, MetricUnit::None), - }; - - let ty = components.next().and_then(|s| s.parse().ok())?; - let value = match ty { - MetricType::Counter => MetricValue::Counter(value_str.parse().ok()?), - MetricType::Distribution => MetricValue::Distribution(value_str.parse().ok()?), - MetricType::Set => MetricValue::Set(value_str.parse().ok()?), - MetricType::Gauge => { - // Gauge values are serialized as `last:min:max:sum:count`. We want to be able - // to parse those strings back, so we just take the first colon-separated segment. - let value_str = value_str.split(':').next().unwrap(); - MetricValue::Gauge(value_str.parse().ok()?) - } - }; - - let mut builder = Metric::build(name.to_owned(), value).with_unit(unit); - - for component in components { - if let Some('#') = component.chars().next() { - for pair in component.get(1..)?.split(',') { - let mut key_value = pair.splitn(2, ':'); - - let key = key_value.next()?.to_owned(); - let value = key_value.next().unwrap_or_default().to_owned(); - - builder = builder.with_tag(key, value); - } - } - } - - Some(builder.finish()) -} - -/// Composite bucket key for [`BucketMap`]. -#[derive(Debug, PartialEq, Eq, Hash)] -struct BucketKey { - ty: MetricType, - name: MetricStr, - unit: MetricUnit, - tags: BTreeMap, -} - -/// UNIX timestamp used for buckets. -type Timestamp = u64; - -/// A nested map storing metric buckets. -/// -/// This map consists of two levels: -/// 1. The rounded UNIX timestamp of buckets. -/// 2. The metric buckets themselves with a corresponding timestamp. -/// -/// This structure allows for efficient dequeueing of buckets that are older than a certain -/// threshold. The buckets are dequeued in order of their timestamp, so the oldest buckets are -/// dequeued first. -type BucketMap = BTreeMap>; - -#[derive(Debug)] -struct SharedAggregatorState { - buckets: BucketMap, - weight: usize, - running: bool, - force_flush: bool, -} - -impl SharedAggregatorState { - pub fn new() -> Self { - Self { - buckets: BTreeMap::new(), - weight: 0, - running: true, - force_flush: false, - } - } - - /// Adds a new bucket to the aggregator. - /// - /// The bucket timestamp is rounded to the nearest bucket interval. Note that this does NOT - /// automatically flush the aggregator if the weight exceeds the weight threshold. - pub fn add(&mut self, mut timestamp: Timestamp, key: BucketKey, value: MetricValue) { - // Floor timestamp to bucket interval - timestamp /= BUCKET_INTERVAL.as_secs(); - timestamp *= BUCKET_INTERVAL.as_secs(); - - match self.buckets.entry(timestamp).or_default().entry(key) { - Entry::Occupied(mut e) => self.weight += e.get_mut().insert(value), - Entry::Vacant(e) => self.weight += e.insert(value.into()).weight(), - } - } - - /// Removes and returns all buckets that are ready to flush. - /// - /// Buckets are ready to flush as soon as their time window has closed. For example, a bucket - /// from timestamps `[4600, 4610)` is ready to flush immediately at `4610`. - pub fn take_buckets(&mut self) -> BucketMap { - if self.force_flush || !self.running { - self.weight = 0; - self.force_flush = false; - std::mem::take(&mut self.buckets) - } else { - let timestamp = SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap_or_default() - .saturating_sub(BUCKET_INTERVAL) - .as_secs(); - - // Split all buckets after the cutoff time. `split` contains newer buckets, which should - // remain, so swap them. After the swap, `split` contains all older buckets. - let mut split = self.buckets.split_off(×tamp); - std::mem::swap(&mut split, &mut self.buckets); - - self.weight -= split - .values() - .flat_map(|map| map.values()) - .map(|bucket| bucket.weight()) - .sum::(); - - split - } - } - - pub fn weight(&self) -> usize { - self.weight - } -} - -type TagMap = BTreeMap; - -fn get_default_tags(options: &ClientOptions) -> TagMap { - let mut tags = TagMap::new(); - if let Some(ref release) = options.release { - tags.insert("release".into(), release.clone()); - } - tags.insert( - "environment".into(), - options - .environment - .clone() - .filter(|e| !e.is_empty()) - .unwrap_or(Cow::Borrowed("production")), - ); - tags -} - -#[derive(Clone)] -struct Worker { - shared: Arc>, - default_tags: TagMap, - transport: TransportArc, -} - -impl Worker { - pub fn run(self) { - loop { - // Park instead of sleep so we can wake the thread up. Do not account for delays during - // flushing, since we benefit from some drift to spread out metric submissions. - thread::park_timeout(FLUSH_INTERVAL); - - let buckets = { - let mut guard = self.shared.lock().unwrap(); - if !guard.running { - break; - } - guard.take_buckets() - }; - - self.flush_buckets(buckets); - } - } - - pub fn flush_buckets(&self, buckets: BucketMap) { - if buckets.is_empty() { - return; - } - - // The transport is usually available when flush is called. Prefer a short lock and worst - // case throw away the result rather than blocking the transport for too long. - if let Ok(output) = self.format_payload(buckets) { - let mut envelope = Envelope::new(); - envelope.add_item(EnvelopeItem::Statsd(output)); - - if let Some(ref transport) = *self.transport.read().unwrap() { - transport.send_envelope(envelope); - } - } - } - - fn format_payload(&self, buckets: BucketMap) -> std::io::Result> { - use std::io::Write; - let mut out = vec![]; - - for (timestamp, buckets) in buckets { - for (key, value) in buckets { - write!( - &mut out, - "{}", - normalization::normalize_name(key.name.as_ref()) - )?; - match key.unit { - MetricUnit::Custom(u) => { - write!(&mut out, "@{}", normalization::normalize_unit(u.as_ref()))? - } - _ => write!(&mut out, "@{}", key.unit)?, - } - match value { - BucketValue::Counter(c) => { - write!(&mut out, ":{}", c)?; - } - BucketValue::Distribution(d) => { - for v in d { - write!(&mut out, ":{}", v)?; - } - } - BucketValue::Set(s) => { - for v in s { - write!(&mut out, ":{}", v)?; - } - } - BucketValue::Gauge(g) => { - write!( - &mut out, - ":{}:{}:{}:{}:{}", - g.last, g.min, g.max, g.sum, g.count - )?; - } - } - - write!(&mut out, "|{}", key.ty.as_str())?; - let normalized_tags = - normalization::normalize_tags(&key.tags).with_default_tags(&self.default_tags); - write!(&mut out, "|#{}", normalized_tags)?; - writeln!(&mut out, "|T{}", timestamp)?; - } - } - - Ok(out) - } -} - -impl fmt::Debug for Worker { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Worker") - .field("transport", &format_args!("ArcTransport")) - .field("default_tags", &self.default_tags) - .finish() - } -} - -#[derive(Debug)] -pub(crate) struct MetricAggregator { - local_worker: Worker, - handle: Option>, -} - -impl MetricAggregator { - pub fn new(transport: TransportArc, options: &ClientOptions) -> Self { - let worker = Worker { - shared: Arc::new(Mutex::new(SharedAggregatorState::new())), - default_tags: get_default_tags(options), - transport, - }; - - let local_worker = worker.clone(); - - let handle = thread::Builder::new() - .name("sentry-metrics".into()) - .spawn(move || worker.run()) - .expect("failed to spawn thread"); - - Self { - local_worker, - handle: Some(handle), - } - } - - pub fn add(&self, metric: Metric) { - let Metric { - name, - unit, - value, - tags, - time, - } = metric; - - let timestamp = time - .unwrap_or_else(SystemTime::now) - .duration_since(UNIX_EPOCH) - .unwrap_or_default() - .as_secs(); - - let key = BucketKey { - ty: value.ty(), - name, - unit, - tags, - }; - - let mut guard = self.local_worker.shared.lock().unwrap(); - guard.add(timestamp, key, value); - - if guard.weight() > MAX_WEIGHT { - if let Some(ref handle) = self.handle { - guard.force_flush = true; - handle.thread().unpark(); - } - } - } - - pub fn flush(&self) { - let buckets = { - let mut guard = self.local_worker.shared.lock().unwrap(); - guard.force_flush = true; - guard.take_buckets() - }; - - self.local_worker.flush_buckets(buckets); - } -} - -impl Drop for MetricAggregator { - fn drop(&mut self) { - let buckets = { - let mut guard = self.local_worker.shared.lock().unwrap(); - guard.running = false; - guard.take_buckets() - }; - - self.local_worker.flush_buckets(buckets); - - if let Some(handle) = self.handle.take() { - handle.thread().unpark(); - handle.join().unwrap(); - } - } -} - -#[cfg(test)] -mod tests { - use crate::test::{with_captured_envelopes, with_captured_envelopes_options}; - use crate::ClientOptions; - - use super::*; - - /// Returns the current system time and rounded bucket timestamp. - fn current_time() -> (SystemTime, u64) { - let now = SystemTime::now(); - let timestamp = now.duration_since(UNIX_EPOCH).unwrap_or_default().as_secs(); - let timestamp = timestamp / 10 * 10; - - (now, timestamp) - } - - fn get_single_metrics(envelopes: &[Envelope]) -> &str { - assert_eq!(envelopes.len(), 1, "expected exactly one envelope"); - - let mut items = envelopes[0].items(); - let Some(EnvelopeItem::Statsd(payload)) = items.next() else { - panic!("expected metrics item"); - }; - - std::str::from_utf8(payload).unwrap().trim() - } - - #[test] - fn test_tags() { - let (time, ts) = current_time(); - - let envelopes = with_captured_envelopes(|| { - Metric::count("my.metric") - .with_tag("foo", "bar") - .with_tag("and", "more") - .with_time(time) - .send(); - }); - - let metrics = get_single_metrics(&envelopes); - assert_eq!( - metrics, - format!("my.metric@none:1|c|#and:more,environment:production,foo:bar|T{ts}") - ); - } - - #[test] - fn test_unit() { - let (time, ts) = current_time(); - - let envelopes = with_captured_envelopes(|| { - Metric::count("my.metric") - .with_time(time) - .with_unit("custom") - .send(); - }); - - let metrics = get_single_metrics(&envelopes); - assert_eq!( - metrics, - format!("my.metric@custom:1|c|#environment:production|T{ts}") - ); - } - - #[test] - fn test_metric_sanitation() { - let (time, ts) = current_time(); - - let envelopes = with_captured_envelopes(|| { - Metric::count("my$$$metric").with_time(time).send(); - }); - - let metrics = get_single_metrics(&envelopes); - assert_eq!( - metrics, - format!("my___metric@none:1|c|#environment:production|T{ts}") - ); - } - - #[test] - fn test_tag_sanitation() { - let (time, ts) = current_time(); - - let envelopes = with_captured_envelopes(|| { - Metric::count("my.metric") - .with_tag("foo-bar$$$blub", "%$föö{}") - .with_time(time) - .send(); - }); - - let metrics = get_single_metrics(&envelopes); - assert_eq!( - metrics, - format!("my.metric@none:1|c|#environment:production,foo-barblub:%$föö{{}}|T{ts}") - ); - } - - #[test] - fn test_default_tags() { - let (time, ts) = current_time(); - - let options = ClientOptions { - release: Some("myapp@1.0.0".into()), - environment: Some("development".into()), - ..Default::default() - }; - - let envelopes = with_captured_envelopes_options( - || { - Metric::count("requests") - .with_tag("foo", "bar") - .with_time(time) - .send(); - }, - options, - ); - - let metrics = get_single_metrics(&envelopes); - assert_eq!( - metrics, - format!("requests@none:1|c|#environment:development,foo:bar,release:myapp@1.0.0|T{ts}") - ); - } - - #[test] - fn test_empty_default_tags() { - let (time, ts) = current_time(); - let options = ClientOptions { - release: Some("".into()), - environment: Some("".into()), - ..Default::default() - }; - - let envelopes = with_captured_envelopes_options( - || { - Metric::count("requests") - .with_tag("foo", "bar") - .with_time(time) - .send(); - }, - options, - ); - - let metrics = get_single_metrics(&envelopes); - assert_eq!( - metrics, - format!("requests@none:1|c|#environment:production,foo:bar|T{ts}") - ); - } - - #[test] - fn test_override_default_tags() { - let (time, ts) = current_time(); - let options = ClientOptions { - release: Some("default_release".into()), - environment: Some("default_env".into()), - ..Default::default() - }; - - let envelopes = with_captured_envelopes_options( - || { - Metric::count("requests") - .with_tag("environment", "custom_env") - .with_tag("release", "custom_release") - .with_time(time) - .send(); - }, - options, - ); - - let metrics = get_single_metrics(&envelopes); - assert_eq!( - metrics, - format!("requests@none:1|c|#environment:custom_env,release:custom_release|T{ts}") - ); - } - - #[test] - fn test_counter() { - let (time, ts) = current_time(); - - let envelopes = with_captured_envelopes(|| { - Metric::count("my.metric").with_time(time).send(); - Metric::incr("my.metric", 2.0).with_time(time).send(); - }); - - let metrics = get_single_metrics(&envelopes); - assert_eq!( - metrics, - format!("my.metric@none:3|c|#environment:production|T{ts}") - ); - } - - #[test] - fn test_timing() { - let (time, ts) = current_time(); - - let envelopes = with_captured_envelopes(|| { - Metric::timing("my.metric", Duration::from_millis(200)) - .with_time(time) - .send(); - Metric::timing("my.metric", Duration::from_millis(100)) - .with_time(time) - .send(); - }); - - let metrics = get_single_metrics(&envelopes); - assert_eq!( - metrics, - format!("my.metric@second:0.2:0.1|d|#environment:production|T{ts}") - ); - } - - #[test] - fn test_distribution() { - let (time, ts) = current_time(); - - let envelopes = with_captured_envelopes(|| { - Metric::distribution("my.metric", 2.0) - .with_time(time) - .send(); - Metric::distribution("my.metric", 1.0) - .with_time(time) - .send(); - }); - - let metrics = get_single_metrics(&envelopes); - assert_eq!( - metrics, - format!("my.metric@none:2:1|d|#environment:production|T{ts}") - ); - } - - #[test] - fn test_set() { - let (time, ts) = current_time(); - - let envelopes = with_captured_envelopes(|| { - Metric::set("my.metric", "hello").with_time(time).send(); - // Duplicate that should not be reflected twice - Metric::set("my.metric", "hello").with_time(time).send(); - Metric::set("my.metric", "world").with_time(time).send(); - }); - - let metrics = get_single_metrics(&envelopes); - assert_eq!( - metrics, - format!("my.metric@none:907060870:980881731|s|#environment:production|T{ts}") - ); - } - - #[test] - fn test_gauge() { - let (time, ts) = current_time(); - - let envelopes = with_captured_envelopes(|| { - Metric::gauge("my.metric", 2.0).with_time(time).send(); - Metric::gauge("my.metric", 1.0).with_time(time).send(); - Metric::gauge("my.metric", 1.5).with_time(time).send(); - }); - - let metrics = get_single_metrics(&envelopes); - assert_eq!( - metrics, - format!("my.metric@none:1.5:1:2:4.5:3|g|#environment:production|T{ts}") - ); - } - - #[test] - fn test_multiple() { - let (time, ts) = current_time(); - - let envelopes = with_captured_envelopes(|| { - Metric::count("my.metric").with_time(time).send(); - Metric::distribution("my.dist", 2.0).with_time(time).send(); - }); - - let metrics = get_single_metrics(&envelopes); - println!("{metrics}"); - - assert!(metrics.contains(&format!("my.metric@none:1|c|#environment:production|T{ts}"))); - assert!(metrics.contains(&format!("my.dist@none:2|d|#environment:production|T{ts}"))); - } - - #[test] - fn test_regression_parse_statsd() { - let payload = "docker.net.bytes_rcvd:27763.20237096717:27763.20237096717:27763.20237096717:27763.20237096717:1|g|#container_id:97df61f5c55b58ec9c04da3e03edc8a875ec90eb405eb5645ad9a86d0a7cd3ee,container_name:app_sidekiq_1"; - let metric = Metric::parse_statsd(payload).unwrap(); - assert_eq!(metric.name, "docker.net.bytes_rcvd"); - assert_eq!(metric.value, MetricValue::Gauge(27763.20237096717)); - assert_eq!( - metric.tags["container_id"], - "97df61f5c55b58ec9c04da3e03edc8a875ec90eb405eb5645ad9a86d0a7cd3ee" - ); - assert_eq!(metric.tags["container_name"], "app_sidekiq_1"); - } -} diff --git a/sentry-core/src/metrics/normalization/mod.rs b/sentry-core/src/metrics/normalization/mod.rs deleted file mode 100644 index 2b228b90b..000000000 --- a/sentry-core/src/metrics/normalization/mod.rs +++ /dev/null @@ -1,28 +0,0 @@ -pub mod normalized_name; -pub mod normalized_tags; -pub mod normalized_unit; - -pub use normalized_name::normalize_name; -pub use normalized_tags::normalize_tags; -pub use normalized_unit::normalize_unit; - -pub fn truncate(s: &str, max_chars: usize) -> &str { - match s.char_indices().nth(max_chars) { - None => s, - Some((i, _)) => &s[..i], - } -} - -#[cfg(test)] -mod test { - - #[test] - fn test_truncate_ascii_chars() { - assert_eq!("abc", super::truncate("abcde", 3)); - } - - #[test] - fn test_truncate_unicode_chars() { - assert_eq!("😀😀😀", super::truncate("😀😀😀😀😀", 3)); - } -} diff --git a/sentry-core/src/metrics/normalization/normalized_name.rs b/sentry-core/src/metrics/normalization/normalized_name.rs deleted file mode 100644 index 4abc2fe1e..000000000 --- a/sentry-core/src/metrics/normalization/normalized_name.rs +++ /dev/null @@ -1,33 +0,0 @@ -use std::{borrow::Cow, sync::OnceLock}; - -use regex::Regex; - -pub fn normalize_name(name: &str) -> Cow { - static METRIC_NAME_RE: OnceLock = OnceLock::new(); - METRIC_NAME_RE - .get_or_init(|| Regex::new(r"[^a-zA-Z0-9_\-.]").expect("Regex should compile")) - .replace_all(super::truncate(name, 150), "_") -} - -#[cfg(test)] -mod test { - - #[test] - fn test_from() { - let expected = "aA1_-.____________"; - - let actual = super::normalize_name("aA1_-./+ö{😀\n\t\r\\| ,"); - - assert_eq!(expected, actual); - } - - #[test] - fn test_length_restriction() { - let expected = "a".repeat(150); - - let too_long_name = "a".repeat(155); - let actual = super::normalize_name(&too_long_name); - - assert_eq!(expected, actual); - } -} diff --git a/sentry-core/src/metrics/normalization/normalized_tags.rs b/sentry-core/src/metrics/normalization/normalized_tags.rs deleted file mode 100644 index 78cb77148..000000000 --- a/sentry-core/src/metrics/normalization/normalized_tags.rs +++ /dev/null @@ -1,181 +0,0 @@ -use regex::Regex; -use std::borrow::Cow; -use std::collections::BTreeMap; -use std::fmt::Write; -use std::sync::OnceLock; - -use crate::metrics::TagMap; - -pub fn normalize_tags(tags: &TagMap) -> NormalizedTags { - NormalizedTags { - tags: tags - .iter() - .map(|(k, v)| { - ( - NormalizedTags::normalize_key(super::truncate(k, 32)), - NormalizedTags::normalize_value(super::truncate(v, 200)), - ) - }) - .filter(|(k, v)| !k.is_empty() && !v.is_empty()) - .collect(), - } -} - -pub struct NormalizedTags<'a> { - tags: BTreeMap, String>, -} - -impl<'a> NormalizedTags<'a> { - pub fn with_default_tags(mut self, tags: &'a TagMap) -> Self { - for (k, v) in tags { - let k = Self::normalize_key(super::truncate(k, 32)); - let v = Self::normalize_value(super::truncate(v, 200)); - if !k.is_empty() && !v.is_empty() { - self.tags.entry(k).or_insert(v); - } - } - self - } - - fn normalize_key(key: &str) -> Cow { - static METRIC_TAG_KEY_RE: OnceLock = OnceLock::new(); - METRIC_TAG_KEY_RE - .get_or_init(|| Regex::new(r"[^a-zA-Z0-9_\-./]").expect("Regex should compile")) - .replace_all(key, "") - } - - fn normalize_value(value: &str) -> String { - let mut escaped = String::with_capacity(value.len()); - for c in value.chars() { - match c { - '\t' => escaped.push_str("\\t"), - '\n' => escaped.push_str("\\n"), - '\r' => escaped.push_str("\\r"), - '\\' => escaped.push_str("\\\\"), - '|' => escaped.push_str("\\u{7c}"), - ',' => escaped.push_str("\\u{2c}"), - _ if c.is_control() => (), - _ => escaped.push(c), - } - } - escaped - } -} - -impl std::fmt::Display for NormalizedTags<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - for (i, (k, v)) in self.tags.iter().enumerate() { - if i > 0 { - f.write_char(',')?; - } - write!(f, "{k}:{v}")?; - } - Ok(()) - } -} - -#[cfg(test)] -mod test { - use super::TagMap; - - #[test] - fn test_replacement_characters() { - let tags = TagMap::from_iter( - [ - ("a\na", "a\na"), - ("b\rb", "b\rb"), - ("c\tc", "c\tc"), - ("d\\d", "d\\d"), - ("e|e", "e|e"), - ("f,f", "f,f"), - ] - .into_iter() - .map(|(k, v)| (k.into(), v.into())), - ); - let expected = "aa:a\\na,bb:b\\rb,cc:c\\tc,dd:d\\\\d,ee:e\\u{7c}e,ff:f\\u{2c}f"; - - let actual = super::normalize_tags(&tags).to_string(); - - assert_eq!(expected, actual); - } - - #[test] - fn test_empty_tags() { - let tags = TagMap::from_iter( - [("+", "a"), ("a", ""), ("", "a"), ("", "")] - .into_iter() - .map(|(k, v)| (k.into(), v.into())), - ); - let expected = ""; - - let actual = super::normalize_tags(&tags).to_string(); - - assert_eq!(expected, actual); - } - - #[test] - fn test_special_characters() { - let tags = TagMap::from([("aA1_-./+ö{ 😀".into(), "aA1_-./+ö{ 😀".into())]); - let expected = "aA1_-./:aA1_-./+ö{ 😀"; - - let actual = super::normalize_tags(&tags).to_string(); - - assert_eq!(expected, actual); - } - - #[test] - fn test_add_default_tags() { - let default_tags = TagMap::from([ - ("release".into(), "default_release".into()), - ("environment".into(), "production".into()), - ]); - let expected = "environment:production,release:default_release"; - - let actual = super::normalize_tags(&TagMap::new()) - .with_default_tags(&default_tags) - .to_string(); - - assert_eq!(expected, actual); - } - - #[test] - fn test_override_default_tags() { - let default_tags = TagMap::from([ - ("release".into(), "default_release".into()), - ("environment".into(), "production".into()), - ]); - let expected = "environment:custom_env,release:custom_release"; - - let actual = super::normalize_tags(&TagMap::from([ - ("release".into(), "custom_release".into()), - ("environment".into(), "custom_env".into()), - ])) - .with_default_tags(&default_tags) - .to_string(); - - assert_eq!(expected, actual); - } - - #[test] - fn test_length_restriction() { - let expected = "dk".repeat(16) - + ":" - + "dv".repeat(100).as_str() - + "," - + "k".repeat(32).as_str() - + ":" - + "v".repeat(200).as_str(); - - let actual = super::normalize_tags(&TagMap::from([( - "k".repeat(35).into(), - "v".repeat(210).into(), - )])) - .with_default_tags(&TagMap::from([( - "dk".repeat(35).into(), - "dv".repeat(210).into(), - )])) - .to_string(); - - assert_eq!(expected, actual); - } -} diff --git a/sentry-core/src/metrics/normalization/normalized_unit.rs b/sentry-core/src/metrics/normalization/normalized_unit.rs deleted file mode 100644 index e6b488b12..000000000 --- a/sentry-core/src/metrics/normalization/normalized_unit.rs +++ /dev/null @@ -1,57 +0,0 @@ -use std::{borrow::Cow, sync::OnceLock}; - -use regex::Regex; - -use crate::units::MetricUnit; - -pub fn normalize_unit(unit: &str) -> Cow { - static METRIC_UNIT_RE: OnceLock = OnceLock::new(); - let normalized_unit = METRIC_UNIT_RE - .get_or_init(|| Regex::new(r"[^a-zA-Z0-9_]").expect("Regex should compile")) - .replace_all(super::truncate(unit, 15), ""); - if normalized_unit.is_empty() { - MetricUnit::None.to_string().into() - } else { - normalized_unit - } -} - -#[cfg(test)] -mod test { - - #[test] - fn test_from() { - let expected = "aA1_"; - - let actual = super::normalize_unit("aA1_-./+ö{😀\n\t\r\\| ,").to_string(); - - assert_eq!(expected, actual); - } - - #[test] - fn test_from_empty() { - let expected = "none"; - - let actual = super::normalize_unit("").to_string(); - - assert_eq!(expected, actual); - } - - #[test] - fn test_from_empty_after_normalization() { - let expected = "none"; - - let actual = super::normalize_unit("+").to_string(); - - assert_eq!(expected, actual); - } - - #[test] - fn test_length_restriction() { - let expected = "a".repeat(15); - - let actual = super::normalize_unit("a".repeat(20).as_ref()).to_string(); - - assert_eq!(expected, actual); - } -} diff --git a/sentry-core/src/units.rs b/sentry-core/src/units.rs deleted file mode 100644 index a0f5026c8..000000000 --- a/sentry-core/src/units.rs +++ /dev/null @@ -1,266 +0,0 @@ -//! Type definitions for Sentry metrics. - -use std::borrow::Cow; -use std::fmt; - -/// The unit of measurement of a metric value. -/// -/// Units augment metric values by giving them a magnitude and semantics. There are certain types of -/// units that are subdivided in their precision: -/// - [`DurationUnit`]: time durations -/// - [`InformationUnit`]: sizes of information -/// - [`FractionUnit`]: fractions -/// -/// You are not restricted to these units, but can use any `&'static str` or `String` as a unit. -#[derive(Clone, Debug, Eq, PartialEq, Hash, Default)] -pub enum MetricUnit { - /// A time duration, defaulting to `"millisecond"`. - Duration(DurationUnit), - /// Size of information derived from bytes, defaulting to `"byte"`. - Information(InformationUnit), - /// Fractions such as percentages, defaulting to `"ratio"`. - Fraction(FractionUnit), - /// user-defined units without builtin conversion or default. - Custom(Cow<'static, str>), - /// Untyped value without a unit (`""`). - #[default] - None, -} - -impl MetricUnit { - /// Returns `true` if the metric_unit is [`None`]. - pub fn is_none(&self) -> bool { - matches!(self, Self::None) - } -} - -impl fmt::Display for MetricUnit { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - MetricUnit::Duration(u) => u.fmt(f), - MetricUnit::Information(u) => u.fmt(f), - MetricUnit::Fraction(u) => u.fmt(f), - MetricUnit::Custom(u) => u.fmt(f), - MetricUnit::None => f.write_str("none"), - } - } -} - -impl std::str::FromStr for MetricUnit { - type Err = ParseMetricUnitError; - - fn from_str(s: &str) -> Result { - Ok(match s { - "nanosecond" | "ns" => Self::Duration(DurationUnit::NanoSecond), - "microsecond" => Self::Duration(DurationUnit::MicroSecond), - "millisecond" | "ms" => Self::Duration(DurationUnit::MilliSecond), - "second" | "s" => Self::Duration(DurationUnit::Second), - "minute" => Self::Duration(DurationUnit::Minute), - "hour" => Self::Duration(DurationUnit::Hour), - "day" => Self::Duration(DurationUnit::Day), - "week" => Self::Duration(DurationUnit::Week), - - "bit" => Self::Information(InformationUnit::Bit), - "byte" => Self::Information(InformationUnit::Byte), - "kilobyte" => Self::Information(InformationUnit::KiloByte), - "kibibyte" => Self::Information(InformationUnit::KibiByte), - "megabyte" => Self::Information(InformationUnit::MegaByte), - "mebibyte" => Self::Information(InformationUnit::MebiByte), - "gigabyte" => Self::Information(InformationUnit::GigaByte), - "gibibyte" => Self::Information(InformationUnit::GibiByte), - "terabyte" => Self::Information(InformationUnit::TeraByte), - "tebibyte" => Self::Information(InformationUnit::TebiByte), - "petabyte" => Self::Information(InformationUnit::PetaByte), - "pebibyte" => Self::Information(InformationUnit::PebiByte), - "exabyte" => Self::Information(InformationUnit::ExaByte), - "exbibyte" => Self::Information(InformationUnit::ExbiByte), - - "ratio" => Self::Fraction(FractionUnit::Ratio), - "percent" => Self::Fraction(FractionUnit::Percent), - - "" | "none" => Self::None, - _ => Self::Custom(s.to_owned().into()), - }) - } -} - -impl From for MetricUnit { - fn from(unit: DurationUnit) -> Self { - Self::Duration(unit) - } -} - -impl From for MetricUnit { - fn from(unit: InformationUnit) -> Self { - Self::Information(unit) - } -} - -impl From for MetricUnit { - fn from(unit: FractionUnit) -> Self { - Self::Fraction(unit) - } -} - -impl From<&'static str> for MetricUnit { - fn from(unit: &'static str) -> Self { - Self::Custom(unit.into()) - } -} - -impl From for MetricUnit { - fn from(unit: String) -> Self { - Self::Custom(unit.into()) - } -} - -impl From> for MetricUnit { - fn from(unit: Cow<'static, str>) -> Self { - Self::Custom(unit) - } -} - -impl From> for MetricUnit { - fn from(unit: Option) -> Self { - unit.map_or_else(|| Self::None, |u| Self::Custom(u.into())) - } -} - -/// Time duration units used in [`MetricUnit::Duration`]. -/// -/// Defaults to `millisecond`. -#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] -pub enum DurationUnit { - /// Nanosecond (`"nanosecond"`), 10^-9 seconds. - NanoSecond, - /// Microsecond (`"microsecond"`), 10^-6 seconds. - MicroSecond, - /// Millisecond (`"millisecond"`), 10^-3 seconds. - MilliSecond, - /// Full second (`"second"`). - Second, - /// Minute (`"minute"`), 60 seconds. - Minute, - /// Hour (`"hour"`), 3600 seconds. - Hour, - /// Day (`"day"`), 86,400 seconds. - Day, - /// Week (`"week"`), 604,800 seconds. - Week, -} - -impl Default for DurationUnit { - fn default() -> Self { - Self::MilliSecond - } -} - -impl fmt::Display for DurationUnit { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::NanoSecond => f.write_str("nanosecond"), - Self::MicroSecond => f.write_str("microsecond"), - Self::MilliSecond => f.write_str("millisecond"), - Self::Second => f.write_str("second"), - Self::Minute => f.write_str("minute"), - Self::Hour => f.write_str("hour"), - Self::Day => f.write_str("day"), - Self::Week => f.write_str("week"), - } - } -} - -/// An error parsing a [`MetricUnit`] or one of its variants. -#[derive(Clone, Copy, Debug)] -pub struct ParseMetricUnitError(()); - -/// Size of information derived from bytes, used in [`MetricUnit::Information`]. -/// -/// Defaults to `byte`. See also [Units of -/// information](https://en.wikipedia.org/wiki/Units_of_information). -#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] -pub enum InformationUnit { - /// Bit (`"bit"`), corresponding to 1/8 of a byte. - /// - /// Note that there are computer systems with a different number of bits per byte. - Bit, - /// Byte (`"byte"`). - Byte, - /// Kilobyte (`"kilobyte"`), 10^3 bytes. - KiloByte, - /// Kibibyte (`"kibibyte"`), 2^10 bytes. - KibiByte, - /// Megabyte (`"megabyte"`), 10^6 bytes. - MegaByte, - /// Mebibyte (`"mebibyte"`), 2^20 bytes. - MebiByte, - /// Gigabyte (`"gigabyte"`), 10^9 bytes. - GigaByte, - /// Gibibyte (`"gibibyte"`), 2^30 bytes. - GibiByte, - /// Terabyte (`"terabyte"`), 10^12 bytes. - TeraByte, - /// Tebibyte (`"tebibyte"`), 2^40 bytes. - TebiByte, - /// Petabyte (`"petabyte"`), 10^15 bytes. - PetaByte, - /// Pebibyte (`"pebibyte"`), 2^50 bytes. - PebiByte, - /// Exabyte (`"exabyte"`), 10^18 bytes. - ExaByte, - /// Exbibyte (`"exbibyte"`), 2^60 bytes. - ExbiByte, -} - -impl Default for InformationUnit { - fn default() -> Self { - Self::Byte - } -} - -impl fmt::Display for InformationUnit { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Bit => f.write_str("bit"), - Self::Byte => f.write_str("byte"), - Self::KiloByte => f.write_str("kilobyte"), - Self::KibiByte => f.write_str("kibibyte"), - Self::MegaByte => f.write_str("megabyte"), - Self::MebiByte => f.write_str("mebibyte"), - Self::GigaByte => f.write_str("gigabyte"), - Self::GibiByte => f.write_str("gibibyte"), - Self::TeraByte => f.write_str("terabyte"), - Self::TebiByte => f.write_str("tebibyte"), - Self::PetaByte => f.write_str("petabyte"), - Self::PebiByte => f.write_str("pebibyte"), - Self::ExaByte => f.write_str("exabyte"), - Self::ExbiByte => f.write_str("exbibyte"), - } - } -} - -/// Units of fraction used in [`MetricUnit::Fraction`]. -/// -/// Defaults to `ratio`. -#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] -pub enum FractionUnit { - /// Floating point fraction of `1`. - Ratio, - /// Ratio expressed as a fraction of `100`. `100%` equals a ratio of `1.0`. - Percent, -} - -impl Default for FractionUnit { - fn default() -> Self { - Self::Ratio - } -} - -impl fmt::Display for FractionUnit { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Ratio => f.write_str("ratio"), - Self::Percent => f.write_str("percent"), - } - } -} diff --git a/sentry-types/Cargo.toml b/sentry-types/Cargo.toml index 2f981db64..88ed1d021 100644 --- a/sentry-types/Cargo.toml +++ b/sentry-types/Cargo.toml @@ -19,7 +19,6 @@ all-features = true [features] default = ["protocol"] protocol = [] -metrics = [] [dependencies] debugid = { version = "0.8.0", features = ["serde"] } diff --git a/sentry-types/src/protocol/envelope.rs b/sentry-types/src/protocol/envelope.rs index 1a4e67ca8..1d7452f6d 100644 --- a/sentry-types/src/protocol/envelope.rs +++ b/sentry-types/src/protocol/envelope.rs @@ -64,10 +64,6 @@ enum EnvelopeItemType { /// A Monitor Check In Item Type #[serde(rename = "check_in")] MonitorCheckIn, - /// A Metrics Item type. - #[cfg(feature = "metrics")] - #[serde(rename = "statsd")] - Metrics, } /// An Envelope Item Header. @@ -116,9 +112,6 @@ pub enum EnvelopeItem { Attachment(Attachment), /// A MonitorCheckIn item. MonitorCheckIn(MonitorCheckIn), - /// A Metrics Item. - #[cfg(feature = "metrics")] - Statsd(Vec), /// This is a sentinel item used to `filter` raw envelopes. Raw, // TODO: @@ -359,8 +352,6 @@ impl Envelope { EnvelopeItem::MonitorCheckIn(check_in) => { serde_json::to_writer(&mut item_buf, check_in)? } - #[cfg(feature = "metrics")] - EnvelopeItem::Statsd(statsd) => item_buf.extend_from_slice(statsd), EnvelopeItem::Raw => { continue; } @@ -371,8 +362,6 @@ impl Envelope { EnvelopeItem::SessionAggregates(_) => "sessions", EnvelopeItem::Transaction(_) => "transaction", EnvelopeItem::MonitorCheckIn(_) => "check_in", - #[cfg(feature = "metrics")] - EnvelopeItem::Statsd(_) => "statsd", EnvelopeItem::Attachment(_) | EnvelopeItem::Raw => unreachable!(), }; writeln!( @@ -517,8 +506,6 @@ impl Envelope { EnvelopeItemType::MonitorCheckIn => { serde_json::from_slice(payload).map(EnvelopeItem::MonitorCheckIn) } - #[cfg(feature = "metrics")] - EnvelopeItemType::Metrics => Ok(EnvelopeItem::Statsd(payload.into())), } .map_err(EnvelopeError::InvalidItemPayload)?; diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index 79d83ee65..e6c2c5062 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -22,8 +22,6 @@ rustdoc-args = ["--cfg", "doc_cfg"] [features] default = ["backtrace", "contexts", "debug-images", "panic", "transport"] -metrics = ["sentry-core/metrics"] -metrics-cadence1 = ["sentry-core/metrics-cadence1"] # default integrations backtrace = ["sentry-backtrace", "sentry-tracing?/backtrace"] diff --git a/sentry/src/transports/ratelimit.rs b/sentry/src/transports/ratelimit.rs index 3b998ff00..3cadfa057 100644 --- a/sentry/src/transports/ratelimit.rs +++ b/sentry/src/transports/ratelimit.rs @@ -12,7 +12,6 @@ pub struct RateLimiter { session: Option, transaction: Option, attachment: Option, - statsd: Option, } impl RateLimiter { @@ -57,7 +56,6 @@ impl RateLimiter { "session" => self.session = new_time, "transaction" => self.transaction = new_time, "attachment" => self.attachment = new_time, - "statsd" => self.statsd = new_time, _ => {} } } @@ -91,7 +89,6 @@ impl RateLimiter { RateLimitingCategory::Session => self.session, RateLimitingCategory::Transaction => self.transaction, RateLimitingCategory::Attachment => self.attachment, - RateLimitingCategory::Statsd => self.statsd, }?; time_left.duration_since(SystemTime::now()).ok() } @@ -115,8 +112,6 @@ impl RateLimiter { } EnvelopeItem::Transaction(_) => RateLimitingCategory::Transaction, EnvelopeItem::Attachment(_) => RateLimitingCategory::Attachment, - #[cfg(feature = "metrics")] - EnvelopeItem::Statsd(_) => RateLimitingCategory::Statsd, _ => RateLimitingCategory::Any, }) }) @@ -136,9 +131,6 @@ pub enum RateLimitingCategory { Transaction, /// Rate Limit pertaining to Attachments. Attachment, - /// Rate Limit pertaining to metrics. - #[allow(unused)] - Statsd, } #[cfg(test)] From 46022c4496e0505677fa456a08b9844d19aadfb6 Mon Sep 17 00:00:00 2001 From: bbrunell Date: Fri, 14 Feb 2025 14:46:58 +0100 Subject: [PATCH 050/148] feat(actix): capture HTTP request body (#731) * Add request body size control options Add MaxRequestBodySize enum to control request body capture with options: - None: Don't capture request body (default) - Small: Capture up to 1000 bytes - Medium: Capture up to 10000 bytes - Always: Capture entire body Add max_request_body_size field to ClientOptions struct with default value of None * feat(sentry-actix): Add request body capture functionality Add support for capturing request bodies in the Sentry middleware for Actix-Web. This includes: - Configurable request body size limits (Small/Medium/Always) - Support for JSON and form-urlencoded content types - Body capture and restoration logic to maintain request integrity - Additional span data enrichment Updates dependencies: - Add serde_json, actix-http, futures dependencies * remove unused futures dependency * remove useless code and dependency, address clippy lints * remove unnecessary async for should_capture_request_body * feat: Add MaxRequestBodySize check for request body limits Implements a method to validate request body sizes against predefined limits: - None: Don't capture request bodies (default) - Small: Capture up to 1000 bytes - Medium: Capture up to 10000 bytes - Always: Capture entire body * feat(sentry-actix): Improve request body capture logic - Add chunked transfer encoding check to prevent capturing chunked requests - Add strict content-type validation for JSON and form-urlencoded - Implement content length validation against size limits * clippy * feat(core): add explicit size limit option for request body capture Add new `Explicit(usize)` variant to `MaxRequestBodySize` enum, allowing users to specify custom maximum request body size limits for event capture. * remove unnecessary async for should_capture_request_body * Add copy trait on MaxRequestBodySize * Remove MaxRequestBodySize::None check It's already handle by the is_within_size_limit. * replace unwrap by empty string * use copy instead of clone for max_request_body_size * set default max_request_body_size to medium --------- Co-authored-by: lcian --- sentry-actix/Cargo.toml | 1 + sentry-actix/src/lib.rs | 105 +++++++++++++++++++++++++------ sentry-core/src/clientoptions.rs | 36 +++++++++++ sentry-core/src/lib.rs | 3 + 4 files changed, 126 insertions(+), 19 deletions(-) diff --git a/sentry-actix/Cargo.toml b/sentry-actix/Cargo.toml index 3a7e94e41..12725490b 100644 --- a/sentry-actix/Cargo.toml +++ b/sentry-actix/Cargo.toml @@ -18,6 +18,7 @@ futures-util = { version = "0.3.5", default-features = false } sentry-core = { version = "0.36.0", path = "../sentry-core", default-features = false, features = [ "client", ] } +actix-http = "3.9.0" [dev-dependencies] actix-web = { version = "4" } diff --git a/sentry-actix/src/lib.rs b/sentry-actix/src/lib.rs index 59dbf0707..be0f21c3e 100644 --- a/sentry-actix/src/lib.rs +++ b/sentry-actix/src/lib.rs @@ -73,15 +73,20 @@ use std::borrow::Cow; use std::pin::Pin; +use std::rc::Rc; use std::sync::Arc; +use actix_http::header::{self, HeaderMap}; use actix_web::dev::{Service, ServiceRequest, ServiceResponse, Transform}; +use actix_web::error::PayloadError; use actix_web::http::StatusCode; -use actix_web::Error; +use actix_web::web::BytesMut; +use actix_web::{Error, HttpMessage}; use futures_util::future::{ok, Future, Ready}; use futures_util::FutureExt; use sentry_core::protocol::{self, ClientSdkPackage, Event, Request}; +use sentry_core::MaxRequestBodySize; use sentry_core::{Hub, SentryFutureExt}; /// A helper construct that can be used to reconfigure and build the middleware. @@ -180,7 +185,7 @@ impl Default for Sentry { impl Transform for Sentry where - S: Service, Error = Error>, + S: Service, Error = Error> + 'static, S::Future: 'static, { type Response = ServiceResponse; @@ -191,7 +196,7 @@ where fn new_transform(&self, service: S) -> Self::Future { ok(SentryMiddleware { - service, + service: Rc::new(service), inner: self.clone(), }) } @@ -199,13 +204,67 @@ where /// The middleware for individual services. pub struct SentryMiddleware { - service: S, + service: Rc, inner: Sentry, } +fn should_capture_request_body( + headers: &HeaderMap, + max_request_body_size: MaxRequestBodySize, +) -> bool { + let is_chunked = headers + .get(header::TRANSFER_ENCODING) + .and_then(|h| h.to_str().ok()) + .map(|transfer_encoding| transfer_encoding.contains("chunked")) + .unwrap_or(false); + + let is_valid_content_type = headers + .get(header::CONTENT_TYPE) + .and_then(|h| h.to_str().ok()) + .is_some_and(|content_type| { + matches!( + content_type, + "application/json" | "application/x-www-form-urlencoded" + ) + }); + + let is_within_size_limit = headers + .get(header::CONTENT_LENGTH) + .and_then(|h| h.to_str().ok()) + .and_then(|content_length| content_length.parse::().ok()) + .map(|content_length| max_request_body_size.is_within_size_limit(content_length)) + .unwrap_or(false); + + !is_chunked && is_valid_content_type && is_within_size_limit +} + +/// Extract a body from the HTTP request +async fn body_from_http(req: &mut ServiceRequest) -> Result { + let mut stream = req.take_payload(); + + let mut body = BytesMut::new(); + while let Some(chunk) = futures_util::StreamExt::next(&mut stream).await { + let chunk = chunk?; + body.extend_from_slice(&chunk); + } + let (_, mut orig_payload) = actix_http::h1::Payload::create(true); + orig_payload.unread_data(body.clone().freeze()); + req.set_payload(actix_web::dev::Payload::from(orig_payload)); + + Ok::<_, PayloadError>(body) +} + +async fn capture_request_body(req: &mut ServiceRequest) -> String { + if let Ok(request_body) = body_from_http(req).await { + String::from_utf8_lossy(&request_body).into_owned() + } else { + String::new() + } +} + impl Service for SentryMiddleware where - S: Service, Error = Error>, + S: Service, Error = Error> + 'static, S::Future: 'static, { type Response = ServiceResponse; @@ -230,6 +289,10 @@ where options.auto_session_tracking && options.session_mode == sentry_core::SessionMode::Request }); + let max_request_body_size = client + .as_ref() + .map(|client| client.options().max_request_body_size) + .unwrap_or(MaxRequestBodySize::None); if track_sessions { hub.start_session(); } @@ -237,7 +300,7 @@ where .as_ref() .is_some_and(|client| client.options().send_default_pii); - let sentry_req = sentry_request_from_http(&req, with_pii); + let mut sentry_req = sentry_request_from_http(&req, with_pii); let name = transaction_name_from_http(&req); let transaction = if inner.start_transaction { @@ -258,21 +321,25 @@ where None }; - let parent_span = hub.configure_scope(|scope| { - let parent_span = scope.get_span(); - if let Some(transaction) = transaction.as_ref() { - scope.set_span(Some(transaction.clone().into())); - } else { - scope.set_transaction((!inner.start_transaction).then_some(&name)); - } - scope.add_event_processor(move |event| Some(process_event(event, &sentry_req))); - parent_span - }); + let svc = self.service.clone(); + async move { + let mut req = req; - let fut = self.service.call(req).bind_hub(hub.clone()); + if should_capture_request_body(req.headers(), max_request_body_size) { + sentry_req.data = Some(capture_request_body(&mut req).await); + } - async move { - // Service errors + let parent_span = hub.configure_scope(|scope| { + let parent_span = scope.get_span(); + if let Some(transaction) = transaction.as_ref() { + scope.set_span(Some(transaction.clone().into())); + } else { + scope.set_transaction((!inner.start_transaction).then_some(&name)); + } + scope.add_event_processor(move |event| Some(process_event(event, &sentry_req))); + parent_span + }); + let fut = svc.call(req).bind_hub(hub.clone()); let mut res: Self::Response = match fut.await { Ok(res) => res, Err(e) => { diff --git a/sentry-core/src/clientoptions.rs b/sentry-core/src/clientoptions.rs index 9926cbcdd..583aae8cc 100644 --- a/sentry-core/src/clientoptions.rs +++ b/sentry-core/src/clientoptions.rs @@ -40,6 +40,39 @@ pub enum SessionMode { Request, } +/// The maximum size of an HTTP request body that the SDK captures. +/// +/// Only request bodies that parse as JSON or form data are currently captured. +/// See the [Documentation on attaching request body](https://develop.sentry.dev/sdk/expected-features/#attaching-request-body-in-server-sdks) +/// and the [Documentation on handling sensitive data](https://develop.sentry.dev/sdk/expected-features/data-handling/#sensitive-data) +/// for more information. +#[derive(Clone, Copy, PartialEq)] +pub enum MaxRequestBodySize { + /// Don't capture request body + None, + /// Capture up to 1000 bytes + Small, + /// Capture up to 10000 bytes + Medium, + /// Capture entire body + Always, + /// Capture up to a specific size + Explicit(usize), +} + +impl MaxRequestBodySize { + /// Check if the content length is within the size limit. + pub fn is_within_size_limit(&self, content_length: usize) -> bool { + match self { + MaxRequestBodySize::None => false, + MaxRequestBodySize::Small => content_length <= 1_000, + MaxRequestBodySize::Medium => content_length <= 10_000, + MaxRequestBodySize::Always => true, + MaxRequestBodySize::Explicit(size) => content_length <= *size, + } + } +} + /// Configuration settings for the client. /// /// These options are explained in more detail in the general @@ -148,6 +181,8 @@ pub struct ClientOptions { pub trim_backtraces: bool, /// The user agent that should be reported. pub user_agent: Cow<'static, str>, + /// Controls how much of request bodies are captured + pub max_request_body_size: MaxRequestBodySize, } impl ClientOptions { @@ -256,6 +291,7 @@ impl Default for ClientOptions { extra_border_frames: vec![], trim_backtraces: true, user_agent: Cow::Borrowed(USER_AGENT), + max_request_body_size: MaxRequestBodySize::Medium, } } } diff --git a/sentry-core/src/lib.rs b/sentry-core/src/lib.rs index 8ea9bcbd2..3021681da 100644 --- a/sentry-core/src/lib.rs +++ b/sentry-core/src/lib.rs @@ -144,6 +144,9 @@ mod hub_impl; #[cfg(feature = "client")] mod session; +#[cfg(feature = "client")] +pub use crate::clientoptions::MaxRequestBodySize; + #[cfg(feature = "client")] pub use crate::{client::Client, hub_impl::SwitchGuard as HubSwitchGuard}; From 89b44c8400a6c287d9a2fbc0aabf5e78adce363d Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Wed, 12 Mar 2025 15:05:45 +0100 Subject: [PATCH 051/148] chore(msrv): bump MSRV to 1.75 (#751) --- .github/workflows/ci.yml | 2 +- README.md | 2 +- clippy.toml | 2 +- sentry-actix/Cargo.toml | 2 +- sentry-anyhow/Cargo.toml | 2 +- sentry-backtrace/Cargo.toml | 2 +- sentry-contexts/Cargo.toml | 2 +- sentry-core/Cargo.toml | 2 +- sentry-debug-images/Cargo.toml | 2 +- sentry-log/Cargo.toml | 2 +- sentry-panic/Cargo.toml | 2 +- sentry-slog/Cargo.toml | 2 +- sentry-tower/Cargo.toml | 2 +- sentry-tracing/Cargo.toml | 2 +- sentry-types/Cargo.toml | 2 +- sentry/Cargo.toml | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7f34e0ff8..448251333 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,7 +65,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - rust: [1.73.0] + rust: [1.75.0] name: Check / Test MSRV on ${{ matrix.os }} runs-on: ${{ matrix.os }} diff --git a/README.md b/README.md index 1c1014207..606000942 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ best API and adding new features. We currently only verify this crate against a recent version of Sentry hosted on [sentry.io](https://sentry.io/) but it should work with on-prem Sentry versions 20.6 and later. -The **Minimum Supported Rust Version** is currently at _1.73.0_. +The **Minimum Supported Rust Version** is currently at _1.75.0_. The Sentry crates tries to support a _6 months_ old Rust version at time of release, and the MSRV will be increased in accordance with its dependencies. diff --git a/clippy.toml b/clippy.toml index f09ac0fb5..130672505 100644 --- a/clippy.toml +++ b/clippy.toml @@ -1 +1 @@ -msrv = "1.73.0" +msrv = "1.75.0" diff --git a/sentry-actix/Cargo.toml b/sentry-actix/Cargo.toml index 12725490b..d9554bb04 100644 --- a/sentry-actix/Cargo.toml +++ b/sentry-actix/Cargo.toml @@ -10,7 +10,7 @@ description = """ Sentry client extension for actix-web 3. """ edition = "2021" -rust-version = "1.73" +rust-version = "1.75" [dependencies] actix-web = { version = "4", default-features = false } diff --git a/sentry-anyhow/Cargo.toml b/sentry-anyhow/Cargo.toml index 769340bc9..5397edd6a 100644 --- a/sentry-anyhow/Cargo.toml +++ b/sentry-anyhow/Cargo.toml @@ -10,7 +10,7 @@ description = """ Sentry integration for anyhow. """ edition = "2021" -rust-version = "1.73" +rust-version = "1.75" [features] default = ["backtrace"] diff --git a/sentry-backtrace/Cargo.toml b/sentry-backtrace/Cargo.toml index e29b32636..51902fed5 100644 --- a/sentry-backtrace/Cargo.toml +++ b/sentry-backtrace/Cargo.toml @@ -10,7 +10,7 @@ description = """ Sentry integration and utilities for dealing with stacktraces. """ edition = "2021" -rust-version = "1.73" +rust-version = "1.75" [dependencies] backtrace = "0.3.44" diff --git a/sentry-contexts/Cargo.toml b/sentry-contexts/Cargo.toml index 90f25de10..627440399 100644 --- a/sentry-contexts/Cargo.toml +++ b/sentry-contexts/Cargo.toml @@ -11,7 +11,7 @@ Sentry integration for os, device, and rust contexts. """ build = "build.rs" edition = "2021" -rust-version = "1.73" +rust-version = "1.75" [dependencies] sentry-core = { version = "0.36.0", path = "../sentry-core" } diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index ecb3c37d5..e372cb1eb 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -10,7 +10,7 @@ description = """ Core sentry library used for instrumentation and integration development. """ edition = "2021" -rust-version = "1.73" +rust-version = "1.75" [package.metadata.docs.rs] all-features = true diff --git a/sentry-debug-images/Cargo.toml b/sentry-debug-images/Cargo.toml index 1025d50bc..26b32f8f0 100644 --- a/sentry-debug-images/Cargo.toml +++ b/sentry-debug-images/Cargo.toml @@ -10,7 +10,7 @@ description = """ Sentry integration that adds the list of loaded libraries to events. """ edition = "2021" -rust-version = "1.73" +rust-version = "1.75" [dependencies] findshlibs = "=0.10.2" diff --git a/sentry-log/Cargo.toml b/sentry-log/Cargo.toml index 59bba3571..b8f2b2c19 100644 --- a/sentry-log/Cargo.toml +++ b/sentry-log/Cargo.toml @@ -10,7 +10,7 @@ description = """ Sentry integration for log and env_logger crates. """ edition = "2021" -rust-version = "1.73" +rust-version = "1.75" [dependencies] sentry-core = { version = "0.36.0", path = "../sentry-core" } diff --git a/sentry-panic/Cargo.toml b/sentry-panic/Cargo.toml index 17d6e8959..d7eedbcc3 100644 --- a/sentry-panic/Cargo.toml +++ b/sentry-panic/Cargo.toml @@ -10,7 +10,7 @@ description = """ Sentry integration for capturing panics. """ edition = "2021" -rust-version = "1.73" +rust-version = "1.75" [dependencies] sentry-core = { version = "0.36.0", path = "../sentry-core" } diff --git a/sentry-slog/Cargo.toml b/sentry-slog/Cargo.toml index 4d64bbd3a..6cb59ee5c 100644 --- a/sentry-slog/Cargo.toml +++ b/sentry-slog/Cargo.toml @@ -10,7 +10,7 @@ description = """ Sentry integration for the slog crate. """ edition = "2021" -rust-version = "1.73" +rust-version = "1.75" [dependencies] sentry-core = { version = "0.36.0", path = "../sentry-core" } diff --git a/sentry-tower/Cargo.toml b/sentry-tower/Cargo.toml index 77f3c6ee2..df0d3d3e8 100644 --- a/sentry-tower/Cargo.toml +++ b/sentry-tower/Cargo.toml @@ -10,7 +10,7 @@ description = """ Sentry integration for tower-based crates. """ edition = "2021" -rust-version = "1.73" +rust-version = "1.75" [package.metadata.docs.rs] all-features = true diff --git a/sentry-tracing/Cargo.toml b/sentry-tracing/Cargo.toml index 50d65bf19..ffa7054a1 100644 --- a/sentry-tracing/Cargo.toml +++ b/sentry-tracing/Cargo.toml @@ -10,7 +10,7 @@ description = """ Sentry integration for tracing and tracing-subscriber crates. """ edition = "2021" -rust-version = "1.73" +rust-version = "1.75" [package.metadata.docs.rs] all-features = true diff --git a/sentry-types/Cargo.toml b/sentry-types/Cargo.toml index 88ed1d021..2afcb34e7 100644 --- a/sentry-types/Cargo.toml +++ b/sentry-types/Cargo.toml @@ -11,7 +11,7 @@ Common reusable types for implementing the sentry.io protocol. """ keywords = ["sentry", "protocol"] edition = "2021" -rust-version = "1.73" +rust-version = "1.75" [package.metadata.docs.rs] all-features = true diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index e6c2c5062..50ece0ca8 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -10,7 +10,7 @@ description = """ Sentry (getsentry.com) client for rust ;) """ edition = "2021" -rust-version = "1.73" +rust-version = "1.75" autoexamples = true # To build locally: From 9df7f4b81bff3f576e91afe717ab54626bdbd8ff Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Wed, 12 Mar 2025 15:16:08 +0100 Subject: [PATCH 052/148] fix(doctests): update prost (#750) --- sentry-tower/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sentry-tower/Cargo.toml b/sentry-tower/Cargo.toml index df0d3d3e8..175a72814 100644 --- a/sentry-tower/Cargo.toml +++ b/sentry-tower/Cargo.toml @@ -32,7 +32,7 @@ url = { version = "2.2.2", optional = true } [dev-dependencies] anyhow = "1" -prost = "0.12.3" +prost = "0.13.3" sentry = { path = "../sentry", default-features = false, features = ["test"] } sentry-anyhow = { path = "../sentry-anyhow" } tokio = { version = "1", features = ["macros", "rt-multi-thread"] } From 757e0ad92c59feb1c2f235d7822e72fbda528166 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Mar 2025 18:08:43 +0100 Subject: [PATCH 053/148] build(deps): bump ring from 0.17.8 to 0.17.13 (#747) Bumps [ring](https://github.com/briansmith/ring) from 0.17.8 to 0.17.13. - [Changelog](https://github.com/briansmith/ring/blob/main/RELEASES.md) - [Commits](https://github.com/briansmith/ring/commits) --- updated-dependencies: - dependency-name: ring dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 162 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 127 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33161a319..0b02957ab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,23 +21,23 @@ dependencies = [ [[package]] name = "actix-http" -version = "3.7.0" +version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eb9843d84c775696c37d9a418bbb01b932629d01870722c0f13eb3f95e2536d" +checksum = "0fa882656b67966045e4152c634051e70346939fced7117d5f0b52146a7c74c9" dependencies = [ "actix-codec", "actix-rt", "actix-service", "actix-utils", - "ahash", "base64 0.22.1", "bitflags 2.5.0", "brotli", "bytes 1.6.0", "bytestring", - "derive_more", + "derive_more 2.0.1", "encoding_rs", "flate2", + "foldhash", "futures-core", "h2 0.3.26", "http 0.2.12", @@ -49,7 +49,7 @@ dependencies = [ "mime", "percent-encoding", "pin-project-lite", - "rand 0.8.5", + "rand 0.9.0", "sha1 0.10.6", "smallvec", "tokio", @@ -151,7 +151,7 @@ dependencies = [ "bytestring", "cfg-if", "cookie 0.16.2", - "derive_more", + "derive_more 0.99.17", "encoding_rs", "futures-core", "futures-util", @@ -263,7 +263,7 @@ dependencies = [ "getrandom 0.2.15", "once_cell", "version_check", - "zerocopy", + "zerocopy 0.7.34", ] [[package]] @@ -768,9 +768,9 @@ dependencies = [ [[package]] name = "brotli" -version = "6.0.0" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" +checksum = "cc97b8f16f944bba54f0433f07e30be199b6dc2bd25937444bbad560bcea29bd" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -892,9 +892,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.1.24" +version = "1.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938" +checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" dependencies = [ "jobserver", "libc", @@ -1414,6 +1414,27 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive_more" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", + "unicode-xid", +] + [[package]] name = "digest" version = "0.9.0" @@ -1820,6 +1841,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" + [[package]] name = "foreign-types" version = "0.3.2" @@ -2013,6 +2040,18 @@ dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] +[[package]] +name = "getrandom" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.13.3+wasi-0.2.2", + "windows-targets 0.52.5", +] + [[package]] name = "ghash" version = "0.3.1" @@ -3234,16 +3273,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "prost" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" -dependencies = [ - "bytes 1.6.0", - "prost-derive", -] - [[package]] name = "prost" version = "0.13.3" @@ -3251,13 +3280,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b0487d90e047de87f984913713b85c601c05609aad5b0df4b4573fbf69aa13f" dependencies = [ "bytes 1.6.0", + "prost-derive", ] [[package]] name = "prost-derive" -version = "0.12.6" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" +checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" dependencies = [ "anyhow", "itertools 0.12.1", @@ -3299,6 +3329,17 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", + "zerocopy 0.8.23", +] + [[package]] name = "rand_chacha" version = "0.2.2" @@ -3319,6 +3360,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", +] + [[package]] name = "rand_core" version = "0.5.1" @@ -3337,6 +3388,15 @@ dependencies = [ "getrandom 0.2.15", ] +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.1", +] + [[package]] name = "rand_hc" version = "0.2.0" @@ -3488,15 +3548,14 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.8" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", "getrandom 0.2.15", "libc", - "spin", "untrusted", "windows-sys 0.52.0", ] @@ -3768,6 +3827,7 @@ dependencies = [ name = "sentry-actix" version = "0.36.0" dependencies = [ + "actix-http", "actix-web", "futures", "futures-util", @@ -3880,7 +3940,7 @@ dependencies = [ "axum 0.8.1", "http 1.1.0", "pin-project", - "prost 0.12.6", + "prost", "sentry", "sentry-anyhow", "sentry-core", @@ -4095,12 +4155,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - [[package]] name = "spinning_top" version = "0.2.5" @@ -4543,7 +4597,7 @@ dependencies = [ "hyper-util", "percent-encoding", "pin-project", - "prost 0.13.3", + "prost", "socket2 0.5.7", "tokio", "tokio-stream", @@ -4854,6 +4908,15 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.13.3+wasi-0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "wasm-bindgen" version = "0.2.92" @@ -5225,13 +5288,31 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "wit-bindgen-rt" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +dependencies = [ + "bitflags 2.5.0", +] + [[package]] name = "zerocopy" version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" dependencies = [ - "zerocopy-derive", + "zerocopy-derive 0.7.34", +] + +[[package]] +name = "zerocopy" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6" +dependencies = [ + "zerocopy-derive 0.8.23", ] [[package]] @@ -5245,6 +5326,17 @@ dependencies = [ "syn 2.0.79", ] +[[package]] +name = "zerocopy-derive" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + [[package]] name = "zeroize" version = "1.8.1" From 3b73aac2f91f9dfe979ea4023d2b4d1a4995aa68 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Wed, 19 Mar 2025 11:06:06 +0100 Subject: [PATCH 054/148] chore(msrv): `cargo update` and bump MSRV to 1.81 (#754) --- .github/workflows/ci.yml | 2 +- Cargo.lock | 1955 +++++++++++++++++++------------- README.md | 2 +- clippy.toml | 2 +- sentry-actix/Cargo.toml | 2 +- sentry-anyhow/Cargo.toml | 2 +- sentry-backtrace/Cargo.toml | 2 +- sentry-contexts/Cargo.toml | 2 +- sentry-core/Cargo.toml | 2 +- sentry-debug-images/Cargo.toml | 2 +- sentry-log/Cargo.toml | 2 +- sentry-panic/Cargo.toml | 2 +- sentry-slog/Cargo.toml | 2 +- sentry-tower/Cargo.toml | 2 +- sentry-tracing/Cargo.toml | 2 +- sentry-types/Cargo.toml | 2 +- sentry/Cargo.toml | 2 +- 17 files changed, 1163 insertions(+), 824 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 448251333..059333848 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,7 +65,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - rust: [1.75.0] + rust: [1.81.0] name: Check / Test MSRV on ${{ matrix.os }} runs-on: ${{ matrix.os }} diff --git a/Cargo.lock b/Cargo.lock index 0b02957ab..9457e131e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,8 +8,8 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" dependencies = [ - "bitflags 2.5.0", - "bytes 1.6.0", + "bitflags 2.9.0", + "bytes 1.10.1", "futures-core", "futures-sink", "memchr", @@ -30,11 +30,11 @@ dependencies = [ "actix-service", "actix-utils", "base64 0.22.1", - "bitflags 2.5.0", + "bitflags 2.9.0", "brotli", - "bytes 1.6.0", + "bytes 1.10.1", "bytestring", - "derive_more 2.0.1", + "derive_more", "encoding_rs", "flate2", "foldhash", @@ -65,7 +65,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote", - "syn 2.0.79", + "syn 2.0.100", ] [[package]] @@ -85,9 +85,9 @@ dependencies = [ [[package]] name = "actix-rt" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28f32d40287d3f402ae0028a9d54bef51af15c8769492826a69d28f81893151d" +checksum = "24eda4e2a6e042aa4e55ac438a2ae052d3b5da0ecf83d7411e1a368946925208" dependencies = [ "futures-core", "tokio", @@ -95,9 +95,9 @@ dependencies = [ [[package]] name = "actix-server" -version = "2.3.0" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eb13e7eef0423ea6eab0e59f6c72e7cb46d33691ad56a726b3cd07ddec2c2d4" +checksum = "6398974fd4284f4768af07965701efbbb5fdc0616bff20cade1bb14b77675e24" dependencies = [ "actix-rt", "actix-service", @@ -105,19 +105,18 @@ dependencies = [ "futures-core", "futures-util", "mio", - "socket2 0.5.7", + "socket2 0.5.8", "tokio", "tracing", ] [[package]] name = "actix-service" -version = "2.0.2" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a" +checksum = "9e46f36bf0e5af44bdc4bdb36fbbd421aa98c79a9bce724e1edeb3894e10dc7f" dependencies = [ "futures-core", - "paste", "pin-project-lite", ] @@ -133,9 +132,9 @@ dependencies = [ [[package]] name = "actix-web" -version = "4.6.0" +version = "4.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1cf67dadb19d7c95e5a299e2dda24193b89d5d4f33a3b9800888ede9e19aa32" +checksum = "f2e3b15b3dc6c6ed996e4032389e9849d4ab002b1e92fbfe85b5f307d1479b4d" dependencies = [ "actix-codec", "actix-http", @@ -146,15 +145,16 @@ dependencies = [ "actix-service", "actix-utils", "actix-web-codegen", - "ahash", - "bytes 1.6.0", + "bytes 1.10.1", "bytestring", "cfg-if", "cookie 0.16.2", - "derive_more 0.99.17", + "derive_more", "encoding_rs", + "foldhash", "futures-core", "futures-util", + "impl-more", "itoa", "language-tags", "log", @@ -167,37 +167,38 @@ dependencies = [ "serde_json", "serde_urlencoded", "smallvec", - "socket2 0.5.7", - "time 0.3.36", + "socket2 0.5.8", + "time 0.3.40", + "tracing", "url", ] [[package]] name = "actix-web-codegen" -version = "4.2.2" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1f50ebbb30eca122b188319a4398b3f7bb4a8cdf50ecfb73bfc6a3c3ce54f5" +checksum = "f591380e2e68490b5dfaf1dd1aa0ebe78d84ba7067078512b4ea6e4492d622b8" dependencies = [ "actix-router", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.100", ] [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "aead" @@ -253,19 +254,6 @@ dependencies = [ "opaque-debug", ] -[[package]] -name = "ahash" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" -dependencies = [ - "cfg-if", - "getrandom 0.2.15", - "once_cell", - "version_check", - "zerocopy 0.7.34", -] - [[package]] name = "aho-corasick" version = "1.1.3" @@ -322,15 +310,15 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstyle" -version = "1.0.7" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" dependencies = [ "backtrace", ] @@ -368,7 +356,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" dependencies = [ "concurrent-queue", - "event-listener-strategy 0.5.2", + "event-listener-strategy", "futures-core", "pin-project-lite", ] @@ -379,20 +367,20 @@ version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c2886ab563af5038f79ec016dd7b87947ed138b794e8dd64992962c9cca0411" dependencies = [ - "async-lock 3.3.0", + "async-lock 3.4.0", "futures-io", ] [[package]] name = "async-executor" -version = "1.12.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8828ec6e544c02b0d6691d21ed9f9218d0384a82542855073c2a3f58304aaf0" +checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" dependencies = [ "async-task", "concurrent-queue", - "fastrand 2.1.0", - "futures-lite 2.3.0", + "fastrand 2.3.0", + "futures-lite 2.6.0", "slab", ] @@ -404,10 +392,10 @@ checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" dependencies = [ "async-channel 2.3.1", "async-executor", - "async-io 2.3.2", - "async-lock 3.3.0", + "async-io 2.4.0", + "async-lock 3.4.0", "blocking", - "futures-lite 2.3.0", + "futures-lite 2.6.0", "once_cell", ] @@ -442,7 +430,7 @@ dependencies = [ "log", "parking", "polling 2.8.0", - "rustix 0.37.27", + "rustix 0.37.28", "slab", "socket2 0.4.10", "waker-fn", @@ -450,21 +438,21 @@ dependencies = [ [[package]] name = "async-io" -version = "2.3.2" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcccb0f599cfa2f8ace422d3555572f47424da5648a4382a9dd0310ff8210884" +checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059" dependencies = [ - "async-lock 3.3.0", + "async-lock 3.4.0", "cfg-if", "concurrent-queue", "futures-io", - "futures-lite 2.3.0", + "futures-lite 2.6.0", "parking", - "polling 3.7.0", - "rustix 0.38.34", + "polling 3.7.4", + "rustix 0.38.44", "slab", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -478,12 +466,12 @@ dependencies = [ [[package]] name = "async-lock" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" dependencies = [ - "event-listener 4.0.3", - "event-listener-strategy 0.4.0", + "event-listener 5.4.0", + "event-listener-strategy", "pin-project-lite", ] @@ -495,25 +483,25 @@ checksum = "9e9e7a929bd34c68a82d58a4de7f86fffdaf97fb2af850162a7bb19dd7269b33" dependencies = [ "async-std", "native-tls", - "thiserror", + "thiserror 1.0.69", "url", ] [[package]] name = "async-std" -version = "1.12.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" +checksum = "730294c1c08c2e0f85759590518f6333f0d5a0a766a27d519c1b244c3dfd8a24" dependencies = [ "async-channel 1.9.0", "async-global-executor", - "async-io 1.13.0", - "async-lock 2.8.0", + "async-io 2.4.0", + "async-lock 3.4.0", "crossbeam-utils", "futures-channel", "futures-core", "futures-io", - "futures-lite 1.13.0", + "futures-lite 2.6.0", "gloo-timers", "kv-log-macro", "log", @@ -527,9 +515,9 @@ dependencies = [ [[package]] name = "async-stream" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" dependencies = [ "async-stream-impl", "futures-core", @@ -538,13 +526,13 @@ dependencies = [ [[package]] name = "async-stream-impl" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.100", ] [[package]] @@ -555,13 +543,13 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.80" +version = "0.1.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" +checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.100", ] [[package]] @@ -572,21 +560,21 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "axum" -version = "0.7.5" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" +checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" dependencies = [ "async-trait", - "axum-core 0.4.3", - "bytes 1.6.0", + "axum-core 0.4.5", + "bytes 1.10.1", "futures-util", - "http 1.1.0", + "http 1.3.1", "http-body", "http-body-util", "itoa", @@ -597,8 +585,8 @@ dependencies = [ "pin-project-lite", "rustversion", "serde", - "sync_wrapper 1.0.1", - "tower 0.4.13", + "sync_wrapper", + "tower 0.5.2", "tower-layer", "tower-service", ] @@ -610,9 +598,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d6fd624c75e18b3b4c6b9caf42b1afe24437daaee904069137d8bab077be8b8" dependencies = [ "axum-core 0.5.0", - "bytes 1.6.0", + "bytes 1.10.1", "futures-util", - "http 1.1.0", + "http 1.3.1", "http-body", "http-body-util", "itoa", @@ -623,7 +611,7 @@ dependencies = [ "pin-project-lite", "rustversion", "serde", - "sync_wrapper 1.0.1", + "sync_wrapper", "tower 0.5.2", "tower-layer", "tower-service", @@ -631,20 +619,20 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" +checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" dependencies = [ "async-trait", - "bytes 1.6.0", + "bytes 1.10.1", "futures-util", - "http 1.1.0", + "http 1.3.1", "http-body", "http-body-util", "mime", "pin-project-lite", "rustversion", - "sync_wrapper 0.1.2", + "sync_wrapper", "tower-layer", "tower-service", ] @@ -655,32 +643,32 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df1362f362fd16024ae199c1970ce98f9661bf5ef94b9808fee734bc3698b733" dependencies = [ - "bytes 1.6.0", + "bytes 1.10.1", "futures-util", - "http 1.1.0", + "http 1.3.1", "http-body", "http-body-util", "mime", "pin-project-lite", "rustversion", - "sync_wrapper 1.0.1", + "sync_wrapper", "tower-layer", "tower-service", ] [[package]] name = "backtrace" -version = "0.3.72" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17c6a35df3749d2e8bb1b7b21a976d82b15548788d2735b9d82f329268f71a11" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] @@ -717,7 +705,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "rustc-hash", + "rustc-hash 1.1.0", "shlex", "syn 1.0.109", "which", @@ -731,9 +719,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" [[package]] name = "block-buffer" @@ -762,7 +750,7 @@ dependencies = [ "async-channel 2.3.1", "async-task", "futures-io", - "futures-lite 2.3.0", + "futures-lite 2.6.0", "piper", ] @@ -779,9 +767,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "4.0.1" +version = "4.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" +checksum = "74fa05ad7d803d413eb8380983b092cbbaf9a85f151b871360e7b00cd7060b37" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -789,9 +777,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.9.1" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" +checksum = "531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0" dependencies = [ "memchr", "serde", @@ -807,14 +795,14 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.100", ] [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" [[package]] name = "byteorder" @@ -830,42 +818,42 @@ checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" [[package]] name = "bytes" -version = "1.6.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "bytestring" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d80203ea6b29df88012294f62733de21cfeab47f17b41af3a38bc30a03ee72" +checksum = "e465647ae23b2823b0753f50decb2d5a86d2bb2cac04788fafd1f80e45378e5f" dependencies = [ - "bytes 1.6.0", + "bytes 1.10.1", ] [[package]] name = "cadence" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f338b979d9ebfff4bb9801ae8f3af0dc3615f7f1ca963f2e4782bcf9acb3753" +checksum = "62fd689c825a93386a2ac05a46f88342c6df9ec3e79416f665650614e92e7475" dependencies = [ "crossbeam-channel", ] [[package]] name = "camino" -version = "1.1.7" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" dependencies = [ "serde", ] [[package]] name = "cargo-platform" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" dependencies = [ "serde", ] @@ -878,10 +866,10 @@ checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" dependencies = [ "camino", "cargo-platform", - "semver 1.0.23", + "semver 1.0.26", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -916,16 +904,22 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", - "windows-targets 0.52.5", + "windows-link", ] [[package]] @@ -977,18 +971,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.4" +version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +checksum = "6088f3ae8c3608d19260cd7445411865a485688711b78b5be70d78cd96136f83" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.2" +version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +checksum = "22a7ef7f676155edfb82daa97f99441f3ebf4a58d5e32f295a56259f1b6facc8" dependencies = [ "anstyle", "clap_lex", @@ -996,15 +990,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "cmake" -version = "0.1.50" +version = "0.1.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" +checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" dependencies = [ "cc", ] @@ -1031,36 +1025,30 @@ dependencies = [ [[package]] name = "const_fn" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "373e9fafaa20882876db20562275ff58d50e0caa2590077fe7ce7bef90211d0d" +checksum = "2f8a2ca5ac02d09563609681103aada9e1777d54fc57a5acd7a41404f9c93b6e" [[package]] name = "const_format" -version = "0.2.32" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" +checksum = "126f97965c8ad46d6d9163268ff28432e8f6a1196a55578867832e3049df63dd" dependencies = [ "const_format_proc_macros", ] [[package]] name = "const_format_proc_macros" -version = "0.2.32" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" dependencies = [ "proc-macro2", "quote", "unicode-xid", ] -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - [[package]] name = "cookie" version = "0.14.4" @@ -1085,7 +1073,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" dependencies = [ "percent-encoding", - "time 0.3.36", + "time 0.3.40", "version_check", ] @@ -1101,15 +1089,15 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ "libc", ] @@ -1167,24 +1155,24 @@ dependencies = [ [[package]] name = "critical-section" -version = "1.1.2" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" [[package]] name = "crossbeam-channel" -version = "0.5.13" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -1201,24 +1189,24 @@ dependencies = [ [[package]] name = "crossbeam-queue" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crunchy" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" [[package]] name = "crypto-common" @@ -1251,24 +1239,24 @@ dependencies = [ [[package]] name = "curl" -version = "0.4.46" +version = "0.4.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e2161dd6eba090ff1594084e95fd67aeccf04382ffea77999ea94ed42ec67b6" +checksum = "d9fb4d13a1be2b58f14d60adba57c9834b78c62fd86c3e76a148f732686e9265" dependencies = [ "curl-sys", "libc", "openssl-probe", "openssl-sys", "schannel", - "socket2 0.5.7", + "socket2 0.5.8", "windows-sys 0.52.0", ] [[package]] name = "curl-sys" -version = "0.4.72+curl-8.6.0" +version = "0.4.80+curl-8.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29cbdc8314c447d11e8fd156dcdd031d9e02a7a976163e396b548c03153bc9ea" +checksum = "55f7df2eac63200c3ab25bde3b2268ef2ee56af3d238e76d61f01c3c49bff734" dependencies = [ "cc", "libc", @@ -1291,9 +1279,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.9" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" dependencies = [ "darling_core", "darling_macro", @@ -1301,26 +1289,26 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.9" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.100", ] [[package]] name = "darling_macro" -version = "0.20.9" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.79", + "syn 2.0.100", ] [[package]] @@ -1362,9 +1350,9 @@ dependencies = [ [[package]] name = "defmt" -version = "0.3.8" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a99dd22262668b887121d4672af5a64b238f026099f1a2a1b322066c9ecfe9e0" +checksum = "86f6162c53f659f65d00619fe31f14556a6e9f8752ccc4a41bd177ffcf3d6130" dependencies = [ "bitflags 1.3.2", "defmt-macros", @@ -1372,48 +1360,35 @@ dependencies = [ [[package]] name = "defmt-macros" -version = "0.3.9" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a9f309eff1f79b3ebdf252954d90ae440599c26c2c553fe87a2d17195f2dcb" +checksum = "9d135dd939bad62d7490b0002602d35b358dce5fd9233a709d3c1ef467d4bde6" dependencies = [ "defmt-parser", - "proc-macro-error", + "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.100", ] [[package]] name = "defmt-parser" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4a5fefe330e8d7f31b16a318f9ce81000d8e35e69b93eae154d16d2278f70f" +checksum = "3983b127f13995e68c1e29071e5d115cd96f215ccb5e6812e3728cd6f92653b3" dependencies = [ - "thiserror", + "thiserror 2.0.12", ] [[package]] name = "deranged" -version = "0.3.11" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" dependencies = [ "powerfmt", ] -[[package]] -name = "derive_more" -version = "0.99.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version 0.4.0", - "syn 1.0.109", -] - [[package]] name = "derive_more" version = "2.0.1" @@ -1431,7 +1406,7 @@ checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.100", "unicode-xid", ] @@ -1460,11 +1435,22 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "either" -version = "1.12.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "embassy-futures" @@ -1583,24 +1569,24 @@ dependencies = [ "shlex", "strum 0.24.1", "tempfile", - "thiserror", + "thiserror 1.0.69", "which", ] [[package]] name = "encoding_rs" -version = "0.8.34" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ "cfg-if", ] [[package]] name = "enumset" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "226c0da7462c13fb57e5cc9e0dc8f0635e7d27f276a3a7fd30054647f669007d" +checksum = "d07a4b049558765cef5f0c1a273c3fc57084d768b44d2f98127aef4cceb17293" dependencies = [ "enumset_derive", "serde", @@ -1608,14 +1594,14 @@ dependencies = [ [[package]] name = "enumset_derive" -version = "0.8.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" +checksum = "59c3b24c345d8c314966bdc1832f6c2635bfcce8e7cf363bd115987bba2ee242" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.100", ] [[package]] @@ -1642,9 +1628,9 @@ dependencies = [ [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "erased-serde" @@ -1657,12 +1643,12 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1735,20 +1721,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "event-listener" -version = "4.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener" -version = "5.3.1" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" dependencies = [ "concurrent-queue", "parking", @@ -1757,21 +1732,11 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" -dependencies = [ - "event-listener 4.0.3", - "pin-project-lite", -] - -[[package]] -name = "event-listener-strategy" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" +checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" dependencies = [ - "event-listener 5.3.1", + "event-listener 5.4.0", "pin-project-lite", ] @@ -1786,20 +1751,20 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.1.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "filetime" -version = "0.2.23" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.4.1", - "windows-sys 0.52.0", + "libredox", + "windows-sys 0.59.0", ] [[package]] @@ -1816,9 +1781,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" dependencies = [ "crc32fast", "miniz_oxide", @@ -1843,9 +1808,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] name = "foreign-types" @@ -1873,23 +1838,23 @@ dependencies = [ [[package]] name = "fs_at" -version = "0.1.10" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982f82cc75107eef84f417ad6c53ae89bf65b561937ca4a3b3b0fd04d0aa2425" +checksum = "14af6c9694ea25db25baa2a1788703b9e7c6648dcaeeebeb98f7561b5384c036" dependencies = [ "aligned", "cfg-if", "cvt", "libc", "nix", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -1902,9 +1867,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -1912,15 +1877,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -1929,9 +1894,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-lite" @@ -1950,11 +1915,11 @@ dependencies = [ [[package]] name = "futures-lite" -version = "2.3.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" dependencies = [ - "fastrand 2.1.0", + "fastrand 2.3.0", "futures-core", "futures-io", "parking", @@ -1963,26 +1928,26 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.100", ] [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-timer" @@ -1992,9 +1957,9 @@ checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -2036,20 +2001,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", ] [[package]] name = "getrandom" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" dependencies = [ "cfg-if", + "js-sys", "libc", - "wasi 0.13.3+wasi-0.2.2", - "windows-targets 0.52.5", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", + "wasm-bindgen", ] [[package]] @@ -2064,21 +2033,21 @@ dependencies = [ [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "glob" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "globset" -version = "0.4.14" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" +checksum = "54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5" dependencies = [ "aho-corasick", "bstr", @@ -2100,9 +2069,9 @@ dependencies = [ [[package]] name = "gloo-timers" -version = "0.2.6" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" dependencies = [ "futures-channel", "futures-core", @@ -2116,13 +2085,13 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ - "bytes 1.6.0", + "bytes 1.10.1", "fnv", "futures-core", "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.2.6", + "indexmap 2.8.0", "slab", "tokio", "tokio-util", @@ -2131,17 +2100,17 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" +checksum = "5017294ff4bb30944501348f6f8e42e6ad28f42c8bbef7a74029aff064a4e3c2" dependencies = [ "atomic-waker", - "bytes 1.6.0", + "bytes 1.10.1", "fnv", "futures-core", "futures-sink", - "http 1.1.0", - "indexmap 2.2.6", + "http 1.3.1", + "indexmap 2.8.0", "slab", "tokio", "tokio-util", @@ -2150,9 +2119,9 @@ dependencies = [ [[package]] name = "half" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +checksum = "7db2ff139bba50379da6aa0766b52fdcb62cb5b263009b09ed58ba604e14bbd1" dependencies = [ "cfg-if", "crunchy", @@ -2179,6 +2148,12 @@ version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + [[package]] name = "heapless" version = "0.8.0" @@ -2202,6 +2177,18 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + +[[package]] +name = "hermit-abi" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbd780fe5cc30f81464441920d82ac8740e2e46b29a6fad543ddd075229ce37e" + [[package]] name = "hex" version = "0.4.3" @@ -2230,11 +2217,11 @@ dependencies = [ [[package]] name = "home" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2254,41 +2241,41 @@ version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ - "bytes 1.6.0", + "bytes 1.10.1", "fnv", "itoa", ] [[package]] name = "http" -version = "1.1.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" dependencies = [ - "bytes 1.6.0", + "bytes 1.10.1", "fnv", "itoa", ] [[package]] name = "http-body" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ - "bytes 1.6.0", - "http 1.1.0", + "bytes 1.10.1", + "http 1.3.1", ] [[package]] name = "http-body-util" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ - "bytes 1.6.0", + "bytes 1.10.1", "futures-core", - "http 1.1.0", + "http 1.3.1", "http-body", "pin-project-lite", ] @@ -2336,9 +2323,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.8.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "httpdate" @@ -2348,21 +2335,21 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "humantime" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +checksum = "9b112acc8b3adf4b107a8ec20977da0273a8c386765a3ec0229bd500a1443f9f" [[package]] name = "hyper" -version = "1.3.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" +checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" dependencies = [ - "bytes 1.6.0", + "bytes 1.10.1", "futures-channel", "futures-util", - "h2 0.4.6", - "http 1.1.0", + "h2 0.4.8", + "http 1.3.1", "http-body", "httparse", "httpdate", @@ -2375,26 +2362,27 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.26.0" +version = "0.27.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" +checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" dependencies = [ "futures-util", - "http 1.1.0", + "http 1.3.1", "hyper", "hyper-util", - "rustls 0.22.4", + "rustls", "rustls-pki-types", "tokio", "tokio-rustls", "tower-service", + "webpki-roots", ] [[package]] name = "hyper-timeout" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3203a961e5c83b6f5498933e78b6b263e208c197b63e9c6c53cc82ffd3f63793" +checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" dependencies = [ "hyper", "hyper-util", @@ -2409,7 +2397,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ - "bytes 1.6.0", + "bytes 1.10.1", "http-body-util", "hyper", "hyper-util", @@ -2421,29 +2409,28 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.5" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b875924a60b96e5d7b9ae7b066540b1dd1cbd90d1828f54c92e02a283351c56" +checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" dependencies = [ - "bytes 1.6.0", + "bytes 1.10.1", "futures-channel", "futures-util", - "http 1.1.0", + "http 1.3.1", "http-body", "hyper", "pin-project-lite", - "socket2 0.5.7", + "socket2 0.5.8", "tokio", - "tower 0.4.13", "tower-service", "tracing", ] [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -2462,6 +2449,124 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -2470,19 +2575,30 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.5.0" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "icu_normalizer", + "icu_properties", ] [[package]] name = "ignore" -version = "0.4.22" +version = "0.4.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" +checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b" dependencies = [ "crossbeam-deque", "globset", @@ -2494,6 +2610,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "impl-more" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a5a9a0ff0086c7a148acb942baaabeadf9504d10400b5a05645853729b9cd2" + [[package]] name = "indexmap" version = "1.9.3" @@ -2506,12 +2628,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.6" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.15.2", ] [[package]] @@ -2535,26 +2657,26 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", "windows-sys 0.48.0", ] [[package]] name = "ipnet" -version = "2.9.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" [[package]] name = "is-terminal" -version = "0.4.12" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ - "hermit-abi", + "hermit-abi 0.5.0", "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2593,34 +2715,35 @@ dependencies = [ [[package]] name = "itertools" -version = "0.12.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" dependencies = [ "either", ] [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jobserver" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -2641,9 +2764,9 @@ checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "lazycell" @@ -2666,53 +2789,76 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.155" +version = "0.2.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" [[package]] name = "libloading" -version = "0.8.3" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] name = "libnghttp2-sys" -version = "0.1.10+1.61.0" +version = "0.1.11+1.64.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "959c25552127d2e1fa72f0e52548ec04fc386e827ba71a7bd01db46a447dc135" +checksum = "1b6c24e48a7167cffa7119da39d577fa482e66c688a4aac016bee862e1a713c4" dependencies = [ "cc", "libc", ] [[package]] -name = "libz-sys" -version = "1.1.18" +name = "libredox" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c15da26e5af7e25c90b37a2d75cdbf940cf4a55316de9d84c679c9b8bfabf82e" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "cc", + "bitflags 2.9.0", "libc", - "pkg-config", - "vcpkg", + "redox_syscall", ] [[package]] -name = "linux-raw-sys" +name = "libz-sys" +version = "1.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b70e7a7df205e92a1a4cd9aaae7898dac0aa555503cc0a649494d0d60e7651d" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linux-raw-sys" version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "linux-raw-sys" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" + +[[package]] +name = "litemap" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" [[package]] name = "local-channel" @@ -2743,9 +2889,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" dependencies = [ "value-bag", ] @@ -2764,9 +2910,9 @@ checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" [[package]] name = "memchr" -version = "2.7.2" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "mime" @@ -2776,9 +2922,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "mime_guess" -version = "2.0.4" +version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" dependencies = [ "mime", "unicase", @@ -2792,30 +2938,30 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" +checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" dependencies = [ - "adler", + "adler2", ] [[package]] name = "mio" -version = "0.8.11" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "native-tls" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" dependencies = [ "libc", "log", @@ -2845,12 +2991,13 @@ checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" [[package]] name = "nix" -version = "0.26.4" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.9.0", "cfg-if", + "cfg_aliases", "libc", ] @@ -2886,11 +3033,11 @@ dependencies = [ [[package]] name = "normpath" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5831952a9476f2fed74b77d74182fa5ddc4d21c72ec45a333b250e3ed0272804" +checksum = "c8911957c4b1549ac0dc74e30db9c8b0e66ddcd6d7acc33098f4c63a64a6d7ed" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2924,51 +3071,51 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", ] [[package]] name = "num_enum" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" dependencies = [ "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.100", ] [[package]] name = "object" -version = "0.35.0" +version = "0.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5e" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" [[package]] name = "oorandom" -version = "11.1.3" +version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" [[package]] name = "opaque-debug" @@ -2978,11 +3125,11 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.70" +version = "0.10.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61cfb4e166a8bb8c9b55c500bc2308550148ece889be90f609377e58140f42c6" +checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.9.0", "cfg-if", "foreign-types", "libc", @@ -2999,20 +3146,20 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.100", ] [[package]] name = "openssl-probe" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" -version = "0.9.105" +version = "0.9.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b22d5b84be05a8d6947c7cb71f7c849aa0f112acd4bf51c2a7c1c988ac0a9dc" +checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" dependencies = [ "cc", "libc", @@ -3022,9 +3169,9 @@ dependencies = [ [[package]] name = "os_info" -version = "3.8.2" +version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae99c7fa6dd38c7cafe1ec085e804f8f555a2f8659b0dbe03f1f9963a9b51092" +checksum = "2a604e53c24761286860eba4e2c8b23a0161526476b1de520139d69cdb85a6b5" dependencies = [ "log", "serde", @@ -3039,9 +3186,9 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "parking" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" @@ -3061,17 +3208,11 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.1", + "redox_syscall", "smallvec", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - [[package]] name = "peeking_take_while" version = "0.1.2" @@ -3086,29 +3227,29 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project" -version = "1.1.5" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.5" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.100", ] [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "pin-utils" @@ -3118,26 +3259,26 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "piper" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "464db0c665917b13ebb5d453ccdec4add5658ee1adc7affc7677615356a8afaf" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" dependencies = [ "atomic-waker", - "fastrand 2.1.0", + "fastrand 2.3.0", "futures-io", ] [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "plotters" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" dependencies = [ "num-traits", "plotters-backend", @@ -3148,15 +3289,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" [[package]] name = "plotters-svg" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" dependencies = [ "plotters-backend", ] @@ -3179,17 +3320,17 @@ dependencies = [ [[package]] name = "polling" -version = "3.7.0" +version = "3.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645493cf344456ef24219d02a768cf1fb92ddf8c92161679ae3d91b91a637be3" +checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f" dependencies = [ "cfg-if", "concurrent-queue", - "hermit-abi", + "hermit-abi 0.4.0", "pin-project-lite", - "rustix 0.38.34", + "rustix 0.38.44", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3211,9 +3352,12 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] [[package]] name = "pretty_env_logger" @@ -3227,35 +3371,33 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.1.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" dependencies = [ "toml_edit", ] [[package]] -name = "proc-macro-error" -version = "1.0.4" +name = "proc-macro-error-attr2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" dependencies = [ - "proc-macro-error-attr", "proc-macro2", "quote", - "syn 1.0.109", - "version_check", ] [[package]] -name = "proc-macro-error-attr" -version = "1.0.4" +name = "proc-macro-error2" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" dependencies = [ + "proc-macro-error-attr2", "proc-macro2", "quote", - "version_check", + "syn 2.0.100", ] [[package]] @@ -3266,20 +3408,20 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.84" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" dependencies = [ "unicode-ident", ] [[package]] name = "prost" -version = "0.13.3" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0487d90e047de87f984913713b85c601c05609aad5b0df4b4573fbf69aa13f" +checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" dependencies = [ - "bytes 1.6.0", + "bytes 1.10.1", "prost-derive", ] @@ -3290,21 +3432,81 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" dependencies = [ "anyhow", - "itertools 0.12.1", + "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.100", +] + +[[package]] +name = "quinn" +version = "0.11.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3bd15a6f2967aef83887dcb9fec0014580467e33720d073560cf015a5683012" +dependencies = [ + "bytes 1.10.1", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash 2.1.1", + "rustls", + "socket2 0.5.8", + "thiserror 2.0.12", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b820744eb4dc9b57a3398183639c511b5a26d2ed702cedd3febaa1393caa22cc" +dependencies = [ + "bytes 1.10.1", + "getrandom 0.3.2", + "rand 0.9.0", + "ring", + "rustc-hash 2.1.1", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.12", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e46f3055866785f6b92bc6164b76be02ca8f2eb4b002c0354b28cf4c119e5944" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2 0.5.8", + "tracing", + "windows-sys 0.59.0", ] [[package]] name = "quote" -version = "1.0.36" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + [[package]] name = "rand" version = "0.7.3" @@ -3337,7 +3539,7 @@ checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.3", - "zerocopy 0.8.23", + "zerocopy", ] [[package]] @@ -3394,7 +3596,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom 0.3.1", + "getrandom 0.3.2", ] [[package]] @@ -3428,27 +3630,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.5.1" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.9.0", ] [[package]] name = "regex" -version = "1.10.4" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -3458,9 +3651,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -3469,15 +3662,15 @@ dependencies = [ [[package]] name = "regex-lite" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b661b2f27137bdbc16f00eda72866a92bb28af1753ffbd56744fb6e2e9cd8e" +checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" [[package]] name = "regex-syntax" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "relative-path" @@ -3487,32 +3680,30 @@ checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" [[package]] name = "remove_dir_all" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23895cfadc1917fed9c6ed76a8c2903615fa3704f7493ff82b364c6540acc02b" +checksum = "a694f9e0eb3104451127f6cc1e5de55f59d3b1fc8c5ddfaeb6f1e716479ceb4a" dependencies = [ - "aligned", "cfg-if", "cvt", "fs_at", - "lazy_static", "libc", "normpath", - "windows-sys 0.45.0", + "windows-sys 0.59.0", ] [[package]] name = "reqwest" -version = "0.12.4" +version = "0.12.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" +checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" dependencies = [ "base64 0.22.1", - "bytes 1.6.0", + "bytes 1.10.1", "futures-channel", "futures-core", "futures-util", - "http 1.1.0", + "http 1.3.1", "http-body", "http-body-util", "hyper", @@ -3527,23 +3718,25 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.22.4", + "quinn", + "rustls", "rustls-pemfile", "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", - "sync_wrapper 0.1.2", + "sync_wrapper", "tokio", "tokio-native-tls", "tokio-rustls", + "tower 0.5.2", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", "webpki-roots", - "winreg", + "windows-registry", ] [[package]] @@ -3569,7 +3762,7 @@ dependencies = [ "futures", "futures-timer", "rstest_macros", - "rustc_version 0.4.0", + "rustc_version 0.4.1", ] [[package]] @@ -3584,8 +3777,8 @@ dependencies = [ "quote", "regex", "relative-path", - "rustc_version 0.4.0", - "syn 2.0.79", + "rustc_version 0.4.1", + "syn 2.0.100", "unicode-ident", ] @@ -3601,6 +3794,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + [[package]] name = "rustc_version" version = "0.2.3" @@ -3612,18 +3811,18 @@ dependencies = [ [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "semver 1.0.23", + "semver 1.0.26", ] [[package]] name = "rustix" -version = "0.37.27" +version = "0.37.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" +checksum = "519165d378b97752ca44bbe15047d5d3409e875f39327546b42ac81d7e18c1b6" dependencies = [ "bitflags 1.3.2", "errno", @@ -3635,36 +3834,35 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.9.0", "errno", "libc", - "linux-raw-sys 0.4.14", - "windows-sys 0.52.0", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", ] [[package]] -name = "rustls" -version = "0.22.4" +name = "rustix" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" +checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96" dependencies = [ - "log", - "ring", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", + "bitflags 2.9.0", + "errno", + "libc", + "linux-raw-sys 0.9.3", + "windows-sys 0.59.0", ] [[package]] name = "rustls" -version = "0.23.18" +version = "0.23.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9cc1d47e243d655ace55ed38201c19ae02c148ae56412ab8750e8f0166ab7f" +checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c" dependencies = [ "log", "once_cell", @@ -3677,25 +3875,27 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" dependencies = [ - "base64 0.22.1", "rustls-pki-types", ] [[package]] name = "rustls-pki-types" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" +checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" +dependencies = [ + "web-time", +] [[package]] name = "rustls-webpki" -version = "0.102.8" +version = "0.103.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +checksum = "0aa4eeac2588ffff23e9d7a7e9b3f971c5fb5b7ebc9452745e0c232c64f83b2f" dependencies = [ "ring", "rustls-pki-types", @@ -3704,15 +3904,15 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.17" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "same-file" @@ -3725,11 +3925,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.23" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3740,11 +3940,11 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "security-framework" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.9.0", "core-foundation", "core-foundation-sys", "libc", @@ -3753,9 +3953,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.11.0" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" dependencies = [ "core-foundation-sys", "libc", @@ -3772,9 +3972,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.23" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" dependencies = [ "serde", ] @@ -3801,7 +4001,7 @@ dependencies = [ "native-tls", "pretty_env_logger", "reqwest", - "rustls 0.23.18", + "rustls", "sentry-anyhow", "sentry-backtrace", "sentry-contexts", @@ -3863,7 +4063,7 @@ dependencies = [ "hostname", "libc", "os_info", - "rustc_version 0.4.0", + "rustc_version 0.4.1", "sentry", "sentry-core", "uname", @@ -3887,7 +4087,7 @@ dependencies = [ "sentry-types", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tokio", "uuid", ] @@ -3938,7 +4138,7 @@ version = "0.36.0" dependencies = [ "anyhow", "axum 0.8.1", - "http 1.1.0", + "http 1.3.1", "pin-project", "prost", "sentry", @@ -3977,39 +4177,40 @@ dependencies = [ "rstest", "serde", "serde_json", - "thiserror", - "time 0.3.36", + "thiserror 1.0.69", + "time 0.3.40", "url", "uuid", ] [[package]] name = "serde" -version = "1.0.203" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.100", ] [[package]] name = "serde_json" -version = "1.0.117" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -4022,7 +4223,7 @@ checksum = "c7715380eec75f029a4ef7de39a9200e0a63823176b759d055b613f5a87df6a6" dependencies = [ "percent-encoding", "serde", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -4059,9 +4260,9 @@ dependencies = [ [[package]] name = "sha1_smol" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" +checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" [[package]] name = "sha2" @@ -4131,9 +4332,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.2" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" [[package]] name = "socket2" @@ -4147,9 +4348,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" dependencies = [ "libc", "windows-sys 0.52.0", @@ -4275,14 +4476,14 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.79", + "syn 2.0.100", ] [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "surf" @@ -4319,9 +4520,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.79" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", @@ -4330,26 +4531,35 @@ dependencies = [ [[package]] name = "sync_wrapper" -version = "0.1.2" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] [[package]] -name = "sync_wrapper" -version = "1.0.1" +name = "synstructure" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] [[package]] name = "tempfile" -version = "3.10.1" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "488960f40a3fd53d72c2a29a58722561dee8afdd175bd88e3db4677d7b2ba600" dependencies = [ - "cfg-if", - "fastrand 2.1.0", - "rustix 0.38.34", - "windows-sys 0.52.0", + "fastrand 2.3.0", + "getrandom 0.3.2", + "once_cell", + "rustix 1.0.3", + "windows-sys 0.59.0", ] [[package]] @@ -4363,22 +4573,42 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.61" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ - "thiserror-impl", + "thiserror-impl 2.0.12", ] [[package]] name = "thiserror-impl" -version = "1.0.61" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.100", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", ] [[package]] @@ -4408,9 +4638,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.36" +version = "0.3.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "9d9c75b47bdff86fa3334a3db91356b8d7d86a9b839dab7d0bdc5c3d3a077618" dependencies = [ "deranged", "itoa", @@ -4418,14 +4648,14 @@ dependencies = [ "powerfmt", "serde", "time-core", - "time-macros 0.2.18", + "time-macros 0.2.21", ] [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" [[package]] name = "time-macros" @@ -4439,9 +4669,9 @@ dependencies = [ [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "29aa485584182073ed57fd5004aa09c371f021325014694e432313345865fd04" dependencies = [ "num-conv", "time-core", @@ -4460,6 +4690,16 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinytemplate" version = "1.2.1" @@ -4472,9 +4712,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" dependencies = [ "tinyvec_macros", ] @@ -4487,32 +4727,31 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.37.0" +version = "1.44.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" dependencies = [ "backtrace", - "bytes 1.6.0", + "bytes 1.10.1", "libc", "mio", - "num_cpus", "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.7", + "socket2 0.5.8", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.100", ] [[package]] @@ -4527,20 +4766,19 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.25.0" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" dependencies = [ - "rustls 0.22.4", - "rustls-pki-types", + "rustls", "tokio", ] [[package]] name = "tokio-stream" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" dependencies = [ "futures-core", "pin-project-lite", @@ -4549,11 +4787,11 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.11" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034" dependencies = [ - "bytes 1.6.0", + "bytes 1.10.1", "futures-core", "futures-sink", "pin-project-lite", @@ -4562,17 +4800,17 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" [[package]] name = "toml_edit" -version = "0.21.1" +version = "0.22.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.8.0", "toml_datetime", "winnow", ] @@ -4585,11 +4823,11 @@ checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" dependencies = [ "async-stream", "async-trait", - "axum 0.7.5", + "axum 0.7.9", "base64 0.22.1", - "bytes 1.6.0", - "h2 0.4.6", - "http 1.1.0", + "bytes 1.10.1", + "h2 0.4.8", + "http 1.3.1", "http-body", "http-body-util", "hyper", @@ -4598,7 +4836,7 @@ dependencies = [ "percent-encoding", "pin-project", "prost", - "socket2 0.5.7", + "socket2 0.5.8", "tokio", "tokio-stream", "tower 0.4.13", @@ -4636,7 +4874,8 @@ dependencies = [ "futures-core", "futures-util", "pin-project-lite", - "sync_wrapper 1.0.1", + "sync_wrapper", + "tokio", "tower-layer", "tower-service", ] @@ -4655,9 +4894,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "log", "pin-project-lite", @@ -4667,20 +4906,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.100", ] [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -4709,9 +4948,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "nu-ansi-term", "sharded-slab", @@ -4729,9 +4968,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "typenum" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] name = "uname" @@ -4753,39 +4992,21 @@ dependencies = [ [[package]] name = "unicase" -version = "2.7.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-normalization" -version = "0.1.23" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" -dependencies = [ - "tinyvec", -] +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "unicode-xid" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "universal-hash" @@ -4805,15 +5026,15 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "2.10.1" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b74fc6b57825be3373f7054754755f03ac3a8f5d70015ccad699ba2029956f4a" +checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d" dependencies = [ "base64 0.22.1", "log", "native-tls", "once_cell", - "rustls 0.23.18", + "rustls", "rustls-pki-types", "url", "webpki-roots", @@ -4821,9 +5042,9 @@ dependencies = [ [[package]] name = "url" -version = "2.5.0" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", @@ -4831,27 +5052,39 @@ dependencies = [ "serde", ] +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "uuid" -version = "1.8.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.3.2", "serde", ] [[package]] name = "valuable" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] name = "value-bag" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a84c137d37ab0142f0f2ddfe332651fdbf252e7b7dbb4e67b6c1f1b2e925101" +checksum = "3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2" [[package]] name = "vcpkg" @@ -4861,9 +5094,9 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "void" @@ -4910,55 +5143,57 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasi" -version = "0.13.3+wasi-0.2.2" +version = "0.14.2+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" dependencies = [ "wit-bindgen-rt", ] [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", + "once_cell", + "rustversion", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.100", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.42" +version = "0.4.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" dependencies = [ "cfg-if", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4966,28 +5201,41 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.100", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] [[package]] name = "web-sys" -version = "0.3.69" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ "js-sys", "wasm-bindgen", @@ -4995,9 +5243,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.26.1" +version = "0.26.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" +checksum = "2210b291f7ea53617fbafcc4939f10914214ec15aace5ba62293a668f322c5c9" dependencies = [ "rustls-pki-types", ] @@ -5011,7 +5259,7 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.34", + "rustix 0.38.44", ] [[package]] @@ -5032,11 +5280,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -5052,7 +5300,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" dependencies = [ "windows-core", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -5061,16 +5309,42 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] -name = "windows-sys" -version = "0.45.0" +name = "windows-link" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" + +[[package]] +name = "windows-registry" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" dependencies = [ - "windows-targets 0.42.2", + "windows-result", + "windows-strings", + "windows-targets 0.53.0", +] + +[[package]] +name = "windows-result" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" +dependencies = [ + "windows-link", ] [[package]] @@ -5088,22 +5362,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] -name = "windows-targets" -version = "0.42.2" +name = "windows-sys" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "windows-targets 0.52.6", ] [[package]] @@ -5123,25 +5391,35 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", - "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" +name = "windows-targets" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] [[package]] name = "windows_aarch64_gnullvm" @@ -5151,15 +5429,15 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" +name = "windows_aarch64_gnullvm" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" [[package]] name = "windows_aarch64_msvc" @@ -5169,15 +5447,15 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] -name = "windows_i686_gnu" -version = "0.42.2" +name = "windows_aarch64_msvc" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" [[package]] name = "windows_i686_gnu" @@ -5187,21 +5465,27 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] -name = "windows_i686_msvc" -version = "0.42.2" +name = "windows_i686_gnullvm" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" [[package]] name = "windows_i686_msvc" @@ -5211,15 +5495,15 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" +name = "windows_i686_msvc" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" [[package]] name = "windows_x86_64_gnu" @@ -5229,15 +5513,15 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" +name = "windows_x86_64_gnu" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" [[package]] name = "windows_x86_64_gnullvm" @@ -5247,15 +5531,15 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" +name = "windows_x86_64_gnullvm" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" [[package]] name = "windows_x86_64_msvc" @@ -5265,45 +5549,68 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" [[package]] name = "winnow" -version = "0.5.40" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36" dependencies = [ "memchr", ] [[package]] -name = "winreg" -version = "0.52.0" +name = "wit-bindgen-rt" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ - "cfg-if", - "windows-sys 0.48.0", + "bitflags 2.9.0", ] [[package]] -name = "wit-bindgen-rt" -version = "0.33.0" +name = "write16" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" dependencies = [ - "bitflags 2.5.0", + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", ] [[package]] -name = "zerocopy" -version = "0.7.34" +name = "yoke-derive" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ - "zerocopy-derive 0.7.34", + "proc-macro2", + "quote", + "syn 2.0.100", + "synstructure", ] [[package]] @@ -5312,29 +5619,39 @@ version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6" dependencies = [ - "zerocopy-derive 0.8.23", + "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.34" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" +checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.100", ] [[package]] -name = "zerocopy-derive" -version = "0.8.23" +name = "zerofrom" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.100", + "synstructure", ] [[package]] @@ -5343,29 +5660,51 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "zstd" -version = "0.13.1" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d789b1514203a1120ad2429eae43a7bd32b90976a7bb8a05f7ec02fa88cc23a" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "7.1.0" +version = "7.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd99b45c6bc03a018c8b8a86025678c87e55526064e38f9df301989dce7ec0a" +checksum = "f3051792fbdc2e1e143244dc28c60f73d8470e93f3f9cbd0ead44da5ed802722" dependencies = [ "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.10+zstd.1.5.6" +version = "2.0.14+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" +checksum = "8fb060d4926e4ac3a3ad15d864e99ceb5f343c6b34f5bd6d81ae6ed417311be5" dependencies = [ "cc", "pkg-config", diff --git a/README.md b/README.md index 606000942..5913abf8b 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ best API and adding new features. We currently only verify this crate against a recent version of Sentry hosted on [sentry.io](https://sentry.io/) but it should work with on-prem Sentry versions 20.6 and later. -The **Minimum Supported Rust Version** is currently at _1.75.0_. +The **Minimum Supported Rust Version** is currently at _1.81.0_. The Sentry crates tries to support a _6 months_ old Rust version at time of release, and the MSRV will be increased in accordance with its dependencies. diff --git a/clippy.toml b/clippy.toml index 130672505..5e90250c4 100644 --- a/clippy.toml +++ b/clippy.toml @@ -1 +1 @@ -msrv = "1.75.0" +msrv = "1.81.0" diff --git a/sentry-actix/Cargo.toml b/sentry-actix/Cargo.toml index d9554bb04..56aa7b90e 100644 --- a/sentry-actix/Cargo.toml +++ b/sentry-actix/Cargo.toml @@ -10,7 +10,7 @@ description = """ Sentry client extension for actix-web 3. """ edition = "2021" -rust-version = "1.75" +rust-version = "1.81" [dependencies] actix-web = { version = "4", default-features = false } diff --git a/sentry-anyhow/Cargo.toml b/sentry-anyhow/Cargo.toml index 5397edd6a..1b64f5dd9 100644 --- a/sentry-anyhow/Cargo.toml +++ b/sentry-anyhow/Cargo.toml @@ -10,7 +10,7 @@ description = """ Sentry integration for anyhow. """ edition = "2021" -rust-version = "1.75" +rust-version = "1.81" [features] default = ["backtrace"] diff --git a/sentry-backtrace/Cargo.toml b/sentry-backtrace/Cargo.toml index 51902fed5..ffafc2e5d 100644 --- a/sentry-backtrace/Cargo.toml +++ b/sentry-backtrace/Cargo.toml @@ -10,7 +10,7 @@ description = """ Sentry integration and utilities for dealing with stacktraces. """ edition = "2021" -rust-version = "1.75" +rust-version = "1.81" [dependencies] backtrace = "0.3.44" diff --git a/sentry-contexts/Cargo.toml b/sentry-contexts/Cargo.toml index 627440399..4e5366e3c 100644 --- a/sentry-contexts/Cargo.toml +++ b/sentry-contexts/Cargo.toml @@ -11,7 +11,7 @@ Sentry integration for os, device, and rust contexts. """ build = "build.rs" edition = "2021" -rust-version = "1.75" +rust-version = "1.81" [dependencies] sentry-core = { version = "0.36.0", path = "../sentry-core" } diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index e372cb1eb..7f0b43193 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -10,7 +10,7 @@ description = """ Core sentry library used for instrumentation and integration development. """ edition = "2021" -rust-version = "1.75" +rust-version = "1.81" [package.metadata.docs.rs] all-features = true diff --git a/sentry-debug-images/Cargo.toml b/sentry-debug-images/Cargo.toml index 26b32f8f0..e1bcc6ba3 100644 --- a/sentry-debug-images/Cargo.toml +++ b/sentry-debug-images/Cargo.toml @@ -10,7 +10,7 @@ description = """ Sentry integration that adds the list of loaded libraries to events. """ edition = "2021" -rust-version = "1.75" +rust-version = "1.81" [dependencies] findshlibs = "=0.10.2" diff --git a/sentry-log/Cargo.toml b/sentry-log/Cargo.toml index b8f2b2c19..4b9ab49be 100644 --- a/sentry-log/Cargo.toml +++ b/sentry-log/Cargo.toml @@ -10,7 +10,7 @@ description = """ Sentry integration for log and env_logger crates. """ edition = "2021" -rust-version = "1.75" +rust-version = "1.81" [dependencies] sentry-core = { version = "0.36.0", path = "../sentry-core" } diff --git a/sentry-panic/Cargo.toml b/sentry-panic/Cargo.toml index d7eedbcc3..c709f41ca 100644 --- a/sentry-panic/Cargo.toml +++ b/sentry-panic/Cargo.toml @@ -10,7 +10,7 @@ description = """ Sentry integration for capturing panics. """ edition = "2021" -rust-version = "1.75" +rust-version = "1.81" [dependencies] sentry-core = { version = "0.36.0", path = "../sentry-core" } diff --git a/sentry-slog/Cargo.toml b/sentry-slog/Cargo.toml index 6cb59ee5c..cdf6aa999 100644 --- a/sentry-slog/Cargo.toml +++ b/sentry-slog/Cargo.toml @@ -10,7 +10,7 @@ description = """ Sentry integration for the slog crate. """ edition = "2021" -rust-version = "1.75" +rust-version = "1.81" [dependencies] sentry-core = { version = "0.36.0", path = "../sentry-core" } diff --git a/sentry-tower/Cargo.toml b/sentry-tower/Cargo.toml index 175a72814..bed8363f6 100644 --- a/sentry-tower/Cargo.toml +++ b/sentry-tower/Cargo.toml @@ -10,7 +10,7 @@ description = """ Sentry integration for tower-based crates. """ edition = "2021" -rust-version = "1.75" +rust-version = "1.81" [package.metadata.docs.rs] all-features = true diff --git a/sentry-tracing/Cargo.toml b/sentry-tracing/Cargo.toml index ffa7054a1..ead02d13a 100644 --- a/sentry-tracing/Cargo.toml +++ b/sentry-tracing/Cargo.toml @@ -10,7 +10,7 @@ description = """ Sentry integration for tracing and tracing-subscriber crates. """ edition = "2021" -rust-version = "1.75" +rust-version = "1.81" [package.metadata.docs.rs] all-features = true diff --git a/sentry-types/Cargo.toml b/sentry-types/Cargo.toml index 2afcb34e7..205b41178 100644 --- a/sentry-types/Cargo.toml +++ b/sentry-types/Cargo.toml @@ -11,7 +11,7 @@ Common reusable types for implementing the sentry.io protocol. """ keywords = ["sentry", "protocol"] edition = "2021" -rust-version = "1.75" +rust-version = "1.81" [package.metadata.docs.rs] all-features = true diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index 50ece0ca8..afba9ffa5 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -10,7 +10,7 @@ description = """ Sentry (getsentry.com) client for rust ;) """ edition = "2021" -rust-version = "1.75" +rust-version = "1.81" autoexamples = true # To build locally: From e9661c7abde71a783bec42e266cf30a83550b1e4 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Thu, 20 Mar 2025 10:21:54 +0100 Subject: [PATCH 055/148] fix(tracing): wrap error with synthetic mechanism only if attaching stacktrace (#755) --- sentry-tracing/src/converters.rs | 48 +++++++++++++++----------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/sentry-tracing/src/converters.rs b/sentry-tracing/src/converters.rs index acce10552..836e8933d 100644 --- a/sentry-tracing/src/converters.rs +++ b/sentry-tracing/src/converters.rs @@ -1,7 +1,7 @@ use std::collections::BTreeMap; use std::error::Error; -use sentry_core::protocol::{Event, Exception, Mechanism, Thread, Value}; +use sentry_core::protocol::{Event, Exception, Mechanism, Value}; use sentry_core::{event_from_error, Breadcrumb, Level, TransactionOrSpan}; use tracing_core::field::{Field, Visit}; use tracing_core::Subscriber; @@ -21,6 +21,7 @@ fn convert_tracing_level(level: &tracing_core::Level) -> Level { } } +#[allow(unused)] fn level_to_exception_type(level: &tracing_core::Level) -> &'static str { match *level { tracing_core::Level::TRACE => "tracing::trace!", @@ -248,41 +249,38 @@ where // proper grouping and issue metadata generation. tracing_core::Record does not contain sufficient // information for this. However, it may contain a serialized error which we can parse to emit // an exception record. + #[allow(unused_mut)] let (mut message, visitor) = extract_event_data_with_context(event, ctx.into()); let FieldVisitor { mut exceptions, mut json_values, } = visitor; - // If there are both a message and an exception, then add the message as synthetic wrapper - // around the exception to support proper grouping. If configured, also add the current stack - // trace to this exception directly, since it points to the place where the exception is - // captured. + // If there are a message, an exception, and we are capturing stack traces, then add the message + // as synthetic wrapper around the exception to support proper grouping. The stack trace to + // attach is the current one, since it points to the place where the exception is captured. + // We should only do this if we're capturing stack traces, otherwise the issue title will be `` + // as Sentry will attempt to use missing stack trace to determine the title. + #[cfg(feature = "backtrace")] if !exceptions.is_empty() && message.is_some() { - #[allow(unused_mut)] - let mut thread = Thread::default(); - - #[cfg(feature = "backtrace")] if let Some(client) = sentry_core::Hub::current().client() { if client.options().attach_stacktrace { - thread = sentry_backtrace::current_thread(true); + let thread = sentry_backtrace::current_thread(true); + let exception = Exception { + ty: level_to_exception_type(event.metadata().level()).to_owned(), + value: message.take(), + module: event.metadata().module_path().map(str::to_owned), + stacktrace: thread.stacktrace, + raw_stacktrace: thread.raw_stacktrace, + thread_id: thread.id, + mechanism: Some(Mechanism { + synthetic: Some(true), + ..Mechanism::default() + }), + }; + exceptions.push(exception) } } - - let exception = Exception { - ty: level_to_exception_type(event.metadata().level()).to_owned(), - value: message.take(), - module: event.metadata().module_path().map(str::to_owned), - stacktrace: thread.stacktrace, - raw_stacktrace: thread.raw_stacktrace, - thread_id: thread.id, - mechanism: Some(Mechanism { - synthetic: Some(true), - ..Mechanism::default() - }), - }; - - exceptions.push(exception); } if let Some(exception) = exceptions.last_mut() { From df0491c9895765cbb20bcb09f8c76eba0dbd19ff Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Thu, 20 Mar 2025 16:50:13 +0100 Subject: [PATCH 056/148] ref(backtrace): add entries and extra logic for in-app detection (#756) * ref(backtrace): add entries and extra logic for in-app detection --- sentry-backtrace/src/process.rs | 4 ++-- sentry-backtrace/src/trim.rs | 18 +++++++++++------- sentry-backtrace/src/utils.rs | 10 ++++++++-- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/sentry-backtrace/src/process.rs b/sentry-backtrace/src/process.rs index 82334c9a7..90c00335b 100644 --- a/sentry-backtrace/src/process.rs +++ b/sentry-backtrace/src/process.rs @@ -3,7 +3,7 @@ use std::borrow::Cow; use backtrace::Backtrace; use sentry_core::ClientOptions; -use crate::trim::{is_sys_function, trim_stacktrace}; +use crate::trim::{is_well_known_not_in_app, trim_stacktrace}; use crate::utils::{ demangle_symbol, filename, function_starts_with, parse_crate_name, strip_symbol, }; @@ -72,7 +72,7 @@ pub fn process_event_stacktrace(stacktrace: &mut Stacktrace, options: &ClientOpt continue; } - if is_sys_function(func_name) { + if is_well_known_not_in_app(func_name) { frame.in_app = Some(false); } } diff --git a/sentry-backtrace/src/trim.rs b/sentry-backtrace/src/trim.rs index d74150054..b1326bee5 100644 --- a/sentry-backtrace/src/trim.rs +++ b/sentry-backtrace/src/trim.rs @@ -2,7 +2,8 @@ use sentry_core::protocol::{Frame, Stacktrace}; use crate::utils::function_starts_with; -const WELL_KNOWN_SYS_MODULES: &[&str] = &[ +const WELL_KNOWN_NOT_IN_APP: &[&str] = &[ + // standard library and sentry crates "std::", "core::", "alloc::", @@ -13,11 +14,14 @@ const WELL_KNOWN_SYS_MODULES: &[&str] = &[ // these are not modules but things like __rust_maybe_catch_panic "__rust_", "___rust_", + "rust_begin_unwind", // these are well-known library frames "anyhow::", "log::", "tokio::", "tracing_core::", + "futures_core::", + "futures_util::", ]; const WELL_KNOWN_BORDER_FRAMES: &[&str] = &[ @@ -39,7 +43,7 @@ where .iter() .rev() .position(|frame| match frame.function { - Some(ref func) => is_well_known(func) || f(frame, stacktrace), + Some(ref func) => is_well_known_border_frame(func) || f(frame, stacktrace), None => false, }); @@ -49,15 +53,15 @@ where } } -/// Checks if a function is considered to be not in-app -pub fn is_sys_function(func: &str) -> bool { - WELL_KNOWN_SYS_MODULES +/// Checks if a function is from a module that shall be considered not in-app by default +pub fn is_well_known_not_in_app(func: &str) -> bool { + WELL_KNOWN_NOT_IN_APP .iter() .any(|m| function_starts_with(func, m)) } -/// Checks if a function is a well-known system function -fn is_well_known(func: &str) -> bool { +/// Checks if a function is a well-known border frame +fn is_well_known_border_frame(func: &str) -> bool { WELL_KNOWN_BORDER_FRAMES .iter() .any(|m| function_starts_with(func, m)) diff --git a/sentry-backtrace/src/utils.rs b/sentry-backtrace/src/utils.rs index 6b018ff50..f638eed45 100644 --- a/sentry-backtrace/src/utils.rs +++ b/sentry-backtrace/src/utils.rs @@ -97,12 +97,15 @@ pub fn demangle_symbol(s: &str) -> String { /// /// In trait implementations, the original type name is wrapped in "_< ... >" and colons are /// replaced with dots. This function accounts for differences while checking. +/// The ` bool { if pattern.starts_with('<') { while pattern.starts_with('<') { pattern = &pattern[1..]; - if func_name.starts_with('<') { + if func_name.starts_with(" bool { } } } else { - func_name = func_name.trim_start_matches('<').trim_start_matches("_<"); + func_name = func_name + .trim_start_matches(" Date: Mon, 24 Mar 2025 12:42:07 +0000 Subject: [PATCH 057/148] refactor(actix): simplify body_from_http (#757) --- Cargo.lock | 1 + sentry-actix/Cargo.toml | 3 ++- sentry-actix/src/lib.rs | 31 ++++++++++++------------------- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9457e131e..e62fa91bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4029,6 +4029,7 @@ version = "0.36.0" dependencies = [ "actix-http", "actix-web", + "bytes 1.10.1", "futures", "futures-util", "sentry", diff --git a/sentry-actix/Cargo.toml b/sentry-actix/Cargo.toml index 56aa7b90e..081db9f70 100644 --- a/sentry-actix/Cargo.toml +++ b/sentry-actix/Cargo.toml @@ -14,11 +14,12 @@ rust-version = "1.81" [dependencies] actix-web = { version = "4", default-features = false } +bytes = "1.2" futures-util = { version = "0.3.5", default-features = false } sentry-core = { version = "0.36.0", path = "../sentry-core", default-features = false, features = [ "client", ] } -actix-http = "3.9.0" +actix-http = "3.10" [dev-dependencies] actix-web = { version = "4" } diff --git a/sentry-actix/src/lib.rs b/sentry-actix/src/lib.rs index be0f21c3e..eea9a03a9 100644 --- a/sentry-actix/src/lib.rs +++ b/sentry-actix/src/lib.rs @@ -78,12 +78,11 @@ use std::sync::Arc; use actix_http::header::{self, HeaderMap}; use actix_web::dev::{Service, ServiceRequest, ServiceResponse, Transform}; -use actix_web::error::PayloadError; use actix_web::http::StatusCode; -use actix_web::web::BytesMut; -use actix_web::{Error, HttpMessage}; +use actix_web::Error; +use bytes::{Bytes, BytesMut}; use futures_util::future::{ok, Future, Ready}; -use futures_util::FutureExt; +use futures_util::{FutureExt as _, TryStreamExt as _}; use sentry_core::protocol::{self, ClientSdkPackage, Event, Request}; use sentry_core::MaxRequestBodySize; @@ -239,26 +238,20 @@ fn should_capture_request_body( } /// Extract a body from the HTTP request -async fn body_from_http(req: &mut ServiceRequest) -> Result { - let mut stream = req.take_payload(); +async fn body_from_http(req: &mut ServiceRequest) -> actix_web::Result { + let stream = req.extract::().await?; + let body = stream.try_collect::().await?.freeze(); - let mut body = BytesMut::new(); - while let Some(chunk) = futures_util::StreamExt::next(&mut stream).await { - let chunk = chunk?; - body.extend_from_slice(&chunk); - } - let (_, mut orig_payload) = actix_http::h1::Payload::create(true); - orig_payload.unread_data(body.clone().freeze()); - req.set_payload(actix_web::dev::Payload::from(orig_payload)); + // put copy of payload back into request for downstream to read + req.set_payload(actix_web::dev::Payload::from(body.clone())); - Ok::<_, PayloadError>(body) + Ok(body) } async fn capture_request_body(req: &mut ServiceRequest) -> String { - if let Ok(request_body) = body_from_http(req).await { - String::from_utf8_lossy(&request_body).into_owned() - } else { - String::new() + match body_from_http(req).await { + Ok(request_body) => String::from_utf8_lossy(&request_body).into_owned(), + Err(_) => String::new(), } } From 44fa0cfcffb9b2e19e4d161acaa4cec2518565b6 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Wed, 26 Mar 2025 13:48:45 +0100 Subject: [PATCH 058/148] fix(actix): process request in other middleware using correct Hub (#758) * feat(actix): pass request Hub in request extensions * Update lib.rs * improve * improve * fixes * import --- sentry-actix/src/lib.rs | 61 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/sentry-actix/src/lib.rs b/sentry-actix/src/lib.rs index eea9a03a9..e5a549d49 100644 --- a/sentry-actix/src/lib.rs +++ b/sentry-actix/src/lib.rs @@ -3,8 +3,7 @@ //! //! To use this middleware just configure Sentry and then add it to your actix web app as a //! middleware. Because actix is generally working with non sendable objects and highly concurrent -//! this middleware creates a new hub per request. As a result many of the sentry integrations -//! such as breadcrumbs do not work unless you bind the actix hub. +//! this middleware creates a new Hub per request. //! //! # Example //! @@ -59,11 +58,15 @@ //! # Reusing the Hub //! //! This integration will automatically create a new per-request Hub from the main Hub, and update the -//! current Hub instance. For example, the following will capture a message in the current request's Hub: +//! current Hub instance. For example, the following in the handler or in any of the subsequent +//! middleware will capture a message in the current request's Hub: //! //! ``` //! sentry::capture_message("Something is not well", sentry::Level::Warning); //! ``` +//! +//! It is recommended to register the Sentry middleware as the last, i.e. the first to be executed +//! when processing a request, so that the rest of the processing will run with the correct Hub. #![doc(html_favicon_url = "https://sentry-brand.storage.googleapis.com/favicon.ico")] #![doc(html_logo_url = "https://sentry-brand.storage.googleapis.com/sentry-glyph-black.png")] @@ -276,6 +279,7 @@ where let hub = Arc::new(Hub::new_from_top( inner.hub.clone().unwrap_or_else(Hub::main), )); + let client = hub.client(); let track_sessions = client.as_ref().is_some_and(|client| { let options = client.options(); @@ -332,7 +336,8 @@ where scope.add_event_processor(move |event| Some(process_event(event, &sentry_req))); parent_span }); - let fut = svc.call(req).bind_hub(hub.clone()); + + let fut = Hub::run(hub.clone(), || svc.call(req)).bind_hub(hub.clone()); let mut res: Self::Response = match fut.await { Ok(res) => res, Err(e) => { @@ -461,6 +466,7 @@ mod tests { use actix_web::{get, web, App, HttpRequest, HttpResponse}; use futures::executor::block_on; + use futures::future::join_all; use sentry::Level; use super::*; @@ -703,4 +709,51 @@ mod tests { } assert_eq!(items.next(), None); } + + /// Tests that the per-request Hub is used in the handler and both sides of the roundtrip + /// through middleware + #[actix_web::test] + async fn test_middleware_and_handler_use_correct_hub() { + sentry::test::with_captured_events(|| { + block_on(async { + sentry::capture_message("message outside", Level::Error); + + let handler = || { + // an event was captured in the middleware + assert!(Hub::current().last_event_id().is_some()); + sentry::capture_message("second message", Level::Error); + HttpResponse::Ok() + }; + + let app = init_service( + App::new() + .wrap_fn(|req, srv| { + // the event captured outside the per-request Hub is not there + assert!(Hub::current().last_event_id().is_none()); + + let event_id = sentry::capture_message("first message", Level::Error); + + srv.call(req).map(move |res| { + // a different event was captured in the handler + assert!(Hub::current().last_event_id().is_some()); + assert_ne!(Some(event_id), Hub::current().last_event_id()); + res + }) + }) + .wrap(Sentry::builder().with_hub(Hub::current()).finish()) + .service(web::resource("/test").to(handler)), + ) + .await; + + // test with multiple requests in parallel + let mut futures = Vec::new(); + for _ in 0..16 { + let req = TestRequest::get().uri("/test").to_request(); + futures.push(call_service(&app, req)); + } + + join_all(futures).await; + }) + }); + } } From a995b9bd66315a1bc1c0c57dd9fef270838cd8e5 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Thu, 27 Mar 2025 11:01:42 +0100 Subject: [PATCH 059/148] feat(core): add more frames to be considered not in_app (#760) --- sentry-backtrace/src/trim.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sentry-backtrace/src/trim.rs b/sentry-backtrace/src/trim.rs index b1326bee5..ec1087cc6 100644 --- a/sentry-backtrace/src/trim.rs +++ b/sentry-backtrace/src/trim.rs @@ -11,10 +11,12 @@ const WELL_KNOWN_NOT_IN_APP: &[&str] = &[ "sentry::", "sentry_core::", "sentry_types::", + "sentry_backtrace::", // these are not modules but things like __rust_maybe_catch_panic "__rust_", "___rust_", "rust_begin_unwind", + "_start", // these are well-known library frames "anyhow::", "log::", From 1f0be60f62c43e4f657e700244f7d4e69b76e766 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Thu, 27 Mar 2025 11:54:47 +0100 Subject: [PATCH 060/148] fix(anyhow): attach stacktrace only if error provides backtrace (#759) --- sentry-anyhow/src/lib.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sentry-anyhow/src/lib.rs b/sentry-anyhow/src/lib.rs index 4127a9567..d5cde23f8 100644 --- a/sentry-anyhow/src/lib.rs +++ b/sentry-anyhow/src/lib.rs @@ -72,7 +72,12 @@ pub fn event_from_error(err: &anyhow::Error) -> Event<'static> { // exception records are sorted in reverse if let Some(exc) = event.exception.iter_mut().last() { let backtrace = err.backtrace(); - exc.stacktrace = sentry_backtrace::parse_stacktrace(&format!("{backtrace:#}")); + if matches!( + backtrace.status(), + std::backtrace::BacktraceStatus::Captured + ) { + exc.stacktrace = sentry_backtrace::parse_stacktrace(&format!("{backtrace:#}")); + } } } From 6a0ffebe16aeebb92e330dcbcbce17966b22a270 Mon Sep 17 00:00:00 2001 From: Jack Lavigne Date: Fri, 28 Mar 2025 11:37:11 +0100 Subject: [PATCH 061/148] feat(core): introduce `release-health` feature (#749) * feat: introduce `release-health `feature * enable by default in subcrates --------- Co-authored-by: lcian --- sentry-actix/Cargo.toml | 4 + sentry-core/Cargo.toml | 3 +- sentry-core/src/api.rs | 4 + sentry-core/src/client.rs | 17 +- sentry-core/src/clientoptions.rs | 9 + sentry-core/src/hub.rs | 3 + sentry-core/src/scope/real.rs | 19 +- sentry-core/src/session.rs | 1151 +++++++++++++++--------------- sentry-tower/Cargo.toml | 2 + sentry-tracing/Cargo.toml | 3 +- sentry/Cargo.toml | 10 +- sentry/src/init.rs | 10 +- 12 files changed, 660 insertions(+), 575 deletions(-) diff --git a/sentry-actix/Cargo.toml b/sentry-actix/Cargo.toml index 081db9f70..273a10ca9 100644 --- a/sentry-actix/Cargo.toml +++ b/sentry-actix/Cargo.toml @@ -12,6 +12,10 @@ Sentry client extension for actix-web 3. edition = "2021" rust-version = "1.81" +[features] +default = ["release-health"] +release-health = ["sentry-core/release-health"] + [dependencies] actix-web = { version = "4", default-features = false } bytes = "1.2" diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index 7f0b43193..0c5dccb03 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -25,7 +25,8 @@ client = ["rand"] # I would love to just have a `log` feature, but this is used inside a macro, # and macros actually expand features (and extern crate) where they are used! debug-logs = ["dep:log"] -test = ["client"] +test = ["client", "release-health"] +release-health = [] [dependencies] cadence = { version = "1.4.0", optional = true } diff --git a/sentry-core/src/api.rs b/sentry-core/src/api.rs index 06164e4e3..ea0b8532f 100644 --- a/sentry-core/src/api.rs +++ b/sentry-core/src/api.rs @@ -1,3 +1,4 @@ +#[cfg(feature = "release-health")] use sentry_types::protocol::v7::SessionStatus; use crate::protocol::{Event, Level}; @@ -279,11 +280,13 @@ pub fn last_event_id() -> Option { /// /// sentry::end_session(); /// ``` +#[cfg(feature = "release-health")] pub fn start_session() { Hub::with_active(|hub| hub.start_session()) } /// End the current Release Health Session. +#[cfg(feature = "release-health")] pub fn end_session() { end_session_with_status(SessionStatus::Exited) } @@ -295,6 +298,7 @@ pub fn end_session() { /// /// When an `Abnormal` session should be captured, it has to be done explicitly /// using this function. +#[cfg(feature = "release-health")] pub fn end_session_with_status(status: SessionStatus) { Hub::with_active(|hub| hub.end_session_with_status(status)) } diff --git a/sentry-core/src/client.rs b/sentry-core/src/client.rs index f95154dea..684f7f2a8 100644 --- a/sentry-core/src/client.rs +++ b/sentry-core/src/client.rs @@ -6,14 +6,18 @@ use std::sync::{Arc, RwLock}; use std::time::Duration; use rand::random; +#[cfg(feature = "release-health")] use sentry_types::protocol::v7::SessionUpdate; use sentry_types::random_uuid; use crate::constants::SDK_INFO; use crate::protocol::{ClientSdkInfo, Event}; +#[cfg(feature = "release-health")] use crate::session::SessionFlusher; use crate::types::{Dsn, Uuid}; -use crate::{ClientOptions, Envelope, Hub, Integration, Scope, SessionMode, Transport}; +#[cfg(feature = "release-health")] +use crate::SessionMode; +use crate::{ClientOptions, Envelope, Hub, Integration, Scope, Transport}; impl> From for Client { fn from(o: T) -> Client { @@ -43,6 +47,7 @@ pub(crate) type TransportArc = Arc>>>; pub struct Client { options: ClientOptions, transport: TransportArc, + #[cfg(feature = "release-health")] session_flusher: RwLock>, integrations: Vec<(TypeId, Arc)>, pub(crate) sdk_info: ClientSdkInfo, @@ -60,13 +65,17 @@ impl fmt::Debug for Client { impl Clone for Client { fn clone(&self) -> Client { let transport = Arc::new(RwLock::new(self.transport.read().unwrap().clone())); + + #[cfg(feature = "release-health")] let session_flusher = RwLock::new(Some(SessionFlusher::new( transport.clone(), self.options.session_mode, ))); + Client { options: self.options.clone(), transport, + #[cfg(feature = "release-health")] session_flusher, integrations: self.integrations.clone(), sdk_info: self.sdk_info.clone(), @@ -131,6 +140,7 @@ impl Client { sdk_info.integrations.push(integration.name().to_string()); } + #[cfg(feature = "release-health")] let session_flusher = RwLock::new(Some(SessionFlusher::new( transport.clone(), options.session_mode, @@ -139,6 +149,7 @@ impl Client { Client { options, transport, + #[cfg(feature = "release-health")] session_flusher, integrations, sdk_info, @@ -266,6 +277,7 @@ impl Client { let mut envelope: Envelope = event.into(); // For request-mode sessions, we aggregate them all instead of // flushing them out early. + #[cfg(feature = "release-health")] if self.options.session_mode == SessionMode::Application { let session_item = scope.and_then(|scope| { scope @@ -300,6 +312,7 @@ impl Client { } } + #[cfg(feature = "release-health")] pub(crate) fn enqueue_session(&self, session_update: SessionUpdate<'static>) { if let Some(ref flusher) = *self.session_flusher.read().unwrap() { flusher.enqueue(session_update); @@ -308,6 +321,7 @@ impl Client { /// Drains all pending events without shutting down. pub fn flush(&self, timeout: Option) -> bool { + #[cfg(feature = "release-health")] if let Some(ref flusher) = *self.session_flusher.read().unwrap() { flusher.flush(); } @@ -326,6 +340,7 @@ impl Client { /// If no timeout is provided the client will wait for as long a /// `shutdown_timeout` in the client options. pub fn close(&self, timeout: Option) -> bool { + #[cfg(feature = "release-health")] drop(self.session_flusher.write().unwrap().take()); let transport_opt = self.transport.write().unwrap().take(); if let Some(transport) = transport_opt { diff --git a/sentry-core/src/clientoptions.rs b/sentry-core/src/clientoptions.rs index 583aae8cc..9c0f98d34 100644 --- a/sentry-core/src/clientoptions.rs +++ b/sentry-core/src/clientoptions.rs @@ -32,6 +32,9 @@ pub type BeforeCallback = Arc Option + Send + Sync>; /// /// See the [Documentation on Session Modes](https://develop.sentry.dev/sdk/sessions/#sdk-considerations) /// for more information. +/// +/// **NOTE**: The `release-health` feature (enabled by default) needs to be enabled for this option to have +/// any effect. #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum SessionMode { /// Long running application session. @@ -171,8 +174,14 @@ pub struct ClientOptions { /// When automatic session tracking is enabled, a new "user-mode" session /// is started at the time of `sentry::init`, and will persist for the /// application lifetime. + /// + /// **NOTE**: The `release-health` feature (enabled by default) needs to be enabled for this option to have + /// any effect. pub auto_session_tracking: bool, /// Determine how Sessions are being tracked. + /// + /// **NOTE**: The `release-health` feature (enabled by default) needs to be enabled for this option to have + /// any effect. pub session_mode: SessionMode, /// Border frames which indicate a border from a backtrace to /// useless internals. Some are automatically included. diff --git a/sentry-core/src/hub.rs b/sentry-core/src/hub.rs index f5ebf155c..6bab5263d 100644 --- a/sentry-core/src/hub.rs +++ b/sentry-core/src/hub.rs @@ -126,6 +126,7 @@ impl Hub { /// /// See the global [`start_session`](fn.start_session.html) /// for more documentation. + #[cfg(feature = "release-health")] pub fn start_session(&self) { with_client_impl! {{ self.inner.with_mut(|stack| { @@ -143,6 +144,7 @@ impl Hub { /// End the current Release Health Session. /// /// See the global [`sentry::end_session`](crate::end_session) for more documentation. + #[cfg(feature = "release-health")] pub fn end_session(&self) { self.end_session_with_status(SessionStatus::Exited) } @@ -151,6 +153,7 @@ impl Hub { /// /// See the global [`end_session_with_status`](crate::end_session_with_status) /// for more documentation. + #[cfg(feature = "release-health")] pub fn end_session_with_status(&self, status: SessionStatus) { with_client_impl! {{ self.inner.with_mut(|stack| { diff --git a/sentry-core/src/scope/real.rs b/sentry-core/src/scope/real.rs index ed033fb00..7c4eda471 100644 --- a/sentry-core/src/scope/real.rs +++ b/sentry-core/src/scope/real.rs @@ -1,10 +1,13 @@ use std::borrow::Cow; use std::collections::{HashMap, VecDeque}; use std::fmt; -use std::sync::{Arc, Mutex, PoisonError, RwLock}; +#[cfg(feature = "release-health")] +use std::sync::Mutex; +use std::sync::{Arc, PoisonError, RwLock}; use crate::performance::TransactionOrSpan; use crate::protocol::{Attachment, Breadcrumb, Context, Event, Level, Transaction, User, Value}; +#[cfg(feature = "release-health")] use crate::session::Session; use crate::Client; @@ -45,6 +48,7 @@ pub struct Scope { pub(crate) tags: Arc>, pub(crate) contexts: Arc>, pub(crate) event_processors: Arc>, + #[cfg(feature = "release-health")] pub(crate) session: Arc>>, pub(crate) span: Arc>, pub(crate) attachments: Arc>, @@ -52,7 +56,8 @@ pub struct Scope { impl fmt::Debug for Scope { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Scope") + let mut debug_struct = f.debug_struct("Scope"); + debug_struct .field("level", &self.level) .field("fingerprint", &self.fingerprint) .field("transaction", &self.transaction) @@ -61,8 +66,12 @@ impl fmt::Debug for Scope { .field("extra", &self.extra) .field("tags", &self.tags) .field("contexts", &self.contexts) - .field("event_processors", &self.event_processors.len()) - .field("session", &self.session) + .field("event_processors", &self.event_processors.len()); + + #[cfg(feature = "release-health")] + debug_struct.field("session", &self.session); + + debug_struct .field("span", &self.span) .field("attachments", &self.attachments.len()) .finish() @@ -341,7 +350,9 @@ impl Scope { self.span.as_ref().clone() } + #[allow(unused_variables)] pub(crate) fn update_session_from_event(&self, event: &Event<'static>) { + #[cfg(feature = "release-health")] if let Some(session) = self.session.lock().unwrap().as_mut() { session.update_from_event(event); } diff --git a/sentry-core/src/session.rs b/sentry-core/src/session.rs index 1b26af74e..00739872f 100644 --- a/sentry-core/src/session.rs +++ b/sentry-core/src/session.rs @@ -2,665 +2,684 @@ //! //! -use std::collections::HashMap; -use std::sync::{Arc, Condvar, Mutex, MutexGuard}; -use std::thread::JoinHandle; -use std::time::{Duration, Instant, SystemTime}; - -use crate::client::TransportArc; -use crate::clientoptions::SessionMode; -use crate::protocol::{ - EnvelopeItem, Event, Level, SessionAggregateItem, SessionAggregates, SessionAttributes, - SessionStatus, SessionUpdate, -}; -use crate::scope::StackLayer; -use crate::types::random_uuid; -use crate::{Client, Envelope}; - -#[derive(Clone, Debug)] -pub struct Session { - client: Arc, - session_update: SessionUpdate<'static>, - started: Instant, - dirty: bool, -} +#[cfg(feature = "release-health")] +pub use session_impl::*; + +#[cfg(feature = "release-health")] +mod session_impl { + + use std::collections::HashMap; + use std::sync::{Arc, Condvar, Mutex, MutexGuard}; + use std::thread::JoinHandle; + use std::time::{Duration, Instant, SystemTime}; + + use crate::client::TransportArc; + use crate::clientoptions::SessionMode; + use crate::protocol::{ + EnvelopeItem, Event, Level, SessionAggregateItem, SessionAggregates, SessionAttributes, + SessionStatus, SessionUpdate, + }; + + #[cfg(feature = "release-health")] + use crate::scope::StackLayer; + + #[cfg(feature = "release-health")] + use crate::types::random_uuid; + use crate::{Client, Envelope}; + + #[derive(Clone, Debug)] + pub struct Session { + client: Arc, + session_update: SessionUpdate<'static>, + started: Instant, + dirty: bool, + } -impl Drop for Session { - fn drop(&mut self) { - self.close(SessionStatus::Exited); - if self.dirty { - self.client.enqueue_session(self.session_update.clone()); + impl Drop for Session { + fn drop(&mut self) { + self.close(SessionStatus::Exited); + if self.dirty { + self.client.enqueue_session(self.session_update.clone()); + } } } -} -impl Session { - pub fn from_stack(stack: &StackLayer) -> Option { - let client = stack.client.as_ref()?; - let options = client.options(); - let user = stack.scope.user.as_deref(); - let distinct_id = user - .and_then(|user| { - user.id - .as_ref() - .or(user.email.as_ref()) - .or(user.username.as_ref()) - }) - .cloned(); - Some(Self { - client: client.clone(), - session_update: SessionUpdate { - session_id: random_uuid(), - distinct_id, - sequence: None, - timestamp: None, - started: SystemTime::now(), - init: true, - duration: None, - status: SessionStatus::Ok, - errors: 0, - attributes: SessionAttributes { - release: options.release.clone()?, - environment: options.environment.clone(), - ip_address: None, - user_agent: None, + impl Session { + #[cfg(feature = "release-health")] + pub fn from_stack(stack: &StackLayer) -> Option { + let client = stack.client.as_ref()?; + let options = client.options(); + let user = stack.scope.user.as_deref(); + let distinct_id = user + .and_then(|user| { + user.id + .as_ref() + .or(user.email.as_ref()) + .or(user.username.as_ref()) + }) + .cloned(); + Some(Self { + client: client.clone(), + session_update: SessionUpdate { + session_id: random_uuid(), + distinct_id, + sequence: None, + timestamp: None, + started: SystemTime::now(), + init: true, + duration: None, + status: SessionStatus::Ok, + errors: 0, + attributes: SessionAttributes { + release: options.release.clone()?, + environment: options.environment.clone(), + ip_address: None, + user_agent: None, + }, }, - }, - started: Instant::now(), - dirty: true, - }) - } - - pub(crate) fn update_from_event(&mut self, event: &Event<'static>) { - if self.session_update.status != SessionStatus::Ok { - // a session that has already transitioned to a "terminal" state - // should not receive any more updates - return; + started: Instant::now(), + dirty: true, + }) } - let mut has_error = event.level >= Level::Error; - let mut is_crash = false; - for exc in &event.exception.values { - has_error = true; - if let Some(mechanism) = &exc.mechanism { - if let Some(false) = mechanism.handled { - is_crash = true; - break; + + pub(crate) fn update_from_event(&mut self, event: &Event<'static>) { + if self.session_update.status != SessionStatus::Ok { + // a session that has already transitioned to a "terminal" state + // should not receive any more updates + return; + } + let mut has_error = event.level >= Level::Error; + let mut is_crash = false; + for exc in &event.exception.values { + has_error = true; + if let Some(mechanism) = &exc.mechanism { + if let Some(false) = mechanism.handled { + is_crash = true; + break; + } } } - } - if is_crash { - self.session_update.status = SessionStatus::Crashed; - } - if has_error { - self.session_update.errors += 1; - self.dirty = true; + if is_crash { + self.session_update.status = SessionStatus::Crashed; + } + if has_error { + self.session_update.errors += 1; + self.dirty = true; + } } - } - pub(crate) fn close(&mut self, status: SessionStatus) { - if self.session_update.status == SessionStatus::Ok { - let status = match status { - SessionStatus::Ok => SessionStatus::Exited, - s => s, - }; - self.session_update.duration = Some(self.started.elapsed().as_secs_f64()); - self.session_update.status = status; - self.dirty = true; + pub(crate) fn close(&mut self, status: SessionStatus) { + if self.session_update.status == SessionStatus::Ok { + let status = match status { + SessionStatus::Ok => SessionStatus::Exited, + s => s, + }; + self.session_update.duration = Some(self.started.elapsed().as_secs_f64()); + self.session_update.status = status; + self.dirty = true; + } } - } - pub(crate) fn create_envelope_item(&mut self) -> Option { - if self.dirty { - let item = self.session_update.clone().into(); - self.session_update.init = false; - self.dirty = false; - return Some(item); + #[cfg(feature = "release-health")] + pub(crate) fn create_envelope_item(&mut self) -> Option { + if self.dirty { + let item = self.session_update.clone().into(); + self.session_update.init = false; + self.dirty = false; + return Some(item); + } + None } - None } -} - -// as defined here: https://develop.sentry.dev/sdk/envelopes/#size-limits -const MAX_SESSION_ITEMS: usize = 100; -const FLUSH_INTERVAL: Duration = Duration::from_secs(60); -#[derive(Debug, Default)] -struct SessionQueue { - individual: Vec>, - aggregated: Option, -} + // as defined here: https://develop.sentry.dev/sdk/envelopes/#size-limits + const MAX_SESSION_ITEMS: usize = 100; + #[cfg(feature = "release-health")] + const FLUSH_INTERVAL: Duration = Duration::from_secs(60); -#[derive(Debug)] -struct AggregatedSessions { - buckets: HashMap, - attributes: SessionAttributes<'static>, -} + #[derive(Debug, Default)] + struct SessionQueue { + individual: Vec>, + aggregated: Option, + } -impl From for EnvelopeItem { - fn from(sessions: AggregatedSessions) -> Self { - let aggregates = sessions - .buckets - .into_iter() - .map(|(key, counts)| SessionAggregateItem { - started: key.started, - distinct_id: key.distinct_id, - exited: counts.exited, - errored: counts.errored, - abnormal: counts.abnormal, - crashed: counts.crashed, - }) - .collect(); + #[derive(Debug)] + struct AggregatedSessions { + buckets: HashMap, + attributes: SessionAttributes<'static>, + } - SessionAggregates { - aggregates, - attributes: sessions.attributes, + impl From for EnvelopeItem { + fn from(sessions: AggregatedSessions) -> Self { + let aggregates = sessions + .buckets + .into_iter() + .map(|(key, counts)| SessionAggregateItem { + started: key.started, + distinct_id: key.distinct_id, + exited: counts.exited, + errored: counts.errored, + abnormal: counts.abnormal, + crashed: counts.crashed, + }) + .collect(); + + SessionAggregates { + aggregates, + attributes: sessions.attributes, + } + .into() } - .into() } -} -#[derive(Debug, PartialEq, Eq, Hash)] -struct AggregationKey { - started: SystemTime, - distinct_id: Option, -} + #[derive(Debug, PartialEq, Eq, Hash)] + struct AggregationKey { + started: SystemTime, + distinct_id: Option, + } -#[derive(Debug, Default)] -struct AggregationCounts { - exited: u32, - errored: u32, - abnormal: u32, - crashed: u32, -} + #[derive(Debug, Default)] + struct AggregationCounts { + exited: u32, + errored: u32, + abnormal: u32, + crashed: u32, + } -/// Background Session Flusher -/// -/// The background flusher queues session updates for delayed batched sending. -/// It has its own background thread that will flush its queue once every -/// `FLUSH_INTERVAL`. -pub(crate) struct SessionFlusher { - transport: TransportArc, - mode: SessionMode, - queue: Arc>, - shutdown: Arc<(Mutex, Condvar)>, - worker: Option>, -} + /// Background Session Flusher + /// + /// The background flusher queues session updates for delayed batched sending. + /// It has its own background thread that will flush its queue once every + /// `FLUSH_INTERVAL`. + pub(crate) struct SessionFlusher { + transport: TransportArc, + mode: SessionMode, + queue: Arc>, + shutdown: Arc<(Mutex, Condvar)>, + worker: Option>, + } -impl SessionFlusher { - /// Creates a new Flusher that will submit envelopes to the given `transport`. - pub fn new(transport: TransportArc, mode: SessionMode) -> Self { - let queue = Arc::new(Mutex::new(Default::default())); - #[allow(clippy::mutex_atomic)] - let shutdown = Arc::new((Mutex::new(false), Condvar::new())); - - let worker_transport = transport.clone(); - let worker_queue = queue.clone(); - let worker_shutdown = shutdown.clone(); - let worker = std::thread::Builder::new() - .name("sentry-session-flusher".into()) - .spawn(move || { - let (lock, cvar) = worker_shutdown.as_ref(); - let mut shutdown = lock.lock().unwrap(); - // check this immediately, in case the main thread is already shutting down - if *shutdown { - return; - } - let mut last_flush = Instant::now(); - loop { - let timeout = FLUSH_INTERVAL - .checked_sub(last_flush.elapsed()) - .unwrap_or_else(|| Duration::from_secs(0)); - shutdown = cvar.wait_timeout(shutdown, timeout).unwrap().0; + impl SessionFlusher { + /// Creates a new Flusher that will submit envelopes to the given `transport`. + #[cfg(feature = "release-health")] + pub fn new(transport: TransportArc, mode: SessionMode) -> Self { + let queue = Arc::new(Mutex::new(Default::default())); + #[allow(clippy::mutex_atomic)] + let shutdown = Arc::new((Mutex::new(false), Condvar::new())); + + let worker_transport = transport.clone(); + let worker_queue = queue.clone(); + let worker_shutdown = shutdown.clone(); + let worker = std::thread::Builder::new() + .name("sentry-session-flusher".into()) + .spawn(move || { + let (lock, cvar) = worker_shutdown.as_ref(); + let mut shutdown = lock.lock().unwrap(); + // check this immediately, in case the main thread is already shutting down if *shutdown { return; } - if last_flush.elapsed() < FLUSH_INTERVAL { - continue; + let mut last_flush = Instant::now(); + loop { + let timeout = FLUSH_INTERVAL + .checked_sub(last_flush.elapsed()) + .unwrap_or_else(|| Duration::from_secs(0)); + shutdown = cvar.wait_timeout(shutdown, timeout).unwrap().0; + if *shutdown { + return; + } + if last_flush.elapsed() < FLUSH_INTERVAL { + continue; + } + SessionFlusher::flush_queue_internal( + worker_queue.lock().unwrap(), + &worker_transport, + ); + last_flush = Instant::now(); } - SessionFlusher::flush_queue_internal( - worker_queue.lock().unwrap(), - &worker_transport, - ); - last_flush = Instant::now(); - } - }) - .unwrap(); - - Self { - transport, - mode, - queue, - shutdown, - worker: Some(worker), - } - } - - /// Enqueues a session update for delayed sending. - /// - /// This will aggregate session counts in request mode, for all sessions - /// that were not yet partially sent. - pub fn enqueue(&self, session_update: SessionUpdate<'static>) { - let mut queue = self.queue.lock().unwrap(); - if self.mode == SessionMode::Application || !session_update.init { - queue.individual.push(session_update); - if queue.individual.len() >= MAX_SESSION_ITEMS { - SessionFlusher::flush_queue_internal(queue, &self.transport); + }) + .unwrap(); + + Self { + transport, + mode, + queue, + shutdown, + worker: Some(worker), } - return; } - let aggregate = queue.aggregated.get_or_insert_with(|| AggregatedSessions { - buckets: HashMap::with_capacity(1), - attributes: session_update.attributes.clone(), - }); - - let duration = session_update - .started - .duration_since(SystemTime::UNIX_EPOCH) - .unwrap(); - let duration = (duration.as_secs() / 60) * 60; - let started = SystemTime::UNIX_EPOCH - .checked_add(Duration::from_secs(duration)) - .unwrap(); - - let key = AggregationKey { - started, - distinct_id: session_update.distinct_id, - }; - - let bucket = aggregate.buckets.entry(key).or_default(); - - match session_update.status { - SessionStatus::Exited => { - if session_update.errors > 0 { - bucket.errored += 1; - } else { - bucket.exited += 1; + /// Enqueues a session update for delayed sending. + /// + /// This will aggregate session counts in request mode, for all sessions + /// that were not yet partially sent. + pub fn enqueue(&self, session_update: SessionUpdate<'static>) { + let mut queue = self.queue.lock().unwrap(); + if self.mode == SessionMode::Application || !session_update.init { + queue.individual.push(session_update); + if queue.individual.len() >= MAX_SESSION_ITEMS { + SessionFlusher::flush_queue_internal(queue, &self.transport); } + return; } - SessionStatus::Crashed => { - bucket.crashed += 1; - } - SessionStatus::Abnormal => { - bucket.abnormal += 1; - } - SessionStatus::Ok => { - sentry_debug!("unreachable: only closed sessions will be enqueued"); - } - } - } - /// Flushes the queue to the transport. - pub fn flush(&self) { - let queue = self.queue.lock().unwrap(); - SessionFlusher::flush_queue_internal(queue, &self.transport); - } + let aggregate = queue.aggregated.get_or_insert_with(|| AggregatedSessions { + buckets: HashMap::with_capacity(1), + attributes: session_update.attributes.clone(), + }); - /// Flushes the queue to the transport. - /// - /// This is a static method as it will be called from both the background - /// thread and the main thread on drop. - fn flush_queue_internal(mut queue_lock: MutexGuard, transport: &TransportArc) { - let queue = std::mem::take(&mut queue_lock.individual); - let aggregate = queue_lock.aggregated.take(); - drop(queue_lock); - - // send aggregates - if let Some(aggregate) = aggregate { - if let Some(ref transport) = *transport.read().unwrap() { - let mut envelope = Envelope::new(); - envelope.add_item(aggregate); - transport.send_envelope(envelope); + let duration = session_update + .started + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap(); + let duration = (duration.as_secs() / 60) * 60; + let started = SystemTime::UNIX_EPOCH + .checked_add(Duration::from_secs(duration)) + .unwrap(); + + let key = AggregationKey { + started, + distinct_id: session_update.distinct_id, + }; + + let bucket = aggregate.buckets.entry(key).or_default(); + + match session_update.status { + SessionStatus::Exited => { + if session_update.errors > 0 { + bucket.errored += 1; + } else { + bucket.exited += 1; + } + } + SessionStatus::Crashed => { + bucket.crashed += 1; + } + SessionStatus::Abnormal => { + bucket.abnormal += 1; + } + SessionStatus::Ok => { + sentry_debug!("unreachable: only closed sessions will be enqueued"); + } } } - // send individual items - if queue.is_empty() { - return; + /// Flushes the queue to the transport. + pub fn flush(&self) { + let queue = self.queue.lock().unwrap(); + SessionFlusher::flush_queue_internal(queue, &self.transport); } - let mut envelope = Envelope::new(); - let mut items = 0; - - for session_update in queue { - if items >= MAX_SESSION_ITEMS { + /// Flushes the queue to the transport. + /// + /// This is a static method as it will be called from both the background + /// thread and the main thread on drop. + fn flush_queue_internal( + mut queue_lock: MutexGuard, + transport: &TransportArc, + ) { + let queue = std::mem::take(&mut queue_lock.individual); + let aggregate = queue_lock.aggregated.take(); + drop(queue_lock); + + // send aggregates + if let Some(aggregate) = aggregate { if let Some(ref transport) = *transport.read().unwrap() { + let mut envelope = Envelope::new(); + envelope.add_item(aggregate); transport.send_envelope(envelope); } - envelope = Envelope::new(); - items = 0; } - envelope.add_item(session_update); - items += 1; - } + // send individual items + if queue.is_empty() { + return; + } - if let Some(ref transport) = *transport.read().unwrap() { - transport.send_envelope(envelope); - } - } -} + let mut envelope = Envelope::new(); + let mut items = 0; + + for session_update in queue { + if items >= MAX_SESSION_ITEMS { + if let Some(ref transport) = *transport.read().unwrap() { + transport.send_envelope(envelope); + } + envelope = Envelope::new(); + items = 0; + } -impl Drop for SessionFlusher { - fn drop(&mut self) { - let (lock, cvar) = self.shutdown.as_ref(); - *lock.lock().unwrap() = true; - cvar.notify_one(); + envelope.add_item(session_update); + items += 1; + } - if let Some(worker) = self.worker.take() { - worker.join().ok(); + if let Some(ref transport) = *transport.read().unwrap() { + transport.send_envelope(envelope); + } } - SessionFlusher::flush_queue_internal(self.queue.lock().unwrap(), &self.transport); } -} -#[cfg(all(test, feature = "test"))] -mod tests { - use std::cmp::Ordering; - - use super::*; - use crate as sentry; - use crate::protocol::{Envelope, EnvelopeItem, SessionStatus}; - - fn capture_envelopes(f: F) -> Vec - where - F: FnOnce(), - { - crate::test::with_captured_envelopes_options( - f, - crate::ClientOptions { - release: Some("some-release".into()), - ..Default::default() - }, - ) - } + impl Drop for SessionFlusher { + fn drop(&mut self) { + let (lock, cvar) = self.shutdown.as_ref(); + *lock.lock().unwrap() = true; + cvar.notify_one(); - #[test] - fn test_session_startstop() { - let envelopes = capture_envelopes(|| { - sentry::start_session(); - std::thread::sleep(std::time::Duration::from_millis(10)); - }); - assert_eq!(envelopes.len(), 1); - - let mut items = envelopes[0].items(); - if let Some(EnvelopeItem::SessionUpdate(session)) = items.next() { - assert_eq!(session.status, SessionStatus::Exited); - assert!(session.duration.unwrap() > 0.01); - assert_eq!(session.errors, 0); - assert_eq!(session.attributes.release, "some-release"); - assert!(session.init); - } else { - panic!("expected session"); + if let Some(worker) = self.worker.take() { + worker.join().ok(); + } + SessionFlusher::flush_queue_internal(self.queue.lock().unwrap(), &self.transport); } - assert_eq!(items.next(), None); } - #[test] - fn test_session_batching() { - let envelopes = capture_envelopes(|| { - for _ in 0..(MAX_SESSION_ITEMS * 2) { - sentry::start_session(); - } - }); - // we only want *two* envelope for all the sessions - assert_eq!(envelopes.len(), 2); - - let items = envelopes[0].items().chain(envelopes[1].items()); - assert_eq!(items.clone().count(), MAX_SESSION_ITEMS * 2); - for item in items { - assert!(matches!(item, EnvelopeItem::SessionUpdate(_))); + #[cfg(all(test, feature = "test"))] + mod tests { + use std::cmp::Ordering; + + use super::*; + use crate as sentry; + use crate::protocol::{Envelope, EnvelopeItem, SessionStatus}; + + fn capture_envelopes(f: F) -> Vec + where + F: FnOnce(), + { + crate::test::with_captured_envelopes_options( + f, + crate::ClientOptions { + release: Some("some-release".into()), + ..Default::default() + }, + ) } - } - #[test] - fn test_session_aggregation() { - let envelopes = crate::test::with_captured_envelopes_options( - || { + #[test] + fn test_session_startstop() { + let envelopes = capture_envelopes(|| { sentry::start_session(); - let err = "NaN".parse::().unwrap_err(); - sentry::capture_error(&err); + std::thread::sleep(std::time::Duration::from_millis(10)); + }); + assert_eq!(envelopes.len(), 1); + + let mut items = envelopes[0].items(); + if let Some(EnvelopeItem::SessionUpdate(session)) = items.next() { + assert_eq!(session.status, SessionStatus::Exited); + assert!(session.duration.unwrap() > 0.01); + assert_eq!(session.errors, 0); + assert_eq!(session.attributes.release, "some-release"); + assert!(session.init); + } else { + panic!("expected session"); + } + assert_eq!(items.next(), None); + } - for _ in 0..50 { + #[test] + fn test_session_batching() { + let envelopes = capture_envelopes(|| { + for _ in 0..(MAX_SESSION_ITEMS * 2) { sentry::start_session(); } - sentry::end_session(); - - sentry::configure_scope(|scope| { - scope.set_user(Some(sentry::User { - id: Some("foo-bar".into()), - ..Default::default() - })); - scope.add_event_processor(Box::new(|_| None)); - }); + }); + // we only want *two* envelope for all the sessions + assert_eq!(envelopes.len(), 2); - for _ in 0..50 { + let items = envelopes[0].items().chain(envelopes[1].items()); + assert_eq!(items.clone().count(), MAX_SESSION_ITEMS * 2); + for item in items { + assert!(matches!(item, EnvelopeItem::SessionUpdate(_))); + } + } + + #[test] + fn test_session_aggregation() { + let envelopes = crate::test::with_captured_envelopes_options( + || { sentry::start_session(); - } + let err = "NaN".parse::().unwrap_err(); + sentry::capture_error(&err); - // This error will be discarded because of the event processor, - // and session will not be updated. - // Only events dropped due to sampling should update the session. - let err = "NaN".parse::().unwrap_err(); - sentry::capture_error(&err); - }, - crate::ClientOptions { - release: Some("some-release".into()), - session_mode: SessionMode::Request, - ..Default::default() - }, - ); - assert_eq!(envelopes.len(), 2); - - let mut items = envelopes[0].items(); - assert!(matches!(items.next(), Some(EnvelopeItem::Event(_)))); - assert_eq!(items.next(), None); - - let mut items = envelopes[1].items(); - if let Some(EnvelopeItem::SessionAggregates(aggregate)) = items.next() { - let mut aggregates = aggregate.aggregates.clone(); - assert_eq!(aggregates.len(), 2); - // the order depends on a hashmap and is not stable otherwise - aggregates.sort_by(|a, b| { - a.distinct_id - .partial_cmp(&b.distinct_id) - .unwrap_or(Ordering::Less) - }); + for _ in 0..50 { + sentry::start_session(); + } + sentry::end_session(); - assert_eq!(aggregates[0].distinct_id, None); - assert_eq!(aggregates[0].exited, 50); + sentry::configure_scope(|scope| { + scope.set_user(Some(sentry::User { + id: Some("foo-bar".into()), + ..Default::default() + })); + scope.add_event_processor(Box::new(|_| None)); + }); - assert_eq!(aggregates[1].errored, 0); - assert_eq!(aggregates[1].distinct_id, Some("foo-bar".into())); - assert_eq!(aggregates[1].exited, 50); - } else { - panic!("expected session"); - } - assert_eq!(items.next(), None); - } + for _ in 0..50 { + sentry::start_session(); + } - #[test] - fn test_session_error() { - let envelopes = capture_envelopes(|| { - sentry::start_session(); - - let err = "NaN".parse::().unwrap_err(); - sentry::capture_error(&err); - }); - assert_eq!(envelopes.len(), 2); - - let mut items = envelopes[0].items(); - assert!(matches!(items.next(), Some(EnvelopeItem::Event(_)))); - if let Some(EnvelopeItem::SessionUpdate(session)) = items.next() { - assert_eq!(session.status, SessionStatus::Ok); - assert_eq!(session.errors, 1); - assert_eq!(session.attributes.release, "some-release"); - assert!(session.init); - } else { - panic!("expected session"); - } - assert_eq!(items.next(), None); - - let mut items = envelopes[1].items(); - if let Some(EnvelopeItem::SessionUpdate(session)) = items.next() { - assert_eq!(session.status, SessionStatus::Exited); - assert_eq!(session.errors, 1); - assert!(!session.init); - } else { - panic!("expected session"); - } - assert_eq!(items.next(), None); - } + // This error will be discarded because of the event processor, + // and session will not be updated. + // Only events dropped due to sampling should update the session. + let err = "NaN".parse::().unwrap_err(); + sentry::capture_error(&err); + }, + crate::ClientOptions { + release: Some("some-release".into()), + #[cfg(feature = "release-health")] + session_mode: SessionMode::Request, + ..Default::default() + }, + ); + assert_eq!(envelopes.len(), 2); + + let mut items = envelopes[0].items(); + assert!(matches!(items.next(), Some(EnvelopeItem::Event(_)))); + assert_eq!(items.next(), None); + + let mut items = envelopes[1].items(); + if let Some(EnvelopeItem::SessionAggregates(aggregate)) = items.next() { + let mut aggregates = aggregate.aggregates.clone(); + assert_eq!(aggregates.len(), 2); + // the order depends on a hashmap and is not stable otherwise + aggregates.sort_by(|a, b| { + a.distinct_id + .partial_cmp(&b.distinct_id) + .unwrap_or(Ordering::Less) + }); + + assert_eq!(aggregates[0].distinct_id, None); + assert_eq!(aggregates[0].exited, 50); - #[test] - fn test_session_abnormal() { - let envelopes = capture_envelopes(|| { - sentry::start_session(); - sentry::end_session_with_status(SessionStatus::Abnormal); - }); - assert_eq!(envelopes.len(), 1); - - let mut items = envelopes[0].items(); - if let Some(EnvelopeItem::SessionUpdate(session)) = items.next() { - assert_eq!(session.status, SessionStatus::Abnormal); - assert!(session.init); - } else { - panic!("expected session"); + assert_eq!(aggregates[1].errored, 0); + assert_eq!(aggregates[1].distinct_id, Some("foo-bar".into())); + assert_eq!(aggregates[1].exited, 50); + } else { + panic!("expected session"); + } + assert_eq!(items.next(), None); } - assert_eq!(items.next(), None); - } - #[test] - fn test_session_sampled_errors() { - let mut envelopes = crate::test::with_captured_envelopes_options( - || { + #[test] + fn test_session_error() { + let envelopes = capture_envelopes(|| { sentry::start_session(); - for _ in 0..100 { - let err = "NaN".parse::().unwrap_err(); - sentry::capture_error(&err); - } - }, - crate::ClientOptions { - release: Some("some-release".into()), - sample_rate: 0.5, - ..Default::default() - }, - ); - assert!(envelopes.len() > 25); - assert!(envelopes.len() < 75); - - let envelope = envelopes.pop().unwrap(); - let mut items = envelope.items(); - if let Some(EnvelopeItem::SessionUpdate(session)) = items.next() { - assert_eq!(session.status, SessionStatus::Exited); - assert_eq!(session.errors, 100); - } else { - panic!("expected session"); + let err = "NaN".parse::().unwrap_err(); + sentry::capture_error(&err); + }); + assert_eq!(envelopes.len(), 2); + + let mut items = envelopes[0].items(); + assert!(matches!(items.next(), Some(EnvelopeItem::Event(_)))); + if let Some(EnvelopeItem::SessionUpdate(session)) = items.next() { + assert_eq!(session.status, SessionStatus::Ok); + assert_eq!(session.errors, 1); + assert_eq!(session.attributes.release, "some-release"); + assert!(session.init); + } else { + panic!("expected session"); + } + assert_eq!(items.next(), None); + + let mut items = envelopes[1].items(); + if let Some(EnvelopeItem::SessionUpdate(session)) = items.next() { + assert_eq!(session.status, SessionStatus::Exited); + assert_eq!(session.errors, 1); + assert!(!session.init); + } else { + panic!("expected session"); + } + assert_eq!(items.next(), None); + } + + #[test] + fn test_session_abnormal() { + let envelopes = capture_envelopes(|| { + sentry::start_session(); + sentry::end_session_with_status(SessionStatus::Abnormal); + }); + assert_eq!(envelopes.len(), 1); + + let mut items = envelopes[0].items(); + if let Some(EnvelopeItem::SessionUpdate(session)) = items.next() { + assert_eq!(session.status, SessionStatus::Abnormal); + assert!(session.init); + } else { + panic!("expected session"); + } + assert_eq!(items.next(), None); } - assert_eq!(items.next(), None); - } - /// For _user-mode_ sessions, we want to inherit the session for any _new_ - /// Hub that is spawned from the main thread Hub which already has a session - /// attached - #[test] - fn test_inherit_session_from_top() { - let envelopes = capture_envelopes(|| { - sentry::start_session(); + #[test] + fn test_session_sampled_errors() { + let mut envelopes = crate::test::with_captured_envelopes_options( + || { + sentry::start_session(); - let err = "NaN".parse::().unwrap_err(); - sentry::capture_error(&err); + for _ in 0..100 { + let err = "NaN".parse::().unwrap_err(); + sentry::capture_error(&err); + } + }, + crate::ClientOptions { + release: Some("some-release".into()), + sample_rate: 0.5, + ..Default::default() + }, + ); + assert!(envelopes.len() > 25); + assert!(envelopes.len() < 75); + + let envelope = envelopes.pop().unwrap(); + let mut items = envelope.items(); + if let Some(EnvelopeItem::SessionUpdate(session)) = items.next() { + assert_eq!(session.status, SessionStatus::Exited); + assert_eq!(session.errors, 100); + } else { + panic!("expected session"); + } + assert_eq!(items.next(), None); + } - // create a new Hub which should have the same session - let hub = std::sync::Arc::new(sentry::Hub::new_from_top(sentry::Hub::current())); + /// For _user-mode_ sessions, we want to inherit the session for any _new_ + /// Hub that is spawned from the main thread Hub which already has a session + /// attached + #[test] + fn test_inherit_session_from_top() { + let envelopes = capture_envelopes(|| { + sentry::start_session(); - sentry::Hub::run(hub, || { let err = "NaN".parse::().unwrap_err(); sentry::capture_error(&err); - sentry::with_scope( - |_| {}, - || { - let err = "NaN".parse::().unwrap_err(); - sentry::capture_error(&err); - }, - ); + // create a new Hub which should have the same session + let hub = std::sync::Arc::new(sentry::Hub::new_from_top(sentry::Hub::current())); + + sentry::Hub::run(hub, || { + let err = "NaN".parse::().unwrap_err(); + sentry::capture_error(&err); + + sentry::with_scope( + |_| {}, + || { + let err = "NaN".parse::().unwrap_err(); + sentry::capture_error(&err); + }, + ); + }); }); - }); - assert_eq!(envelopes.len(), 4); // 3 errors and one session end + assert_eq!(envelopes.len(), 4); // 3 errors and one session end - let mut items = envelopes[3].items(); - if let Some(EnvelopeItem::SessionUpdate(session)) = items.next() { - assert_eq!(session.status, SessionStatus::Exited); - assert_eq!(session.errors, 3); - assert!(!session.init); - } else { - panic!("expected session"); + let mut items = envelopes[3].items(); + if let Some(EnvelopeItem::SessionUpdate(session)) = items.next() { + assert_eq!(session.status, SessionStatus::Exited); + assert_eq!(session.errors, 3); + assert!(!session.init); + } else { + panic!("expected session"); + } + assert_eq!(items.next(), None); } - assert_eq!(items.next(), None); - } - /// We want to forward-inherit sessions as the previous test asserted, but - /// not *backwards*. So any new session created in a derived Hub and scope - /// will only get updates from that particular scope. - #[test] - fn test_dont_inherit_session_backwards() { - let envelopes = capture_envelopes(|| { - let hub = std::sync::Arc::new(sentry::Hub::new_from_top(sentry::Hub::current())); - - sentry::Hub::run(hub, || { - sentry::with_scope( - |_| {}, - || { - sentry::start_session(); + /// We want to forward-inherit sessions as the previous test asserted, but + /// not *backwards*. So any new session created in a derived Hub and scope + /// will only get updates from that particular scope. + #[test] + fn test_dont_inherit_session_backwards() { + let envelopes = capture_envelopes(|| { + let hub = std::sync::Arc::new(sentry::Hub::new_from_top(sentry::Hub::current())); + + sentry::Hub::run(hub, || { + sentry::with_scope( + |_| {}, + || { + sentry::start_session(); + + let err = "NaN".parse::().unwrap_err(); + sentry::capture_error(&err); + }, + ); - let err = "NaN".parse::().unwrap_err(); - sentry::capture_error(&err); - }, - ); + let err = "NaN".parse::().unwrap_err(); + sentry::capture_error(&err); + }); let err = "NaN".parse::().unwrap_err(); sentry::capture_error(&err); }); - let err = "NaN".parse::().unwrap_err(); - sentry::capture_error(&err); - }); - - assert_eq!(envelopes.len(), 4); // 3 errors and one session end + assert_eq!(envelopes.len(), 4); // 3 errors and one session end - let mut items = envelopes[0].items(); - assert!(matches!(items.next(), Some(EnvelopeItem::Event(_)))); - if let Some(EnvelopeItem::SessionUpdate(session)) = items.next() { - assert_eq!(session.status, SessionStatus::Ok); - assert_eq!(session.errors, 1); - assert!(session.init); - } else { - panic!("expected session"); - } - assert_eq!(items.next(), None); - - // the other two events should not have session updates - let mut items = envelopes[1].items(); - assert!(matches!(items.next(), Some(EnvelopeItem::Event(_)))); - assert_eq!(items.next(), None); - - let mut items = envelopes[2].items(); - assert!(matches!(items.next(), Some(EnvelopeItem::Event(_)))); - assert_eq!(items.next(), None); - - // the session end is sent last as it is possibly batched - let mut items = envelopes[3].items(); - if let Some(EnvelopeItem::SessionUpdate(session)) = items.next() { - assert_eq!(session.status, SessionStatus::Exited); - assert_eq!(session.errors, 1); - assert!(!session.init); - } else { - panic!("expected session"); + let mut items = envelopes[0].items(); + assert!(matches!(items.next(), Some(EnvelopeItem::Event(_)))); + if let Some(EnvelopeItem::SessionUpdate(session)) = items.next() { + assert_eq!(session.status, SessionStatus::Ok); + assert_eq!(session.errors, 1); + assert!(session.init); + } else { + panic!("expected session"); + } + assert_eq!(items.next(), None); + + // the other two events should not have session updates + let mut items = envelopes[1].items(); + assert!(matches!(items.next(), Some(EnvelopeItem::Event(_)))); + assert_eq!(items.next(), None); + + let mut items = envelopes[2].items(); + assert!(matches!(items.next(), Some(EnvelopeItem::Event(_)))); + assert_eq!(items.next(), None); + + // the session end is sent last as it is possibly batched + let mut items = envelopes[3].items(); + if let Some(EnvelopeItem::SessionUpdate(session)) = items.next() { + assert_eq!(session.status, SessionStatus::Exited); + assert_eq!(session.errors, 1); + assert!(!session.init); + } else { + panic!("expected session"); + } + assert_eq!(items.next(), None); } - assert_eq!(items.next(), None); } } diff --git a/sentry-tower/Cargo.toml b/sentry-tower/Cargo.toml index bed8363f6..9be031dc1 100644 --- a/sentry-tower/Cargo.toml +++ b/sentry-tower/Cargo.toml @@ -16,8 +16,10 @@ rust-version = "1.81" all-features = true [features] +default = ["release-health"] http = ["dep:http", "pin-project", "url"] axum-matched-path = ["http", "axum/matched-path"] +release-health = ["sentry-core/release-health"] [dependencies] axum = { version = "0.8", optional = true, default-features = false } diff --git a/sentry-tracing/Cargo.toml b/sentry-tracing/Cargo.toml index ead02d13a..317fca173 100644 --- a/sentry-tracing/Cargo.toml +++ b/sentry-tracing/Cargo.toml @@ -16,8 +16,9 @@ rust-version = "1.81" all-features = true [features] -default = [] +default = ["release-health"] backtrace = ["dep:sentry-backtrace"] +release-health = ["sentry-core/release-health"] [dependencies] sentry-core = { version = "0.36.0", path = "../sentry-core", features = [ diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index afba9ffa5..2ebf7660b 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -21,7 +21,14 @@ all-features = true rustdoc-args = ["--cfg", "doc_cfg"] [features] -default = ["backtrace", "contexts", "debug-images", "panic", "transport"] +default = [ + "backtrace", + "contexts", + "debug-images", + "panic", + "transport", + "release-health", +] # default integrations backtrace = ["sentry-backtrace", "sentry-tracing?/backtrace"] @@ -39,6 +46,7 @@ tracing = ["sentry-tracing"] # other features test = ["sentry-core/test"] debug-logs = ["dep:log", "sentry-core/debug-logs"] +release-health = ["sentry-core/release-health"] # transports transport = ["reqwest", "native-tls"] reqwest = ["dep:reqwest", "httpdate", "tokio"] diff --git a/sentry/src/init.rs b/sentry/src/init.rs index befb66fd6..27fdbce29 100644 --- a/sentry/src/init.rs +++ b/sentry/src/init.rs @@ -1,6 +1,8 @@ use std::sync::Arc; -use sentry_core::{sentry_debug, SessionMode}; +use sentry_core::sentry_debug; +#[cfg(feature = "release-health")] +use sentry_core::SessionMode; use crate::defaults::apply_defaults; use crate::{Client, ClientOptions, Hub}; @@ -34,6 +36,7 @@ impl Drop for ClientInitGuard { sentry_debug!("dropping client guard (no client to dispose)"); } // end any session that might be open before closing the client + #[cfg(feature = "release-health")] crate::end_session(); self.0.close(None); } @@ -93,8 +96,12 @@ where C: Into, { let opts = apply_defaults(opts.into()); + + #[allow(unused)] let auto_session_tracking = opts.auto_session_tracking; + #[allow(unused)] let session_mode = opts.session_mode; + let client = Arc::new(Client::from(opts)); Hub::with(|hub| hub.bind_client(Some(client.clone()))); @@ -103,6 +110,7 @@ where } else { sentry_debug!("initialized disabled sentry client due to disabled or invalid DSN"); } + #[cfg(feature = "release-health")] if auto_session_tracking && session_mode == SessionMode::Application { crate::start_session() } From 6a8b96d4a124897ecde8f90a3b01373fdb9c463d Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Tue, 1 Apr 2025 12:43:04 +0200 Subject: [PATCH 062/148] chore: prepare changelog for release (#761) * chore: prepare changelog for release * Update CHANGELOG.md --- CHANGELOG.md | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fdaf63cc5..3219df4b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,62 @@ # Changelog +## Unreleased + +### Breaking changes + +- chore(msrv): `cargo update` and bump MSRV to 1.81 (#754) by @lcian + - The minimum supported Rust version has been raised to 1.81. +- feat(core): introduce `release-health` feature (#749) by @pepperoni505 + - A new `release-health` feature flag was introduced that gates the [Release Health](https://docs.sentry.io/product/releases/health/) features of Sentry. + - This allows for compilation of the SDK on certain WASM targets. + - Release Health features were already present and enabled with no feature flag in previous versions. + - The new feature flag will be enabled by default when using `sentry`, `sentry-actix`, `sentry-tower` or `sentry-tracing` with the default features. + - If you're fine-tuning your feature flags, make sure to enable `release-health` to get back the previous behavior. +- ref(metrics): remove features and code related to the old metrics beta (#740) by @lcian + - The metrics feature and the code related to it has been removed from the crate, as the Sentry backend stopped ingesting metrics a while ago. +- Switch to MIT license (#724) by @cleptric + - The license for the crates has been changed to MIT. + +### Features + +- feat(actix): capture HTTP request body (#731) by @pacifistes + - The middleware for `actix-web` now supports capturing and attaching the request body to HTTP request transactions. + - You need to enable `send_default_pii` in your client options for this to be enabled, and you can fine-tune the behavior using the new option `max_request_body_size`. +- feat(core): `transaction.set_data` sets data on `TraceContext` (#739) by @lcian + - `transaction.set_data` now sets data on `TraceContext`, as the SDK should not use the `extra` field. +- ref(backtrace): add entries and extra logic for in-app detection (#756) by @lcian +- feat(core): add more frames to be considered not in_app (#760) by @lcian + - The logic used by the SDK to detect `in-app` stack frames has been improved. Now the SDK will mark more frames as not `in-app`. + - A similar improvement has been added to the Sentry [backend](https://github.com/getsentry/sentry/commit/cef4d53e05093d6e9c81c1c49585af86cc135f8b) so that old versions of the SDK can benefit from improved `in-app` reporting. + +### Fixes + +- fix(http): Finish transaction on drop (#727) by @Dav1dde + - Fixed a bug where the current transaction was not finished (hence not sent to Sentry) when its corresponding future was dropped, e.g. due to a panic. +- follow https://github.com/getsentry/sentry-rust/pull/439 for actix-web. fix https://github.com/getsentry/sentry-rust/issues/680 (#737) by @pavel-rosputko + - The HTTP request metadata is now being correctly attached to transactions when using `sentry-actix`. +- fix(tracing): wrap error with synthetic mechanism only if attaching stacktrace (#755) by @lcian + - Fixed a bug that should result in improved grouping and issue titles for events reported by `sentry-tracing` when not capturing stack traces. +- fix(actix): process request in other middleware using correct Hub (#758) by @lcian + - The subsequent middleware in the chain when processing a request now execute within the correct Hub. +- fix(anyhow): attach stacktrace only if error provides backtrace (#759) by @lcian + - Fixed a bug where the SDK was providing incorrect stack traces when capturing an `anyhow` when the `backtrace` feature is enabled but `RUST_BACKTRACE` is not set. + - This should result in correct grouping of the affected issues. + +### Various fixes & improvements + +- Fix CS (#726) by @cleptric +- fix(doctests): update prost (#750) by @lcian +- chore(msrv): bump MSRV to 1.75 (#751) by @lcian +- refactor(actix): simplify body_from_http (#757) by @robjtede +- chore: prepare changelog for release (#761) by @lcian + +### Dependencies + +- build(deps): bump openssl from 0.10.66 to 0.10.70 (#732) by @dependabot +- build(deps): bump ring from 0.17.8 to 0.17.13 (#747) by @dependabot + + ## 0.36.0 ### Various fixes & improvements From 7e6d8cbd5e3179bc10a42f37d6d1bf266e0113a0 Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Tue, 1 Apr 2025 10:53:55 +0000 Subject: [PATCH 063/148] release: 0.37.0 --- CHANGELOG.md | 3 +-- sentry-actix/Cargo.toml | 4 ++-- sentry-actix/README.md | 9 ++++++--- sentry-anyhow/Cargo.toml | 6 +++--- sentry-backtrace/Cargo.toml | 4 ++-- sentry-contexts/Cargo.toml | 4 ++-- sentry-core/Cargo.toml | 4 ++-- sentry-core/README.md | 2 +- sentry-debug-images/Cargo.toml | 4 ++-- sentry-debug-images/README.md | 2 +- sentry-log/Cargo.toml | 4 ++-- sentry-panic/Cargo.toml | 6 +++--- sentry-slog/Cargo.toml | 4 ++-- sentry-tower/Cargo.toml | 4 ++-- sentry-tower/README.md | 2 +- sentry-tracing/Cargo.toml | 6 +++--- sentry-tracing/README.md | 2 +- sentry-types/Cargo.toml | 2 +- sentry/Cargo.toml | 22 +++++++++++----------- sentry/README.md | 12 ++++++------ 20 files changed, 54 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3219df4b3..02daa3530 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 0.37.0 ### Breaking changes @@ -56,7 +56,6 @@ - build(deps): bump openssl from 0.10.66 to 0.10.70 (#732) by @dependabot - build(deps): bump ring from 0.17.8 to 0.17.13 (#747) by @dependabot - ## 0.36.0 ### Various fixes & improvements diff --git a/sentry-actix/Cargo.toml b/sentry-actix/Cargo.toml index 273a10ca9..be9c19d99 100644 --- a/sentry-actix/Cargo.toml +++ b/sentry-actix/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-actix" -version = "0.36.0" +version = "0.37.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -20,7 +20,7 @@ release-health = ["sentry-core/release-health"] actix-web = { version = "4", default-features = false } bytes = "1.2" futures-util = { version = "0.3.5", default-features = false } -sentry-core = { version = "0.36.0", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.37.0", path = "../sentry-core", default-features = false, features = [ "client", ] } actix-http = "3.10" diff --git a/sentry-actix/README.md b/sentry-actix/README.md index a4bbd2982..04263046e 100644 --- a/sentry-actix/README.md +++ b/sentry-actix/README.md @@ -11,8 +11,7 @@ report them to `Sentry`. To use this middleware just configure Sentry and then add it to your actix web app as a middleware. Because actix is generally working with non sendable objects and highly concurrent -this middleware creates a new hub per request. As a result many of the sentry integrations -such as breadcrumbs do not work unless you bind the actix hub. +this middleware creates a new Hub per request. ## Example @@ -67,12 +66,16 @@ let _sentry = sentry::init(sentry::ClientOptions { ## Reusing the Hub This integration will automatically create a new per-request Hub from the main Hub, and update the -current Hub instance. For example, the following will capture a message in the current request's Hub: +current Hub instance. For example, the following in the handler or in any of the subsequent +middleware will capture a message in the current request's Hub: ```rust sentry::capture_message("Something is not well", sentry::Level::Warning); ``` +It is recommended to register the Sentry middleware as the last, i.e. the first to be executed +when processing a request, so that the rest of the processing will run with the correct Hub. + ## Resources License: MIT diff --git a/sentry-anyhow/Cargo.toml b/sentry-anyhow/Cargo.toml index 1b64f5dd9..17376cab8 100644 --- a/sentry-anyhow/Cargo.toml +++ b/sentry-anyhow/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-anyhow" -version = "0.36.0" +version = "0.37.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -17,8 +17,8 @@ default = ["backtrace"] backtrace = ["anyhow/backtrace"] [dependencies] -sentry-backtrace = { version = "0.36.0", path = "../sentry-backtrace" } -sentry-core = { version = "0.36.0", path = "../sentry-core" } +sentry-backtrace = { version = "0.37.0", path = "../sentry-backtrace" } +sentry-core = { version = "0.37.0", path = "../sentry-core" } anyhow = "1.0.39" [dev-dependencies] diff --git a/sentry-backtrace/Cargo.toml b/sentry-backtrace/Cargo.toml index ffafc2e5d..a3f58eb9e 100644 --- a/sentry-backtrace/Cargo.toml +++ b/sentry-backtrace/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-backtrace" -version = "0.36.0" +version = "0.37.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -19,4 +19,4 @@ regex = { version = "1.5.5", default-features = false, features = [ "std", "unicode-perl", ] } -sentry-core = { version = "0.36.0", path = "../sentry-core" } +sentry-core = { version = "0.37.0", path = "../sentry-core" } diff --git a/sentry-contexts/Cargo.toml b/sentry-contexts/Cargo.toml index 4e5366e3c..03c2096a9 100644 --- a/sentry-contexts/Cargo.toml +++ b/sentry-contexts/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-contexts" -version = "0.36.0" +version = "0.37.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -14,7 +14,7 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.36.0", path = "../sentry-core" } +sentry-core = { version = "0.37.0", path = "../sentry-core" } libc = "0.2.66" hostname = "0.4" diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index 0c5dccb03..c276a5270 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-core" -version = "0.36.0" +version = "0.37.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -35,7 +35,7 @@ log = { version = "0.4.8", optional = true, features = ["std"] } once_cell = "1" rand = { version = "0.8.1", optional = true } regex = { version = "1.7.3", optional = true } -sentry-types = { version = "0.36.0", path = "../sentry-types" } +sentry-types = { version = "0.37.0", path = "../sentry-types" } serde = { version = "1.0.104", features = ["derive"] } serde_json = { version = "1.0.46" } uuid = { version = "1.0.0", features = ["v4", "serde"], optional = true } diff --git a/sentry-core/README.md b/sentry-core/README.md index 19d992b70..645a051cc 100644 --- a/sentry-core/README.md +++ b/sentry-core/README.md @@ -102,7 +102,7 @@ functionality. [Sentry]: https://sentry.io/ [`sentry`]: https://crates.io/crates/sentry [Unified API]: https://develop.sentry.dev/sdk/unified-api/ -[`test`]: https://docs.rs/sentry-core/0.36.0/sentry_core/test/index.html +[`test`]: https://docs.rs/sentry-core/0.37.0/sentry_core/test/index.html ## Resources diff --git a/sentry-debug-images/Cargo.toml b/sentry-debug-images/Cargo.toml index e1bcc6ba3..7f4df4c28 100644 --- a/sentry-debug-images/Cargo.toml +++ b/sentry-debug-images/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-debug-images" -version = "0.36.0" +version = "0.37.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -15,4 +15,4 @@ rust-version = "1.81" [dependencies] findshlibs = "=0.10.2" once_cell = "1" -sentry-core = { version = "0.36.0", path = "../sentry-core" } +sentry-core = { version = "0.37.0", path = "../sentry-core" } diff --git a/sentry-debug-images/README.md b/sentry-debug-images/README.md index b280e304d..0629301be 100644 --- a/sentry-debug-images/README.md +++ b/sentry-debug-images/README.md @@ -22,7 +22,7 @@ let integration = sentry_debug_images::DebugImagesIntegration::new() .filter(|event| event.level >= Level::Warning); ``` -[`Event`]: https://docs.rs/sentry-debug-images/0.36.0/sentry_debug_images/sentry_core::protocol::Event +[`Event`]: https://docs.rs/sentry-debug-images/0.37.0/sentry_debug_images/sentry_core::protocol::Event ## Resources diff --git a/sentry-log/Cargo.toml b/sentry-log/Cargo.toml index 4b9ab49be..2b31c45a7 100644 --- a/sentry-log/Cargo.toml +++ b/sentry-log/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-log" -version = "0.36.0" +version = "0.37.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.36.0", path = "../sentry-core" } +sentry-core = { version = "0.37.0", path = "../sentry-core" } log = { version = "0.4.8", features = ["std"] } [dev-dependencies] diff --git a/sentry-panic/Cargo.toml b/sentry-panic/Cargo.toml index c709f41ca..0ad95881e 100644 --- a/sentry-panic/Cargo.toml +++ b/sentry-panic/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-panic" -version = "0.36.0" +version = "0.37.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -13,8 +13,8 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.36.0", path = "../sentry-core" } -sentry-backtrace = { version = "0.36.0", path = "../sentry-backtrace" } +sentry-core = { version = "0.37.0", path = "../sentry-core" } +sentry-backtrace = { version = "0.37.0", path = "../sentry-backtrace" } [dev-dependencies] sentry = { path = "../sentry", default-features = false, features = ["test"] } diff --git a/sentry-slog/Cargo.toml b/sentry-slog/Cargo.toml index cdf6aa999..4028bc748 100644 --- a/sentry-slog/Cargo.toml +++ b/sentry-slog/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-slog" -version = "0.36.0" +version = "0.37.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.36.0", path = "../sentry-core" } +sentry-core = { version = "0.37.0", path = "../sentry-core" } slog = { version = "2.5.2", features = ["nested-values"] } serde_json = "1.0.46" diff --git a/sentry-tower/Cargo.toml b/sentry-tower/Cargo.toml index 9be031dc1..a5c8a4f97 100644 --- a/sentry-tower/Cargo.toml +++ b/sentry-tower/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tower" -version = "0.36.0" +version = "0.37.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -27,7 +27,7 @@ tower-layer = "0.3" tower-service = "0.3" http = { version = "1.0.0", optional = true } pin-project = { version = "1.0.10", optional = true } -sentry-core = { version = "0.36.0", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.37.0", path = "../sentry-core", default-features = false, features = [ "client", ] } url = { version = "2.2.2", optional = true } diff --git a/sentry-tower/README.md b/sentry-tower/README.md index fd25c050d..6aaba0bd9 100644 --- a/sentry-tower/README.md +++ b/sentry-tower/README.md @@ -103,7 +103,7 @@ feature of the `sentry` crate instead of the `tower` feature. The created transaction will automatically use the request URI as its name. This is sometimes not desirable in case the request URI contains unique IDs or similar. In this case, users should manually override the transaction name -in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.36.0/sentry_tower/sentry_core::Scope::set_transaction) +in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.37.0/sentry_tower/sentry_core::Scope::set_transaction) method. When combining both layers, take care of the ordering of both. For example diff --git a/sentry-tracing/Cargo.toml b/sentry-tracing/Cargo.toml index 317fca173..47eb141cc 100644 --- a/sentry-tracing/Cargo.toml +++ b/sentry-tracing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tracing" -version = "0.36.0" +version = "0.37.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -21,14 +21,14 @@ backtrace = ["dep:sentry-backtrace"] release-health = ["sentry-core/release-health"] [dependencies] -sentry-core = { version = "0.36.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.37.0", path = "../sentry-core", features = [ "client", ] } tracing-core = "0.1" tracing-subscriber = { version = "0.3.1", default-features = false, features = [ "std", ] } -sentry-backtrace = { version = "0.36.0", path = "../sentry-backtrace", optional = true } +sentry-backtrace = { version = "0.37.0", path = "../sentry-backtrace", optional = true } [dev-dependencies] log = "0.4" diff --git a/sentry-tracing/README.md b/sentry-tracing/README.md index 00ad63c7b..7ed9411d5 100644 --- a/sentry-tracing/README.md +++ b/sentry-tracing/README.md @@ -83,7 +83,7 @@ tracing::error!( ); ``` -To track [error structs](https://docs.rs/sentry-tracing/0.36.0/sentry_tracing/std::error::Error), assign a reference to error trait object as field +To track [error structs](https://docs.rs/sentry-tracing/0.37.0/sentry_tracing/std::error::Error), assign a reference to error trait object as field in one of the logging macros. By convention, it is recommended to use the `ERROR` level and assign it to a field called `error`, although the integration will also work with all other levels and field names. diff --git a/sentry-types/Cargo.toml b/sentry-types/Cargo.toml index 205b41178..ac5593153 100644 --- a/sentry-types/Cargo.toml +++ b/sentry-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-types" -version = "0.36.0" +version = "0.37.0" authors = ["Sentry "] license = "MIT" readme = "README.md" diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index 2ebf7660b..15e44de92 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry" -version = "0.36.0" +version = "0.37.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -60,18 +60,18 @@ rustls = ["dep:rustls", "reqwest?/rustls-tls", "ureq?/tls", "webpki-roots"] embedded-svc-http = ["dep:embedded-svc", "dep:esp-idf-svc"] [dependencies] -sentry-core = { version = "0.36.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.37.0", path = "../sentry-core", features = [ "client", ] } -sentry-anyhow = { version = "0.36.0", path = "../sentry-anyhow", optional = true } -sentry-backtrace = { version = "0.36.0", path = "../sentry-backtrace", optional = true } -sentry-contexts = { version = "0.36.0", path = "../sentry-contexts", optional = true } -sentry-debug-images = { version = "0.36.0", path = "../sentry-debug-images", optional = true } -sentry-log = { version = "0.36.0", path = "../sentry-log", optional = true } -sentry-panic = { version = "0.36.0", path = "../sentry-panic", optional = true } -sentry-slog = { version = "0.36.0", path = "../sentry-slog", optional = true } -sentry-tower = { version = "0.36.0", path = "../sentry-tower", optional = true } -sentry-tracing = { version = "0.36.0", path = "../sentry-tracing", optional = true } +sentry-anyhow = { version = "0.37.0", path = "../sentry-anyhow", optional = true } +sentry-backtrace = { version = "0.37.0", path = "../sentry-backtrace", optional = true } +sentry-contexts = { version = "0.37.0", path = "../sentry-contexts", optional = true } +sentry-debug-images = { version = "0.37.0", path = "../sentry-debug-images", optional = true } +sentry-log = { version = "0.37.0", path = "../sentry-log", optional = true } +sentry-panic = { version = "0.37.0", path = "../sentry-panic", optional = true } +sentry-slog = { version = "0.37.0", path = "../sentry-slog", optional = true } +sentry-tower = { version = "0.37.0", path = "../sentry-tower", optional = true } +sentry-tracing = { version = "0.37.0", path = "../sentry-tracing", optional = true } log = { version = "0.4.8", optional = true, features = ["std"] } reqwest = { version = "0.12", optional = true, features = [ "blocking", diff --git a/sentry/README.md b/sentry/README.md index 54a275e4d..1e90b154e 100644 --- a/sentry/README.md +++ b/sentry/README.md @@ -34,8 +34,8 @@ sentry::capture_message("Hello World!", sentry::Level::Info); More complex examples on how to use sentry can also be found in [examples]. Extended instructions may also be found on [Sentry itself]. -[`sentry::init`]: https://docs.rs/sentry/0.36.0/sentry/fn.init.html -[`Hub`]: https://docs.rs/sentry/0.36.0/sentry/struct.Hub.html +[`sentry::init`]: https://docs.rs/sentry/0.37.0/sentry/fn.init.html +[`Hub`]: https://docs.rs/sentry/0.37.0/sentry/struct.Hub.html [examples]: https://github.com/getsentry/sentry-rust/tree/master/sentry/examples [Sentry itself]: https://docs.sentry.io/platforms/rust @@ -47,8 +47,8 @@ the ecosystem require a feature flag. For available integrations and how to use [integrations] and [apply_defaults]. [Features]: #features -[integrations]: https://docs.rs/sentry/0.36.0/sentry/integrations/index.html -[apply_defaults]: https://docs.rs/sentry/0.36.0/sentry/fn.apply_defaults.html +[integrations]: https://docs.rs/sentry/0.37.0/sentry/integrations/index.html +[apply_defaults]: https://docs.rs/sentry/0.37.0/sentry/fn.apply_defaults.html ## Minimal API @@ -56,8 +56,8 @@ This crate comes fully-featured. If the goal is to instrument libraries for usag with sentry, or to extend sentry with a custom [`Integration`] or a [`Transport`], one should use the [`sentry-core`] crate instead. -[`Integration`]: https://docs.rs/sentry/0.36.0/sentry/trait.Integration.html -[`Transport`]: https://docs.rs/sentry/0.36.0/sentry/trait.Transport.html +[`Integration`]: https://docs.rs/sentry/0.37.0/sentry/trait.Integration.html +[`Transport`]: https://docs.rs/sentry/0.37.0/sentry/trait.Transport.html [`sentry-core`]: https://crates.io/crates/sentry-core ## Features From be86143b8bcaad98ae0c6a3d84e548f627749681 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Apr 2025 10:46:26 +0200 Subject: [PATCH 064/148] build(deps): bump openssl from 0.10.71 to 0.10.72 (#762) Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.71 to 0.10.72. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.71...openssl-v0.10.72) --- updated-dependencies: - dependency-name: openssl dependency-version: 0.10.72 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e62fa91bc..c294d2015 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3125,9 +3125,9 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.71" +version = "0.10.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" +checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da" dependencies = [ "bitflags 2.9.0", "cfg-if", @@ -3157,9 +3157,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" -version = "0.9.106" +version = "0.9.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" +checksum = "8288979acd84749c744a9014b4382d42b8f7b2592847b5afb2ed29e5d16ede07" dependencies = [ "cc", "libc", @@ -3987,7 +3987,7 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "sentry" -version = "0.36.0" +version = "0.37.0" dependencies = [ "actix-web", "anyhow", @@ -4025,7 +4025,7 @@ dependencies = [ [[package]] name = "sentry-actix" -version = "0.36.0" +version = "0.37.0" dependencies = [ "actix-http", "actix-web", @@ -4039,7 +4039,7 @@ dependencies = [ [[package]] name = "sentry-anyhow" -version = "0.36.0" +version = "0.37.0" dependencies = [ "anyhow", "sentry", @@ -4049,7 +4049,7 @@ dependencies = [ [[package]] name = "sentry-backtrace" -version = "0.36.0" +version = "0.37.0" dependencies = [ "backtrace", "once_cell", @@ -4059,7 +4059,7 @@ dependencies = [ [[package]] name = "sentry-contexts" -version = "0.36.0" +version = "0.37.0" dependencies = [ "hostname", "libc", @@ -4072,7 +4072,7 @@ dependencies = [ [[package]] name = "sentry-core" -version = "0.36.0" +version = "0.37.0" dependencies = [ "anyhow", "cadence", @@ -4095,7 +4095,7 @@ dependencies = [ [[package]] name = "sentry-debug-images" -version = "0.36.0" +version = "0.37.0" dependencies = [ "findshlibs", "once_cell", @@ -4104,7 +4104,7 @@ dependencies = [ [[package]] name = "sentry-log" -version = "0.36.0" +version = "0.37.0" dependencies = [ "log", "pretty_env_logger", @@ -4114,7 +4114,7 @@ dependencies = [ [[package]] name = "sentry-panic" -version = "0.36.0" +version = "0.37.0" dependencies = [ "sentry", "sentry-backtrace", @@ -4123,7 +4123,7 @@ dependencies = [ [[package]] name = "sentry-slog" -version = "0.36.0" +version = "0.37.0" dependencies = [ "erased-serde", "sentry", @@ -4135,7 +4135,7 @@ dependencies = [ [[package]] name = "sentry-tower" -version = "0.36.0" +version = "0.37.0" dependencies = [ "anyhow", "axum 0.8.1", @@ -4155,7 +4155,7 @@ dependencies = [ [[package]] name = "sentry-tracing" -version = "0.36.0" +version = "0.37.0" dependencies = [ "log", "sentry", @@ -4170,7 +4170,7 @@ dependencies = [ [[package]] name = "sentry-types" -version = "0.36.0" +version = "0.37.0" dependencies = [ "debugid", "hex", From 64c65ea99d0c1bc48b05a2dee6eaa5a149a84619 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Apr 2025 11:10:08 +0200 Subject: [PATCH 065/148] build(deps): bump tokio from 1.44.1 to 1.44.2 (#763) Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.44.1 to 1.44.2. - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.44.1...tokio-1.44.2) --- updated-dependencies: - dependency-name: tokio dependency-version: 1.44.2 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- sentry-actix/Cargo.toml | 2 +- sentry-core/Cargo.toml | 2 +- sentry-tracing/Cargo.toml | 2 +- sentry/Cargo.toml | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c294d2015..18af740b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4728,9 +4728,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.44.1" +version = "1.44.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" +checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48" dependencies = [ "backtrace", "bytes 1.10.1", diff --git a/sentry-actix/Cargo.toml b/sentry-actix/Cargo.toml index be9c19d99..30658b7bf 100644 --- a/sentry-actix/Cargo.toml +++ b/sentry-actix/Cargo.toml @@ -29,4 +29,4 @@ actix-http = "3.10" actix-web = { version = "4" } futures = "0.3" sentry = { path = "../sentry", features = ["test"] } -tokio = { version = "1.0", features = ["full"] } +tokio = { version = "1.44", features = ["full"] } diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index c276a5270..891e77147 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -53,4 +53,4 @@ criterion = "0.5" futures = "0.3.24" rayon = "1.5.3" thiserror = "1.0.15" -tokio = { version = "1.0", features = ["rt", "rt-multi-thread", "macros"] } +tokio = { version = "1.44", features = ["rt", "rt-multi-thread", "macros"] } diff --git a/sentry-tracing/Cargo.toml b/sentry-tracing/Cargo.toml index 47eb141cc..190f6a4d0 100644 --- a/sentry-tracing/Cargo.toml +++ b/sentry-tracing/Cargo.toml @@ -36,4 +36,4 @@ sentry = { path = "../sentry", default-features = false, features = ["test"] } serde_json = "1" tracing = "0.1" tracing-subscriber = { version = "0.3.1", features = ["fmt", "registry"] } -tokio = { version = "1.8", features = ["rt-multi-thread", "macros", "time"] } +tokio = { version = "1.44", features = ["rt-multi-thread", "macros", "time"] } diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index 15e44de92..934c93ba1 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -83,7 +83,7 @@ surf = { version = "2.0.0", optional = true, default-features = false } http-client = { version = "6.5.3", optional = true } isahc = { version = "0.9.14", optional = true } serde_json = { version = "1.0.48", optional = true } -tokio = { version = "1.0", features = ["rt"], optional = true } +tokio = { version = "1.44", features = ["rt"], optional = true } ureq = { version = "2.10.1", optional = true, default-features = false } native-tls = { version = "0.2.8", optional = true } rustls = { version = "0.23.18", optional = true, default-features = false } @@ -103,7 +103,7 @@ anyhow = { version = "1.0.30" } log = { version = "0.4.8", features = ["std"] } pretty_env_logger = "0.5.0" slog = { version = "2.5.2" } -tokio = { version = "1.0", features = ["macros"] } +tokio = { version = "1.44", features = ["macros"] } tower = { version = "0.4", features = ["util"] } tracing = { version = "0.1" } tracing-subscriber = { version = "0.3", features = ["fmt", "tracing-log"] } From 24886715243eb7a656f83ef92ff6d5dfed586710 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Thu, 10 Apr 2025 17:58:41 +0200 Subject: [PATCH 066/148] refactor: remove Surf transport (#766) * refactor: remove Surf transport * improve --- sentry/Cargo.toml | 5 -- sentry/README.md | 2 - sentry/src/lib.rs | 2 - sentry/src/transports/mod.rs | 24 +------- sentry/src/transports/surf.rs | 102 ---------------------------------- 5 files changed, 2 insertions(+), 133 deletions(-) delete mode 100644 sentry/src/transports/surf.rs diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index 934c93ba1..54a982a48 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -51,8 +51,6 @@ release-health = ["sentry-core/release-health"] transport = ["reqwest", "native-tls"] reqwest = ["dep:reqwest", "httpdate", "tokio"] curl = ["dep:curl", "httpdate"] -surf-h1 = ["surf/h1-client", "httpdate"] -surf = ["surf/curl-client", "http-client", "httpdate", "isahc", "tokio"] ureq = ["dep:ureq", "httpdate"] # transport settings native-tls = ["dep:native-tls", "reqwest?/default-tls", "ureq?/native-tls"] @@ -79,9 +77,6 @@ reqwest = { version = "0.12", optional = true, features = [ ], default-features = false } curl = { version = "0.4.25", optional = true } httpdate = { version = "1.0.0", optional = true } -surf = { version = "2.0.0", optional = true, default-features = false } -http-client = { version = "6.5.3", optional = true } -isahc = { version = "0.9.14", optional = true } serde_json = { version = "1.0.48", optional = true } tokio = { version = "1.44", features = ["rt"], optional = true } ureq = { version = "2.10.1", optional = true, default-features = false } diff --git a/sentry/README.md b/sentry/README.md index 1e90b154e..9da99f0b5 100644 --- a/sentry/README.md +++ b/sentry/README.md @@ -81,7 +81,6 @@ extra setup to function properly. | `native-tls` | ✅ | | | `reqwest` must be enabled. | | `rustls` | | | | `reqwest` must be enabled. `native-tls` must be disabled via `default-features = false`. | | `curl` | | | | | -| `surf` | | | | | | `tower` | | 🔌 | | Requires extra setup; See [`sentry-tower`]'s documentation. | | `ureq` | | | | `ureq` transport support using `rustls` by default | | `ureq-native-tls` | | | | | @@ -113,7 +112,6 @@ extra setup to function properly. feature, and `default-features = false` must be set to completely disable building `native-tls` dependencies. - `curl`: Enables the `curl` transport. -- `surf`: Enables the `surf` transport. - `ureq`: Enables the `ureq` transport using `rustls`. - `ureq-native-tls`: Enables the `ureq` transport using `native-tls`. diff --git a/sentry/src/lib.rs b/sentry/src/lib.rs index 6652e1800..be98796ff 100644 --- a/sentry/src/lib.rs +++ b/sentry/src/lib.rs @@ -73,7 +73,6 @@ //! | `native-tls` | ✅ | | | `reqwest` must be enabled. | //! | `rustls` | | | | `reqwest` must be enabled. `native-tls` must be disabled via `default-features = false`. | //! | `curl` | | | | | -//! | `surf` | | | | | //! | `tower` | | 🔌 | | Requires extra setup; See [`sentry-tower`]'s documentation. | //! | `ureq` | | | | `ureq` transport support using `rustls` by default | //! | `ureq-native-tls` | | | | | @@ -105,7 +104,6 @@ //! feature, and `default-features = false` must be set to completely disable building `native-tls` //! dependencies. //! - `curl`: Enables the `curl` transport. -//! - `surf`: Enables the `surf` transport. //! - `ureq`: Enables the `ureq` transport using `rustls`. //! - `ureq-native-tls`: Enables the `ureq` transport using `native-tls`. //! diff --git a/sentry/src/transports/mod.rs b/sentry/src/transports/mod.rs index 46a849880..424c8a7a9 100644 --- a/sentry/src/transports/mod.rs +++ b/sentry/src/transports/mod.rs @@ -1,7 +1,7 @@ //! The provided transports. //! //! This module exposes all transports that are compiled into the sentry -//! library. The `reqwest`, `curl`, `surf` and `ureq` features turn on these transports. +//! library. The `reqwest`, `curl`, and `ureq` features turn on these transports. use crate::{ClientOptions, Transport, TransportFactory}; use std::sync::Arc; @@ -10,7 +10,7 @@ use std::sync::Arc; mod ratelimit; #[cfg(any(feature = "curl", feature = "ureq"))] mod thread; -#[cfg(any(feature = "reqwest", feature = "surf",))] +#[cfg(feature = "reqwest")] mod tokio_thread; #[cfg(feature = "reqwest")] @@ -28,11 +28,6 @@ mod curl; #[cfg(feature = "curl")] pub use self::curl::CurlHttpTransport; -#[cfg(feature = "surf")] -mod surf; -#[cfg(feature = "surf")] -pub use self::surf::SurfHttpTransport; - #[cfg(feature = "ureq")] mod ureq; #[cfg(feature = "ureq")] @@ -45,26 +40,15 @@ type DefaultTransport = ReqwestHttpTransport; feature = "curl", not(all(target_os = "espidf", feature = "embedded-svc-http")), not(feature = "reqwest"), - not(feature = "surf"), not(feature = "ureq") ))] type DefaultTransport = CurlHttpTransport; -#[cfg(all( - feature = "surf", - not(all(target_os = "espidf", feature = "embedded-svc-http")), - not(feature = "reqwest"), - not(feature = "curl"), - not(feature = "ureq") -))] -type DefaultTransport = SurfHttpTransport; - #[cfg(all( feature = "ureq", not(all(target_os = "espidf", feature = "embedded-svc-http")), not(feature = "reqwest"), not(feature = "curl"), - not(feature = "surf") ))] type DefaultTransport = UreqHttpTransport; @@ -73,7 +57,6 @@ type DefaultTransport = UreqHttpTransport; feature = "embedded-svc-http", not(feature = "reqwest"), not(feature = "curl"), - not(feature = "surf"), not(feature = "ureq") ))] type DefaultTransport = EmbeddedSVCHttpTransport; @@ -83,7 +66,6 @@ type DefaultTransport = EmbeddedSVCHttpTransport; all(target_os = "espidf", feature = "embedded-svc-http"), feature = "reqwest", feature = "curl", - feature = "surf", feature = "ureq" ))] pub type HttpTransport = DefaultTransport; @@ -102,7 +84,6 @@ impl TransportFactory for DefaultTransportFactory { all(target_os = "espidf", feature = "embedded-svc-http"), feature = "reqwest", feature = "curl", - feature = "surf", feature = "ureq" ))] { @@ -112,7 +93,6 @@ impl TransportFactory for DefaultTransportFactory { all(target_os = "espidf", feature = "embedded-svc-http"), feature = "reqwest", feature = "curl", - feature = "surf", feature = "ureq" )))] { diff --git a/sentry/src/transports/surf.rs b/sentry/src/transports/surf.rs deleted file mode 100644 index 0a902a688..000000000 --- a/sentry/src/transports/surf.rs +++ /dev/null @@ -1,102 +0,0 @@ -use std::time::Duration; - -use isahc::{ - config::{Configurable, SslOption}, - HttpClient, -}; -use surf::{http::headers as SurfHeaders, Client as SurfClient, StatusCode}; - -use super::tokio_thread::TransportThread; - -use crate::{sentry_debug, ClientOptions, Envelope, Transport}; - -/// A [`Transport`] that sends events via the [`surf`] library. -/// -/// This is enabled by the `surf` feature flag. -/// -/// [`surf`]: https://crates.io/crates/surf -#[cfg_attr(doc_cfg, doc(cfg(feature = "surf")))] -pub struct SurfHttpTransport { - thread: TransportThread, -} - -impl SurfHttpTransport { - /// Creates a new Transport. - pub fn new(options: &ClientOptions) -> Self { - Self::new_internal(options, None) - } - - /// Creates a new Transport that uses the specified [`SurfClient`]. - pub fn with_client(options: &ClientOptions, client: SurfClient) -> Self { - Self::new_internal(options, Some(client)) - } - - fn new_internal(options: &ClientOptions, client: Option) -> Self { - let mut client = client.unwrap_or_default(); - if options.accept_invalid_certs { - let hc = HttpClient::builder() - .ssl_options(SslOption::DANGER_ACCEPT_INVALID_CERTS) - .build() - .unwrap(); - let http_client = http_client::isahc::IsahcClient::from_client(hc); - client = SurfClient::with_http_client(http_client) - } - - let dsn = options.dsn.as_ref().unwrap(); - let user_agent = options.user_agent.clone(); - let auth = dsn.to_auth(Some(&user_agent)).to_string(); - let url = dsn.envelope_api_url().to_string(); - - let thread = TransportThread::new(move |envelope, mut rl| { - let mut body = Vec::new(); - envelope.to_writer(&mut body).unwrap(); - let request = client.post(&url).header("X-Sentry-Auth", &auth).body(body); - - async move { - match request.await { - Ok(mut response) => { - if let Some(sentry_header) = - response.header("x-sentry-rate-limits").map(|x| x.as_str()) - { - rl.update_from_retry_after(sentry_header); - } else if let Some(retry_after) = response - .header(SurfHeaders::RETRY_AFTER) - .map(|x| x.as_str()) - { - rl.update_from_retry_after(retry_after); - } else if response.status() == StatusCode::TooManyRequests { - rl.update_from_429(); - } - - match response.body_string().await { - Err(err) => { - sentry_debug!("Failed to read sentry response: {}", err); - } - Ok(text) => { - sentry_debug!("Get response: `{}`", text); - } - } - } - Err(err) => { - sentry_debug!("Failed to send envelope: {}", err); - } - } - rl - } - }); - Self { thread } - } -} - -impl Transport for SurfHttpTransport { - fn send_envelope(&self, envelope: Envelope) { - self.thread.send(envelope) - } - fn flush(&self, timeout: Duration) -> bool { - self.thread.flush(timeout) - } - - fn shutdown(&self, timeout: Duration) -> bool { - self.flush(timeout) - } -} From 6401cfc9dc2917bc61882c571ee8970c07939b9b Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Thu, 10 Apr 2025 18:06:34 +0200 Subject: [PATCH 067/148] refactor(tracing): remove `EventFilter::exception` and always attach exception (#768) * feat(tracing): attach errors to warning events and breadcrumbs * improve --- sentry-tracing/src/converters.rs | 39 ++++++++++++++------------------ sentry-tracing/src/layer.rs | 9 ++------ 2 files changed, 19 insertions(+), 29 deletions(-) diff --git a/sentry-tracing/src/converters.rs b/sentry-tracing/src/converters.rs index 836e8933d..5822e96b3 100644 --- a/sentry-tracing/src/converters.rs +++ b/sentry-tracing/src/converters.rs @@ -150,12 +150,27 @@ where S: Subscriber + for<'a> LookupSpan<'a>, { let (message, visitor) = extract_event_data_with_context(event, ctx.into()); + + let FieldVisitor { + exceptions, + mut json_values, + } = visitor; + + let errors = exceptions + .iter() + .rev() + .filter_map(|x| x.value.as_ref().map(|v| format!("{}: {}", x.ty, *v))) + .collect::>(); + if !errors.is_empty() { + json_values.insert("errors".to_owned(), errors.into()); + } + Breadcrumb { category: Some(event.metadata().target().to_owned()), ty: "log".into(), level: convert_tracing_level(event.metadata().level()), message, - data: visitor.json_values, + data: json_values, ..Default::default() } } @@ -217,31 +232,11 @@ fn contexts_from_event( context } -/// Creates an [`Event`] from a given [`tracing_core::Event`] +/// Creates an [`Event`] (possibly carrying an exception) from a given [`tracing_core::Event`] pub fn event_from_event<'context, S>( event: &tracing_core::Event, ctx: impl Into>>, ) -> Event<'static> -where - S: Subscriber + for<'a> LookupSpan<'a>, -{ - let (message, mut visitor) = extract_event_data_with_context(event, ctx.into()); - - Event { - logger: Some(event.metadata().target().to_owned()), - level: convert_tracing_level(event.metadata().level()), - message, - tags: tags_from_event(&mut visitor.json_values), - contexts: contexts_from_event(event, visitor.json_values), - ..Default::default() - } -} - -/// Creates an exception [`Event`] from a given [`tracing_core::Event`] -pub fn exception_from_event<'context, S>( - event: &tracing_core::Event, - ctx: impl Into>>, -) -> Event<'static> where S: Subscriber + for<'a> LookupSpan<'a>, { diff --git a/sentry-tracing/src/layer.rs b/sentry-tracing/src/layer.rs index a2f94d176..0ae51dfab 100644 --- a/sentry-tracing/src/layer.rs +++ b/sentry-tracing/src/layer.rs @@ -20,10 +20,8 @@ pub enum EventFilter { Ignore, /// Create a [`Breadcrumb`] from this [`Event`] Breadcrumb, - /// Create a message [`sentry_core::protocol::Event`] from this [`Event`] + /// Create a [`sentry_core::protocol::Event`] from this [`Event`] Event, - /// Create an exception [`sentry_core::protocol::Event`] from this [`Event`] - Exception, } /// The type of data Sentry should ingest for a [`Event`] @@ -44,7 +42,7 @@ pub enum EventMapping { /// `warning` and `info`, and `debug` and `trace` logs are ignored. pub fn default_event_filter(metadata: &Metadata) -> EventFilter { match metadata.level() { - &Level::ERROR => EventFilter::Exception, + &Level::ERROR => EventFilter::Event, &Level::WARN | &Level::INFO => EventFilter::Breadcrumb, &Level::DEBUG | &Level::TRACE => EventFilter::Ignore, } @@ -217,9 +215,6 @@ where EventMapping::Breadcrumb(breadcrumb_from_event(event, span_ctx)) } EventFilter::Event => EventMapping::Event(event_from_event(event, span_ctx)), - EventFilter::Exception => { - EventMapping::Event(exception_from_event(event, span_ctx)) - } } } }; From 2f9d2471c1d3f715b65c0c1bc8386f60269ce490 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Thu, 17 Apr 2025 09:36:19 +0200 Subject: [PATCH 068/148] chore(deps): bump some dependencies and update `Cargo.lock` (#772) --- Cargo.lock | 1662 ++++++--------------------------------- sentry-core/Cargo.toml | 4 +- sentry-tower/Cargo.toml | 4 +- sentry-types/Cargo.toml | 6 +- sentry/Cargo.toml | 6 +- 5 files changed, 268 insertions(+), 1414 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 18af740b9..58e0fae16 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9,7 +9,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" dependencies = [ "bitflags 2.9.0", - "bytes 1.10.1", + "bytes", "futures-core", "futures-sink", "memchr", @@ -29,10 +29,10 @@ dependencies = [ "actix-rt", "actix-service", "actix-utils", - "base64 0.22.1", + "base64", "bitflags 2.9.0", "brotli", - "bytes 1.10.1", + "bytes", "bytestring", "derive_more", "encoding_rs", @@ -50,7 +50,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "rand 0.9.0", - "sha1 0.10.6", + "sha1", "smallvec", "tokio", "tokio-util", @@ -105,7 +105,7 @@ dependencies = [ "futures-core", "futures-util", "mio", - "socket2 0.5.8", + "socket2", "tokio", "tracing", ] @@ -145,10 +145,10 @@ dependencies = [ "actix-service", "actix-utils", "actix-web-codegen", - "bytes 1.10.1", + "bytes", "bytestring", "cfg-if", - "cookie 0.16.2", + "cookie", "derive_more", "encoding_rs", "foldhash", @@ -167,8 +167,8 @@ dependencies = [ "serde_json", "serde_urlencoded", "smallvec", - "socket2 0.5.8", - "time 0.3.40", + "socket2", + "time", "tracing", "url", ] @@ -200,60 +200,6 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" -[[package]] -name = "aead" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fc95d1bdb8e6666b2b217308eeeb09f2d6728d104be3e31916cc74d15420331" -dependencies = [ - "generic-array", -] - -[[package]] -name = "aes" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "884391ef1066acaa41e766ba8f596341b96e93ce34f9a43e7d24bf0a0eaf0561" -dependencies = [ - "aes-soft", - "aesni", - "cipher", -] - -[[package]] -name = "aes-gcm" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5278b5fabbb9bd46e24aa69b2fdea62c99088e0a950a9be40e3e0101298f88da" -dependencies = [ - "aead", - "aes", - "cipher", - "ctr", - "ghash", - "subtle", -] - -[[package]] -name = "aes-soft" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be14c7498ea50828a38d0e24a765ed2effe92a705885b57d029cd67d45744072" -dependencies = [ - "cipher", - "opaque-debug", -] - -[[package]] -name = "aesni" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2e11f5e94c2f7d386164cc2aa1f97823fed6f259e486940a71c174dd01b0ce" -dependencies = [ - "cipher", - "opaque-debug", -] - [[package]] name = "aho-corasick" version = "1.1.3" @@ -316,19 +262,13 @@ checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anyhow" -version = "1.0.97" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" dependencies = [ "backtrace", ] -[[package]] -name = "arrayvec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" - [[package]] name = "as-slice" version = "0.2.1" @@ -338,181 +278,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "async-channel" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" -dependencies = [ - "concurrent-queue", - "event-listener 2.5.3", - "futures-core", -] - -[[package]] -name = "async-channel" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" -dependencies = [ - "concurrent-queue", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-dup" -version = "1.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c2886ab563af5038f79ec016dd7b87947ed138b794e8dd64992962c9cca0411" -dependencies = [ - "async-lock 3.4.0", - "futures-io", -] - -[[package]] -name = "async-executor" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" -dependencies = [ - "async-task", - "concurrent-queue", - "fastrand 2.3.0", - "futures-lite 2.6.0", - "slab", -] - -[[package]] -name = "async-global-executor" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" -dependencies = [ - "async-channel 2.3.1", - "async-executor", - "async-io 2.4.0", - "async-lock 3.4.0", - "blocking", - "futures-lite 2.6.0", - "once_cell", -] - -[[package]] -name = "async-h1" -version = "2.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d1d1dae8cb2c4258a79d6ed088b7fb9b4763bf4e9b22d040779761e046a2971" -dependencies = [ - "async-channel 1.9.0", - "async-dup", - "async-global-executor", - "async-io 1.13.0", - "futures-lite 1.13.0", - "http-types", - "httparse", - "log", - "pin-project", -] - -[[package]] -name = "async-io" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" -dependencies = [ - "async-lock 2.8.0", - "autocfg", - "cfg-if", - "concurrent-queue", - "futures-lite 1.13.0", - "log", - "parking", - "polling 2.8.0", - "rustix 0.37.28", - "slab", - "socket2 0.4.10", - "waker-fn", -] - -[[package]] -name = "async-io" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059" -dependencies = [ - "async-lock 3.4.0", - "cfg-if", - "concurrent-queue", - "futures-io", - "futures-lite 2.6.0", - "parking", - "polling 3.7.4", - "rustix 0.38.44", - "slab", - "tracing", - "windows-sys 0.59.0", -] - -[[package]] -name = "async-lock" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" -dependencies = [ - "event-listener 2.5.3", -] - -[[package]] -name = "async-lock" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" -dependencies = [ - "event-listener 5.4.0", - "event-listener-strategy", - "pin-project-lite", -] - -[[package]] -name = "async-native-tls" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e9e7a929bd34c68a82d58a4de7f86fffdaf97fb2af850162a7bb19dd7269b33" -dependencies = [ - "async-std", - "native-tls", - "thiserror 1.0.69", - "url", -] - -[[package]] -name = "async-std" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "730294c1c08c2e0f85759590518f6333f0d5a0a766a27d519c1b244c3dfd8a24" -dependencies = [ - "async-channel 1.9.0", - "async-global-executor", - "async-io 2.4.0", - "async-lock 3.4.0", - "crossbeam-utils", - "futures-channel", - "futures-core", - "futures-io", - "futures-lite 2.6.0", - "gloo-timers", - "kv-log-macro", - "log", - "memchr", - "once_cell", - "pin-project-lite", - "pin-utils", - "slab", - "wasm-bindgen-futures", -] - [[package]] name = "async-stream" version = "0.3.6" @@ -535,12 +300,6 @@ dependencies = [ "syn 2.0.100", ] -[[package]] -name = "async-task" -version = "4.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" - [[package]] name = "async-trait" version = "0.1.88" @@ -572,7 +331,7 @@ checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" dependencies = [ "async-trait", "axum-core 0.4.5", - "bytes 1.10.1", + "bytes", "futures-util", "http 1.3.1", "http-body", @@ -593,12 +352,12 @@ dependencies = [ [[package]] name = "axum" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d6fd624c75e18b3b4c6b9caf42b1afe24437daaee904069137d8bab077be8b8" +checksum = "de45108900e1f9b9242f7f2e254aa3e2c029c921c258fe9e6b4217eeebd54288" dependencies = [ - "axum-core 0.5.0", - "bytes 1.10.1", + "axum-core 0.5.2", + "bytes", "futures-util", "http 1.3.1", "http-body", @@ -624,7 +383,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" dependencies = [ "async-trait", - "bytes 1.10.1", + "bytes", "futures-util", "http 1.3.1", "http-body", @@ -639,12 +398,12 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.5.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1362f362fd16024ae199c1970ce98f9661bf5ef94b9808fee734bc3698b733" +checksum = "68464cd0412f486726fb3373129ef5d2993f90c34bc2bc1c1e9943b2f4fc7ca6" dependencies = [ - "bytes 1.10.1", - "futures-util", + "bytes", + "futures-core", "http 1.3.1", "http-body", "http-body-util", @@ -671,18 +430,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "base-x" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" - -[[package]] -name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - [[package]] name = "base64" version = "0.22.1" @@ -691,24 +438,22 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bindgen" -version = "0.63.0" +version = "0.71.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36d860121800b2a9a94f9b5604b332d5cffb234ce17609ea479d723dbc9d3885" +checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.9.0", "cexpr", "clang-sys", - "lazy_static", - "lazycell", + "itertools 0.13.0", "log", - "peeking_take_while", + "prettyplease", "proc-macro2", "quote", "regex", - "rustc-hash 1.1.0", + "rustc-hash", "shlex", - "syn 1.0.109", - "which", + "syn 2.0.100", ] [[package]] @@ -723,15 +468,6 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - [[package]] name = "block-buffer" version = "0.10.4" @@ -741,19 +477,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "blocking" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" -dependencies = [ - "async-channel 2.3.1", - "async-task", - "futures-io", - "futures-lite 2.6.0", - "piper", -] - [[package]] name = "brotli" version = "7.0.0" @@ -777,9 +500,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.11.3" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0" +checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" dependencies = [ "memchr", "serde", @@ -810,12 +533,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" -[[package]] -name = "bytes" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" - [[package]] name = "bytes" version = "1.10.1" @@ -828,7 +545,7 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e465647ae23b2823b0753f50decb2d5a86d2bb2cac04788fafd1f80e45378e5f" dependencies = [ - "bytes 1.10.1", + "bytes", ] [[package]] @@ -866,7 +583,7 @@ checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" dependencies = [ "camino", "cargo-platform", - "semver 1.0.26", + "semver", "serde", "serde_json", "thiserror 1.0.69", @@ -880,9 +597,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.16" +version = "1.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" +checksum = "8e3a13707ac958681c13b39b458c073d0d9bc8a22cb1b2f4c8e55eb72c13f362" dependencies = [ "jobserver", "libc", @@ -895,7 +612,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" dependencies = [ - "nom 7.1.3", + "nom", ] [[package]] @@ -949,15 +666,6 @@ dependencies = [ "half", ] -[[package]] -name = "cipher" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f8e7987cbd042a63249497f41aed09f8e65add917ea6566effbc56578d6801" -dependencies = [ - "generic-array", -] - [[package]] name = "clang-sys" version = "1.8.1" @@ -971,18 +679,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.32" +version = "4.5.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6088f3ae8c3608d19260cd7445411865a485688711b78b5be70d78cd96136f83" +checksum = "2df961d8c8a0d08aa9945718ccf584145eee3f3aa06cddbeac12933781102e04" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.32" +version = "4.5.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a7ef7f676155edfb82daa97f99441f3ebf4a58d5e32f295a56259f1b6facc8" +checksum = "132dbda40fb6753878316a489d5a1242a8ef2f0d9e47ba01c951ea8aa7d013a5" dependencies = [ "anstyle", "clap_lex", @@ -1003,32 +711,6 @@ dependencies = [ "cc", ] -[[package]] -name = "concurrent-queue" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "config" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b076e143e1d9538dde65da30f8481c2a6c44040edb8e02b9bf1351edb92ce3" -dependencies = [ - "lazy_static", - "nom 5.1.3", - "serde", -] - -[[package]] -name = "const_fn" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f8a2ca5ac02d09563609681103aada9e1777d54fc57a5acd7a41404f9c93b6e" - [[package]] name = "const_format" version = "0.2.34" @@ -1049,23 +731,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "cookie" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a5d7b21829bc7b4bf4754a978a241ae54ea55a40f92bb20216e54096f4b951" -dependencies = [ - "aes-gcm", - "base64 0.13.1", - "hkdf", - "hmac", - "percent-encoding", - "rand 0.8.5", - "sha2", - "time 0.2.27", - "version_check", -] - [[package]] name = "cookie" version = "0.16.2" @@ -1073,7 +738,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" dependencies = [ "percent-encoding", - "time 0.3.40", + "time", "version_check", ] @@ -1102,12 +767,6 @@ dependencies = [ "libc", ] -[[package]] -name = "cpuid-bool" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb25d077389e53838a8158c8e99174c5a9d902dee4904320db714f3c653ffba" - [[package]] name = "crc32fast" version = "1.4.2" @@ -1161,9 +820,9 @@ checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" [[package]] name = "crossbeam-channel" -version = "0.5.14" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" dependencies = [ "crossbeam-utils", ] @@ -1187,15 +846,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "crossbeam-queue" -version = "0.3.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" -dependencies = [ - "crossbeam-utils", -] - [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -1218,25 +868,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "crypto-mac" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4857fd85a0c34b3c3297875b747c1e02e06b6a0ea32dd892d8192b9ce0813ea6" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "ctr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb4a30d54f7443bf3d6191dcd486aca19e67cb3c49fa7a06a319966346707e7f" -dependencies = [ - "cipher", -] - [[package]] name = "curl" version = "0.4.47" @@ -1248,7 +879,7 @@ dependencies = [ "openssl-probe", "openssl-sys", "schannel", - "socket2 0.5.8", + "socket2", "windows-sys 0.52.0", ] @@ -1260,7 +891,6 @@ checksum = "55f7df2eac63200c3ab25bde3b2268ef2ee56af3d238e76d61f01c3c49bff734" dependencies = [ "cc", "libc", - "libnghttp2-sys", "libz-sys", "openssl-sys", "pkg-config", @@ -1279,9 +909,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.10" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" dependencies = [ "darling_core", "darling_macro", @@ -1289,9 +919,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.10" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" dependencies = [ "fnv", "ident_case", @@ -1302,9 +932,9 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.10" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", @@ -1312,47 +942,29 @@ dependencies = [ ] [[package]] -name = "dashmap" -version = "5.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" -dependencies = [ - "cfg-if", - "hashbrown 0.14.5", - "lock_api", - "once_cell", - "parking_lot_core", -] - -[[package]] -name = "deadpool" -version = "0.7.0" +name = "debugid" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d126179d86aee4556e54f5f3c6bf6d9884e7cc52cef82f77ee6f90a7747616d" +checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" dependencies = [ - "async-trait", - "config", - "crossbeam-queue", - "num_cpus", "serde", - "tokio", + "uuid", ] [[package]] -name = "debugid" -version = "0.8.0" +name = "defmt" +version = "0.3.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" +checksum = "f0963443817029b2024136fc4dd07a5107eb8f977eaf18fcd1fdeb11306b64ad" dependencies = [ - "serde", - "uuid", + "defmt 1.0.1", ] [[package]] name = "defmt" -version = "0.3.10" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f6162c53f659f65d00619fe31f14556a6e9f8752ccc4a41bd177ffcf3d6130" +checksum = "548d977b6da32fa1d1fda2876453da1e7df63ad0304c8b3dae4dbe7b96f39b78" dependencies = [ "bitflags 1.3.2", "defmt-macros", @@ -1360,9 +972,9 @@ dependencies = [ [[package]] name = "defmt-macros" -version = "0.4.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d135dd939bad62d7490b0002602d35b358dce5fd9233a709d3c1ef467d4bde6" +checksum = "3d4fc12a85bcf441cfe44344c4b72d58493178ce635338a3f3b78943aceb258e" dependencies = [ "defmt-parser", "proc-macro-error2", @@ -1373,9 +985,9 @@ dependencies = [ [[package]] name = "defmt-parser" -version = "0.4.1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3983b127f13995e68c1e29071e5d115cd96f215ccb5e6812e3728cd6f92653b3" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" dependencies = [ "thiserror 2.0.12", ] @@ -1410,31 +1022,16 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - [[package]] name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.4", + "block-buffer", "crypto-common", ] -[[package]] -name = "discard" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" - [[package]] name = "displaydoc" version = "0.2.5" @@ -1460,13 +1057,14 @@ checksum = "1f878075b9794c1e4ac788c95b728f26aa6366d32eeb10c7051389f898f7d067" [[package]] name = "embassy-sync" -version = "0.5.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd938f25c0798db4280fcd8026bf4c2f48789aebf8f77b6e5cf8a7693ba114ec" +checksum = "8d2c8cdff05a7a51ba0087489ea44b0b1d97a296ca6b1d6d1a33ea7423d34049" dependencies = [ "cfg-if", "critical-section", "embedded-io-async", + "futures-sink", "futures-util", "heapless", ] @@ -1532,17 +1130,16 @@ dependencies = [ [[package]] name = "embedded-svc" -version = "0.27.1" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac6f87e7654f28018340aa55f933803017aefabaa5417820a3b2f808033c7bbc" +checksum = "a7770e30ab55cfbf954c00019522490d6ce26a3334bede05a732ba61010e98e0" dependencies = [ - "defmt", + "defmt 0.3.100", "embedded-io", "embedded-io-async", "enumset", "heapless", "log", - "no-std-net", "num_enum", "serde", "strum 0.25.0", @@ -1551,9 +1148,9 @@ dependencies = [ [[package]] name = "embuild" -version = "0.31.4" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4caa4f198bb9152a55c0103efb83fa4edfcbb8625f4c9e94ae8ec8e23827c563" +checksum = "28a8cbd9507fabce8f2741b9ca45da9e898cc2b0f1c2e53d21cb2436aeac811d" dependencies = [ "anyhow", "bindgen", @@ -1563,6 +1160,7 @@ dependencies = [ "globwalk", "home", "log", + "regex", "remove_dir_all", "serde", "serde_json", @@ -1643,9 +1241,9 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" dependencies = [ "libc", "windows-sys 0.59.0", @@ -1653,9 +1251,9 @@ dependencies = [ [[package]] name = "esp-idf-hal" -version = "0.43.1" +version = "0.45.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7adf3fb19a9ca016cbea1ab8a7b852ac69df8fcde4923c23d3b155efbc42a74" +checksum = "775ce25171dc4f615146a4a27ed3a64c6fd99ced77d7112062f2b19bf933f5db" dependencies = [ "atomic-waker", "embassy-sync", @@ -1677,9 +1275,9 @@ dependencies = [ [[package]] name = "esp-idf-svc" -version = "0.48.1" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2180642ca122a7fec1ec417a9b1a77aa66aaa067fdf1daae683dd8caba84f26b" +checksum = "2bc07aaba257d28d54a96af005ca67d0b38876d8837f5d54a3e0547e100b219c" dependencies = [ "embassy-futures", "embedded-hal-async", @@ -1687,6 +1285,7 @@ dependencies = [ "embuild", "enumset", "esp-idf-hal", + "futures-io", "heapless", "log", "num_enum", @@ -1695,14 +1294,14 @@ dependencies = [ [[package]] name = "esp-idf-sys" -version = "0.34.1" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e148f97c04ed3e9181a08bcdc9560a515aad939b0ba7f50a0022e294665e0af" +checksum = "fb77a3d02b579a60a811ed9be22b78c5e794bc492d833ee7fc44d3a0155885e1" dependencies = [ "anyhow", - "bindgen", "build-time", "cargo_metadata", + "cmake", "const_format", "embuild", "envy", @@ -1713,42 +1312,6 @@ dependencies = [ "which", ] -[[package]] -name = "event-listener" -version = "2.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" - -[[package]] -name = "event-listener" -version = "5.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener-strategy" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" -dependencies = [ - "event-listener 5.4.0", - "pin-project-lite", -] - -[[package]] -name = "fastrand" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] - [[package]] name = "fastrand" version = "2.3.0" @@ -1781,25 +1344,14 @@ dependencies = [ [[package]] name = "flate2" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" +checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" dependencies = [ "crc32fast", "miniz_oxide", ] -[[package]] -name = "flume" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bebadab126f8120d410b677ed95eee4ba6eb7c6dd8e34a5ec88a08050e26132" -dependencies = [ - "futures-core", - "futures-sink", - "spinning_top", -] - [[package]] name = "fnv" version = "1.0.7" @@ -1898,34 +1450,6 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" -[[package]] -name = "futures-lite" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" -dependencies = [ - "fastrand 1.9.0", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite", - "waker-fn", -] - -[[package]] -name = "futures-lite" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" -dependencies = [ - "fastrand 2.3.0", - "futures-core", - "futures-io", - "parking", - "pin-project-lite", -] - [[package]] name = "futures-macro" version = "0.3.31" @@ -1983,17 +1507,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - [[package]] name = "getrandom" version = "0.2.15" @@ -2021,16 +1534,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "ghash" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97304e4cd182c3846f7575ced3890c53012ce534ad9114046b0a9e00bb30a375" -dependencies = [ - "opaque-debug", - "polyval", -] - [[package]] name = "gimli" version = "0.31.1" @@ -2067,31 +1570,19 @@ dependencies = [ "walkdir", ] -[[package]] -name = "gloo-timers" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - [[package]] name = "h2" version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ - "bytes 1.10.1", + "bytes", "fnv", "futures-core", "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.8.0", + "indexmap 2.9.0", "slab", "tokio", "tokio-util", @@ -2100,17 +1591,17 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5017294ff4bb30944501348f6f8e42e6ad28f42c8bbef7a74029aff064a4e3c2" +checksum = "75249d144030531f8dee69fe9cea04d3edf809a017ae445e2abdff6629e86633" dependencies = [ "atomic-waker", - "bytes 1.10.1", + "bytes", "fnv", "futures-core", "futures-sink", "http 1.3.1", - "indexmap 2.8.0", + "indexmap 2.9.0", "slab", "tokio", "tokio-util", @@ -2119,9 +1610,9 @@ dependencies = [ [[package]] name = "half" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7db2ff139bba50379da6aa0766b52fdcb62cb5b263009b09ed58ba604e14bbd1" +checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" dependencies = [ "cfg-if", "crunchy", @@ -2142,12 +1633,6 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -[[package]] -name = "hashbrown" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" - [[package]] name = "hashbrown" version = "0.15.2" @@ -2167,21 +1652,9 @@ dependencies = [ [[package]] name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hermit-abi" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" @@ -2195,26 +1668,6 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[package]] -name = "hkdf" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51ab2f639c231793c5f6114bdb9bbe50a7dbbfcd7c7c6bd8475dec2d991e964f" -dependencies = [ - "digest 0.9.0", - "hmac", -] - -[[package]] -name = "hmac" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1441c6b1e930e2817404b5046f1f989899143a12bf92de603b69f4e0aee1e15" -dependencies = [ - "crypto-mac", - "digest 0.9.0", -] - [[package]] name = "home" version = "0.5.11" @@ -2226,13 +1679,13 @@ dependencies = [ [[package]] name = "hostname" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9c7c7c8ac16c798734b8a24560c1362120597c40d5e1459f09498f8f6c8f2ba" +checksum = "a56f203cd1c76362b69e3863fd987520ac36cf70a8c92627449b2f64a8cf7d65" dependencies = [ "cfg-if", "libc", - "windows", + "windows-link", ] [[package]] @@ -2241,7 +1694,7 @@ version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ - "bytes 1.10.1", + "bytes", "fnv", "itoa", ] @@ -2252,7 +1705,7 @@ version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" dependencies = [ - "bytes 1.10.1", + "bytes", "fnv", "itoa", ] @@ -2263,7 +1716,7 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ - "bytes 1.10.1", + "bytes", "http 1.3.1", ] @@ -2273,54 +1726,13 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ - "bytes 1.10.1", + "bytes", "futures-core", "http 1.3.1", "http-body", "pin-project-lite", ] -[[package]] -name = "http-client" -version = "6.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1947510dc91e2bf586ea5ffb412caad7673264e14bb39fb9078da114a94ce1a5" -dependencies = [ - "async-h1", - "async-native-tls", - "async-std", - "async-trait", - "cfg-if", - "dashmap", - "deadpool", - "futures", - "http-types", - "isahc", - "log", -] - -[[package]] -name = "http-types" -version = "2.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e9b187a72d63adbfba487f48095306ac823049cb504ee195541e91c7775f5ad" -dependencies = [ - "anyhow", - "async-channel 1.9.0", - "async-std", - "base64 0.13.1", - "cookie 0.14.4", - "futures-lite 1.13.0", - "infer", - "pin-project-lite", - "rand 0.7.3", - "serde", - "serde_json", - "serde_qs", - "serde_urlencoded", - "url", -] - [[package]] name = "httparse" version = "1.10.1" @@ -2345,10 +1757,10 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" dependencies = [ - "bytes 1.10.1", + "bytes", "futures-channel", "futures-util", - "h2 0.4.8", + "h2 0.4.9", "http 1.3.1", "http-body", "httparse", @@ -2397,7 +1809,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ - "bytes 1.10.1", + "bytes", "http-body-util", "hyper", "hyper-util", @@ -2409,18 +1821,19 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" +checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2" dependencies = [ - "bytes 1.10.1", + "bytes", "futures-channel", "futures-util", "http 1.3.1", "http-body", "hyper", + "libc", "pin-project-lite", - "socket2 0.5.8", + "socket2", "tokio", "tower-service", "tracing", @@ -2428,14 +1841,15 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.61" +version = "0.1.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", + "log", "wasm-bindgen", "windows-core", ] @@ -2490,9 +1904,9 @@ dependencies = [ [[package]] name = "icu_locid_transform_data" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" +checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d" [[package]] name = "icu_normalizer" @@ -2514,9 +1928,9 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" +checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7" [[package]] name = "icu_properties" @@ -2535,9 +1949,9 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" +checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2" [[package]] name = "icu_provider" @@ -2628,40 +2042,14 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" dependencies = [ "equivalent", "hashbrown 0.15.2", ] -[[package]] -name = "infer" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e9829a50b42bb782c1df523f78d332fe371b10c661e78b7a3c34b0198e9fac" - -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi 0.3.9", - "libc", - "windows-sys 0.48.0", -] - [[package]] name = "ipnet" version = "2.11.0" @@ -2674,41 +2062,25 @@ version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ - "hermit-abi 0.5.0", + "hermit-abi", "libc", "windows-sys 0.59.0", ] [[package]] -name = "isahc" -version = "0.9.14" +name = "itertools" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2948a0ce43e2c2ef11d7edf6816508998d99e13badd1150be0914205df9388a" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ - "bytes 0.5.6", - "crossbeam-utils", - "curl", - "curl-sys", - "encoding_rs", - "flume", - "futures-lite 1.13.0", - "http 0.2.12", - "log", - "mime", - "once_cell", - "slab", - "sluice", - "tracing", - "tracing-futures", - "url", - "waker-fn", + "either", ] [[package]] name = "itertools" -version = "0.10.5" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" dependencies = [ "either", ] @@ -2730,10 +2102,11 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jobserver" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" dependencies = [ + "getrandom 0.3.2", "libc", ] @@ -2747,15 +2120,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "kv-log-macro" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" -dependencies = [ - "log", -] - [[package]] name = "language-tags" version = "0.3.2" @@ -2768,30 +2132,11 @@ 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 = "lexical-core" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" -dependencies = [ - "arrayvec", - "bitflags 1.3.2", - "cfg-if", - "ryu", - "static_assertions", -] - [[package]] name = "libc" -version = "0.2.171" +version = "0.2.172" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" [[package]] name = "libloading" @@ -2803,16 +2148,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "libnghttp2-sys" -version = "0.1.11+1.64.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b6c24e48a7167cffa7119da39d577fa482e66c688a4aac016bee862e1a713c4" -dependencies = [ - "cc", - "libc", -] - [[package]] name = "libredox" version = "0.1.3" @@ -2836,12 +2171,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "linux-raw-sys" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" - [[package]] name = "linux-raw-sys" version = "0.4.15" @@ -2850,9 +2179,9 @@ checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "linux-raw-sys" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" [[package]] name = "litemap" @@ -2889,12 +2218,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.26" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" -dependencies = [ - "value-bag", -] +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "matchit" @@ -2920,16 +2246,6 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" -[[package]] -name = "mime_guess" -version = "2.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" -dependencies = [ - "mime", - "unicase", -] - [[package]] name = "minimal-lexical" version = "0.2.1" @@ -2938,9 +2254,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" +checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" dependencies = [ "adler2", ] @@ -3001,26 +2317,6 @@ dependencies = [ "libc", ] -[[package]] -name = "no-std-net" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bcece43b12349917e096cddfa66107277f123e6c96a5aea78711dc601a47152" -dependencies = [ - "serde", -] - -[[package]] -name = "nom" -version = "5.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08959a387a676302eebf4ddbcbc611da04285579f76f88ee0506c63b1a61dd4b" -dependencies = [ - "lexical-core", - "memchr", - "version_check", -] - [[package]] name = "nom" version = "7.1.3" @@ -3065,16 +2361,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi 0.3.9", - "libc", -] - [[package]] name = "num_enum" version = "0.7.3" @@ -3107,9 +2393,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.1" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "oorandom" @@ -3117,12 +2403,6 @@ version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - [[package]] name = "openssl" version = "0.10.72" @@ -3184,12 +2464,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" -[[package]] -name = "parking" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" - [[package]] name = "parking_lot" version = "0.12.3" @@ -3213,12 +2487,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[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" @@ -3257,17 +2525,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "piper" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" -dependencies = [ - "atomic-waker", - "fastrand 2.3.0", - "futures-io", -] - [[package]] name = "pkg-config" version = "0.3.32" @@ -3302,48 +2559,6 @@ dependencies = [ "plotters-backend", ] -[[package]] -name = "polling" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" -dependencies = [ - "autocfg", - "bitflags 1.3.2", - "cfg-if", - "concurrent-queue", - "libc", - "log", - "pin-project-lite", - "windows-sys 0.48.0", -] - -[[package]] -name = "polling" -version = "3.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f" -dependencies = [ - "cfg-if", - "concurrent-queue", - "hermit-abi 0.4.0", - "pin-project-lite", - "rustix 0.38.44", - "tracing", - "windows-sys 0.59.0", -] - -[[package]] -name = "polyval" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eebcc4aa140b9abd2bc40d9c3f7ccec842679cd79045ac3a7ac698c1a064b7cd" -dependencies = [ - "cpuid-bool", - "opaque-debug", - "universal-hash", -] - [[package]] name = "powerfmt" version = "0.2.0" @@ -3369,6 +2584,16 @@ dependencies = [ "log", ] +[[package]] +name = "prettyplease" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "664ec5419c51e34154eec046ebcba56312d5a2fc3b09a06da188e1ad21afadf6" +dependencies = [ + "proc-macro2", + "syn 2.0.100", +] + [[package]] name = "proc-macro-crate" version = "3.3.0" @@ -3400,17 +2625,11 @@ dependencies = [ "syn 2.0.100", ] -[[package]] -name = "proc-macro-hack" -version = "0.5.20+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" - [[package]] name = "proc-macro2" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] @@ -3421,7 +2640,7 @@ version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" dependencies = [ - "bytes 1.10.1", + "bytes", "prost-derive", ] @@ -3444,14 +2663,14 @@ version = "0.11.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3bd15a6f2967aef83887dcb9fec0014580467e33720d073560cf015a5683012" dependencies = [ - "bytes 1.10.1", + "bytes", "cfg_aliases", "pin-project-lite", "quinn-proto", "quinn-udp", - "rustc-hash 2.1.1", + "rustc-hash", "rustls", - "socket2 0.5.8", + "socket2", "thiserror 2.0.12", "tokio", "tracing", @@ -3464,11 +2683,11 @@ version = "0.11.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b820744eb4dc9b57a3398183639c511b5a26d2ed702cedd3febaa1393caa22cc" dependencies = [ - "bytes 1.10.1", + "bytes", "getrandom 0.3.2", "rand 0.9.0", "ring", - "rustc-hash 2.1.1", + "rustc-hash", "rustls", "rustls-pki-types", "slab", @@ -3480,14 +2699,14 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.10" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e46f3055866785f6b92bc6164b76be02ca8f2eb4b002c0354b28cf4c119e5944" +checksum = "541d0f57c6ec747a90738a52741d3221f7960e8ac2f0ff4b1a63680e033b4ab5" dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.5.8", + "socket2", "tracing", "windows-sys 0.59.0", ] @@ -3507,19 +2726,6 @@ version = "5.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc", -] - [[package]] name = "rand" version = "0.8.5" @@ -3542,16 +2748,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", -] - [[package]] name = "rand_chacha" version = "0.3.1" @@ -3572,15 +2768,6 @@ dependencies = [ "rand_core 0.9.3", ] -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] - [[package]] name = "rand_core" version = "0.6.4" @@ -3599,15 +2786,6 @@ dependencies = [ "getrandom 0.3.2", ] -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", -] - [[package]] name = "rayon" version = "1.10.0" @@ -3630,9 +2808,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.10" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" +checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" dependencies = [ "bitflags 2.9.0", ] @@ -3698,8 +2876,8 @@ version = "0.12.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" dependencies = [ - "base64 0.22.1", - "bytes 1.10.1", + "base64", + "bytes", "futures-channel", "futures-core", "futures-util", @@ -3755,29 +2933,30 @@ dependencies = [ [[package]] name = "rstest" -version = "0.19.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5316d2a1479eeef1ea21e7f9ddc67c191d497abc8fc3ba2467857abbb68330" +checksum = "6fc39292f8613e913f7df8fa892b8944ceb47c247b78e1b1ae2f09e019be789d" dependencies = [ - "futures", "futures-timer", + "futures-util", "rstest_macros", - "rustc_version 0.4.1", + "rustc_version", ] [[package]] name = "rstest_macros" -version = "0.19.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04a9df72cc1f67020b0d63ad9bfe4a323e459ea7eb68e03bd9824db49f9a4c25" +checksum = "1f168d99749d307be9de54d23fd226628d99768225ef08f6ffb52e0182a27746" dependencies = [ "cfg-if", "glob", + "proc-macro-crate", "proc-macro2", "quote", "regex", "relative-path", - "rustc_version 0.4.1", + "rustc_version", "syn 2.0.100", "unicode-ident", ] @@ -3788,12 +2967,6 @@ 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" @@ -3801,35 +2974,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver 0.9.0", -] - -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver 1.0.26", -] - -[[package]] -name = "rustix" -version = "0.37.28" +name = "rustc_version" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "519165d378b97752ca44bbe15047d5d3409e875f39327546b42ac81d7e18c1b6" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "bitflags 1.3.2", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys 0.3.8", - "windows-sys 0.48.0", + "semver", ] [[package]] @@ -3847,22 +2997,22 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.3" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96" +checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" dependencies = [ "bitflags 2.9.0", "errno", "libc", - "linux-raw-sys 0.9.3", + "linux-raw-sys 0.9.4", "windows-sys 0.59.0", ] [[package]] name = "rustls" -version = "0.23.25" +version = "0.23.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c" +checksum = "df51b5869f3a441595eac5e8ff14d486ff285f7b8c0df8770e49c3b56351f0f0" dependencies = [ "log", "once_cell", @@ -3893,9 +3043,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.0" +version = "0.103.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0aa4eeac2588ffff23e9d7a7e9b3f971c5fb5b7ebc9452745e0c232c64f83b2f" +checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03" dependencies = [ "ring", "rustls-pki-types", @@ -3961,15 +3111,6 @@ dependencies = [ "libc", ] -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - [[package]] name = "semver" version = "1.0.26" @@ -3979,12 +3120,6 @@ dependencies = [ "serde", ] -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - [[package]] name = "sentry" version = "0.37.0" @@ -3994,9 +3129,7 @@ dependencies = [ "curl", "embedded-svc", "esp-idf-svc", - "http-client", "httpdate", - "isahc", "log", "native-tls", "pretty_env_logger", @@ -4014,9 +3147,8 @@ dependencies = [ "sentry-tracing", "serde_json", "slog", - "surf", "tokio", - "tower 0.4.13", + "tower 0.5.2", "tracing", "tracing-subscriber", "ureq", @@ -4029,7 +3161,7 @@ version = "0.37.0" dependencies = [ "actix-http", "actix-web", - "bytes 1.10.1", + "bytes", "futures", "futures-util", "sentry", @@ -4064,7 +3196,7 @@ dependencies = [ "hostname", "libc", "os_info", - "rustc_version 0.4.1", + "rustc_version", "sentry", "sentry-core", "uname", @@ -4081,14 +3213,14 @@ dependencies = [ "futures", "log", "once_cell", - "rand 0.8.5", + "rand 0.9.0", "rayon", "regex", "sentry", "sentry-types", "serde", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.12", "tokio", "uuid", ] @@ -4138,7 +3270,7 @@ name = "sentry-tower" version = "0.37.0" dependencies = [ "anyhow", - "axum 0.8.1", + "axum 0.8.3", "http 1.3.1", "pin-project", "prost", @@ -4147,7 +3279,7 @@ dependencies = [ "sentry-core", "tokio", "tonic", - "tower 0.4.13", + "tower 0.5.2", "tower-layer", "tower-service", "url", @@ -4174,12 +3306,12 @@ version = "0.37.0" dependencies = [ "debugid", "hex", - "rand 0.8.5", + "rand 0.9.0", "rstest", "serde", "serde_json", - "thiserror 1.0.69", - "time 0.3.40", + "thiserror 2.0.12", + "time", "url", "uuid", ] @@ -4216,17 +3348,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_qs" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7715380eec75f029a4ef7de39a9200e0a63823176b759d055b613f5a87df6a6" -dependencies = [ - "percent-encoding", - "serde", - "thiserror 1.0.69", -] - [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -4239,15 +3360,6 @@ dependencies = [ "serde", ] -[[package]] -name = "sha1" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770" -dependencies = [ - "sha1_smol", -] - [[package]] name = "sha1" version = "0.10.6" @@ -4256,26 +3368,7 @@ checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.7", -] - -[[package]] -name = "sha1_smol" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" - -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", + "digest", ] [[package]] @@ -4320,122 +3413,28 @@ dependencies = [ "erased-serde", ] -[[package]] -name = "sluice" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7400c0eff44aa2fcb5e31a5f24ba9716ed90138769e4977a2ba6014ae63eb5" -dependencies = [ - "async-channel 1.9.0", - "futures-core", - "futures-io", -] - [[package]] name = "smallvec" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" - -[[package]] -name = "socket2" -version = "0.4.10" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" -dependencies = [ - "libc", - "winapi", -] +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" [[package]] name = "socket2" -version = "0.5.8" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" +checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" dependencies = [ "libc", "windows-sys 0.52.0", ] -[[package]] -name = "spinning_top" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b9eb1a2f4c41445a3a0ff9abc5221c5fcd28e1f13cd7c0397706f9ac938ddb0" -dependencies = [ - "lock_api", -] - [[package]] name = "stable_deref_trait" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" -[[package]] -name = "standback" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff" -dependencies = [ - "version_check", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "stdweb" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" -dependencies = [ - "discard", - "rustc_version 0.2.3", - "stdweb-derive", - "stdweb-internal-macros", - "stdweb-internal-runtime", - "wasm-bindgen", -] - -[[package]] -name = "stdweb-derive" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" -dependencies = [ - "proc-macro2", - "quote", - "serde", - "serde_derive", - "syn 1.0.109", -] - -[[package]] -name = "stdweb-internal-macros" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" -dependencies = [ - "base-x", - "proc-macro2", - "quote", - "serde", - "serde_derive", - "serde_json", - "sha1 0.6.1", - "syn 1.0.109", -] - -[[package]] -name = "stdweb-internal-runtime" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" - [[package]] name = "strum" version = "0.24.1" @@ -4486,28 +3485,6 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" -[[package]] -name = "surf" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718b1ae6b50351982dedff021db0def601677f2120938b070eadb10ba4038dd7" -dependencies = [ - "async-native-tls", - "async-std", - "async-trait", - "cfg-if", - "futures-util", - "getrandom 0.2.15", - "http-client", - "http-types", - "log", - "mime_guess", - "once_cell", - "pin-project-lite", - "serde", - "serde_json", -] - [[package]] name = "syn" version = "1.0.109" @@ -4552,14 +3529,14 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.19.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488960f40a3fd53d72c2a29a58722561dee8afdd175bd88e3db4677d7b2ba600" +checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" dependencies = [ - "fastrand 2.3.0", + "fastrand", "getrandom 0.3.2", "once_cell", - "rustix 1.0.3", + "rustix 1.0.5", "windows-sys 0.59.0", ] @@ -4624,24 +3601,9 @@ dependencies = [ [[package]] name = "time" -version = "0.2.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4752a97f8eebd6854ff91f1c1824cd6160626ac4bd44287f7f4ea2035a02a242" -dependencies = [ - "const_fn", - "libc", - "standback", - "stdweb", - "time-macros 0.1.1", - "version_check", - "winapi", -] - -[[package]] -name = "time" -version = "0.3.40" +version = "0.3.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d9c75b47bdff86fa3334a3db91356b8d7d86a9b839dab7d0bdc5c3d3a077618" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" dependencies = [ "deranged", "itoa", @@ -4649,7 +3611,7 @@ dependencies = [ "powerfmt", "serde", "time-core", - "time-macros 0.2.21", + "time-macros", ] [[package]] @@ -4660,37 +3622,14 @@ checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" [[package]] name = "time-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1" -dependencies = [ - "proc-macro-hack", - "time-macros-impl", -] - -[[package]] -name = "time-macros" -version = "0.2.21" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29aa485584182073ed57fd5004aa09c371f021325014694e432313345865fd04" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" dependencies = [ "num-conv", "time-core", ] -[[package]] -name = "time-macros-impl" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f" -dependencies = [ - "proc-macro-hack", - "proc-macro2", - "quote", - "standback", - "syn 1.0.109", -] - [[package]] name = "tinystr" version = "0.7.6" @@ -4733,13 +3672,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48" dependencies = [ "backtrace", - "bytes 1.10.1", + "bytes", "libc", "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.8", + "socket2", "tokio-macros", "windows-sys 0.52.0", ] @@ -4792,7 +3731,7 @@ version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034" dependencies = [ - "bytes 1.10.1", + "bytes", "futures-core", "futures-sink", "pin-project-lite", @@ -4811,7 +3750,7 @@ version = "0.22.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" dependencies = [ - "indexmap 2.8.0", + "indexmap 2.9.0", "toml_datetime", "winnow", ] @@ -4825,9 +3764,9 @@ dependencies = [ "async-stream", "async-trait", "axum 0.7.9", - "base64 0.22.1", - "bytes 1.10.1", - "h2 0.4.8", + "base64", + "bytes", + "h2 0.4.9", "http 1.3.1", "http-body", "http-body-util", @@ -4837,7 +3776,7 @@ dependencies = [ "percent-encoding", "pin-project", "prost", - "socket2 0.5.8", + "socket2", "tokio", "tokio-stream", "tower 0.4.13", @@ -4926,16 +3865,6 @@ dependencies = [ "valuable", ] -[[package]] -name = "tracing-futures" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" -dependencies = [ - "pin-project", - "tracing", -] - [[package]] name = "tracing-log" version = "0.2.0" @@ -4991,12 +3920,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "unicase" -version = "2.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" - [[package]] name = "unicode-ident" version = "1.0.18" @@ -5009,16 +3932,6 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" -[[package]] -name = "universal-hash" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8326b2c654932e3e4f9196e69d08fdf7cfd718e1dc6f66b347e6024a0c961402" -dependencies = [ - "generic-array", - "subtle", -] - [[package]] name = "untrusted" version = "0.9.0" @@ -5031,7 +3944,7 @@ version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d" dependencies = [ - "base64 0.22.1", + "base64", "log", "native-tls", "once_cell", @@ -5081,12 +3994,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" -[[package]] -name = "value-bag" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2" - [[package]] name = "vcpkg" version = "0.2.15" @@ -5105,12 +4012,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -[[package]] -name = "waker-fn" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" - [[package]] name = "walkdir" version = "2.5.0" @@ -5130,12 +4031,6 @@ dependencies = [ "try-lock", ] -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -5295,22 +4190,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows" -version = "0.52.0" +name = "windows-core" +version = "0.61.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" dependencies = [ - "windows-core", - "windows-targets 0.52.6", + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings 0.4.0", ] [[package]] -name = "windows-core" -version = "0.52.0" +name = "windows-implement" +version = "0.60.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" dependencies = [ - "windows-targets 0.52.6", + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", ] [[package]] @@ -5326,7 +4237,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" dependencies = [ "windows-result", - "windows-strings", + "windows-strings 0.3.1", "windows-targets 0.53.0", ] @@ -5349,12 +4260,12 @@ dependencies = [ ] [[package]] -name = "windows-sys" -version = "0.48.0" +name = "windows-strings" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" dependencies = [ - "windows-targets 0.48.5", + "windows-link", ] [[package]] @@ -5375,21 +4286,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - [[package]] name = "windows-targets" version = "0.52.6" @@ -5422,12 +4318,6 @@ dependencies = [ "windows_x86_64_msvc 0.53.0", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" @@ -5440,12 +4330,6 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" @@ -5458,12 +4342,6 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -5488,12 +4366,6 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.6" @@ -5506,12 +4378,6 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" @@ -5524,12 +4390,6 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" @@ -5542,12 +4402,6 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -5562,9 +4416,9 @@ checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" [[package]] name = "winnow" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36" +checksum = "63d3fcd9bba44b03821e7d699eeee959f3126dcc4aa8e4ae18ec617c2a5cea10" dependencies = [ "memchr", ] @@ -5616,18 +4470,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.23" +version = "0.8.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6" +checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.23" +version = "0.8.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154" +checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" dependencies = [ "proc-macro2", "quote", @@ -5694,18 +4548,18 @@ dependencies = [ [[package]] name = "zstd-safe" -version = "7.2.3" +version = "7.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3051792fbdc2e1e143244dc28c60f73d8470e93f3f9cbd0ead44da5ed802722" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" dependencies = [ "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.14+zstd.1.5.7" +version = "2.0.15+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fb060d4926e4ac3a3ad15d864e99ceb5f343c6b34f5bd6d81ae6ed417311be5" +checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237" dependencies = [ "cc", "pkg-config", diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index 891e77147..09b4574bf 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -33,7 +33,7 @@ cadence = { version = "1.4.0", optional = true } crc32fast = { version = "1.4.0", optional = true } log = { version = "0.4.8", optional = true, features = ["std"] } once_cell = "1" -rand = { version = "0.8.1", optional = true } +rand = { version = "0.9.0", optional = true } regex = { version = "1.7.3", optional = true } sentry-types = { version = "0.37.0", path = "../sentry-types" } serde = { version = "1.0.104", features = ["derive"] } @@ -52,5 +52,5 @@ anyhow = "1.0.30" criterion = "0.5" futures = "0.3.24" rayon = "1.5.3" -thiserror = "1.0.15" +thiserror = "2.0.12" tokio = { version = "1.44", features = ["rt", "rt-multi-thread", "macros"] } diff --git a/sentry-tower/Cargo.toml b/sentry-tower/Cargo.toml index a5c8a4f97..8be3a7212 100644 --- a/sentry-tower/Cargo.toml +++ b/sentry-tower/Cargo.toml @@ -38,5 +38,5 @@ prost = "0.13.3" sentry = { path = "../sentry", default-features = false, features = ["test"] } sentry-anyhow = { path = "../sentry-anyhow" } tokio = { version = "1", features = ["macros", "rt-multi-thread"] } -tonic = { version = "0.12", features = ["transport"] } -tower = { version = "0.4", features = ["util", "timeout"] } +tonic = { version = "0.12.3", features = ["transport"] } +tower = { version = "0.5.2", features = ["util", "timeout"] } diff --git a/sentry-types/Cargo.toml b/sentry-types/Cargo.toml index ac5593153..c634bc0b0 100644 --- a/sentry-types/Cargo.toml +++ b/sentry-types/Cargo.toml @@ -23,13 +23,13 @@ protocol = [] [dependencies] debugid = { version = "0.8.0", features = ["serde"] } hex = "0.4.3" -rand = "0.8.5" +rand = "0.9.0" serde = { version = "1.0.104", features = ["derive"] } serde_json = "1.0.46" -thiserror = "1.0.15" +thiserror = "2.0.12" time = { version = "0.3.5", features = ["formatting", "parsing"] } url = { version = "2.1.1", features = ["serde"] } uuid = { version = "1.0.0", features = ["serde"] } [dev-dependencies] -rstest = "0.19.0" +rstest = "0.25.0" diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index 54a982a48..5d77a6299 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -83,9 +83,9 @@ ureq = { version = "2.10.1", optional = true, default-features = false } native-tls = { version = "0.2.8", optional = true } rustls = { version = "0.23.18", optional = true, default-features = false } webpki-roots = { version = "0.26.1", optional = true } -embedded-svc = { version = "0.27.1", optional = true } +embedded-svc = { version = "0.28.1", optional = true } [target.'cfg(target_os = "espidf")'.dependencies] -esp-idf-svc = { version = "0.48.1", optional = true } +esp-idf-svc = { version = "0.51.0", optional = true } [dev-dependencies] sentry-anyhow = { path = "../sentry-anyhow" } @@ -99,7 +99,7 @@ log = { version = "0.4.8", features = ["std"] } pretty_env_logger = "0.5.0" slog = { version = "2.5.2" } tokio = { version = "1.44", features = ["macros"] } -tower = { version = "0.4", features = ["util"] } +tower = { version = "0.5.2", features = ["util"] } tracing = { version = "0.1" } tracing-subscriber = { version = "0.3", features = ["fmt", "tracing-log"] } From 6f568328bdec04e72288e69bcd80afe191fdbafb Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Thu, 17 Apr 2025 15:24:22 +0200 Subject: [PATCH 069/148] refactor: honor `send_default_pii` in `sentry-actix` and `sentry-tower` (#771) * refactor: honor `send-default-pii` in `sentry-actix` and `sentry-tower` * also actix request body * improve * deprecate instead of removing * improve * improve --- sentry-actix/src/lib.rs | 24 ++++++++++------- sentry-core/src/clientoptions.rs | 2 +- sentry-core/src/lib.rs | 3 +++ sentry-core/src/utils.rs | 17 ++++++++++++ sentry-tower/src/http.rs | 45 +++++++++++++++++++++++++++----- sentry-tower/src/lib.rs | 2 +- 6 files changed, 74 insertions(+), 19 deletions(-) create mode 100644 sentry-core/src/utils.rs diff --git a/sentry-actix/src/lib.rs b/sentry-actix/src/lib.rs index e5a549d49..fe447704c 100644 --- a/sentry-actix/src/lib.rs +++ b/sentry-actix/src/lib.rs @@ -88,6 +88,7 @@ use futures_util::future::{ok, Future, Ready}; use futures_util::{FutureExt as _, TryStreamExt as _}; use sentry_core::protocol::{self, ClientSdkPackage, Event, Request}; +use sentry_core::utils::is_sensitive_header; use sentry_core::MaxRequestBodySize; use sentry_core::{Hub, SentryFutureExt}; @@ -212,6 +213,7 @@ pub struct SentryMiddleware { fn should_capture_request_body( headers: &HeaderMap, + with_pii: bool, max_request_body_size: MaxRequestBodySize, ) -> bool { let is_chunked = headers @@ -220,15 +222,16 @@ fn should_capture_request_body( .map(|transfer_encoding| transfer_encoding.contains("chunked")) .unwrap_or(false); - let is_valid_content_type = headers - .get(header::CONTENT_TYPE) - .and_then(|h| h.to_str().ok()) - .is_some_and(|content_type| { - matches!( - content_type, - "application/json" | "application/x-www-form-urlencoded" - ) - }); + let is_valid_content_type = with_pii + || headers + .get(header::CONTENT_TYPE) + .and_then(|h| h.to_str().ok()) + .is_some_and(|content_type| { + matches!( + content_type, + "application/json" | "application/x-www-form-urlencoded" + ) + }); let is_within_size_limit = headers .get(header::CONTENT_LENGTH) @@ -322,7 +325,7 @@ where async move { let mut req = req; - if should_capture_request_body(req.headers(), max_request_body_size) { + if should_capture_request_body(req.headers(), with_pii, max_request_body_size) { sentry_req.data = Some(capture_request_body(&mut req).await); } @@ -424,6 +427,7 @@ fn sentry_request_from_http(request: &ServiceRequest, with_pii: bool) -> Request .headers() .iter() .filter(|(_, v)| !v.is_sensitive()) + .filter(|(k, _)| with_pii || !is_sensitive_header(k.as_str())) .map(|(k, v)| (k.to_string(), v.to_str().unwrap_or_default().to_string())) .collect(), ..Default::default() diff --git a/sentry-core/src/clientoptions.rs b/sentry-core/src/clientoptions.rs index 9c0f98d34..b05767e20 100644 --- a/sentry-core/src/clientoptions.rs +++ b/sentry-core/src/clientoptions.rs @@ -120,7 +120,7 @@ pub struct ClientOptions { pub max_breadcrumbs: usize, /// Attaches stacktraces to messages. pub attach_stacktrace: bool, - /// If turned on some default PII informat is attached. + /// If turned on, some information that can be considered PII is captured, such as potentially sensitive HTTP headers and user IP address in HTTP server integrations. pub send_default_pii: bool, /// The server name to be reported. pub server_name: Option>, diff --git a/sentry-core/src/lib.rs b/sentry-core/src/lib.rs index 3021681da..db1b511ac 100644 --- a/sentry-core/src/lib.rs +++ b/sentry-core/src/lib.rs @@ -159,3 +159,6 @@ pub mod test; pub use sentry_types as types; pub use sentry_types::protocol::v7 as protocol; pub use sentry_types::protocol::v7::{Breadcrumb, Envelope, Level, User}; + +// utilities reused across integrations +pub mod utils; diff --git a/sentry-core/src/utils.rs b/sentry-core/src/utils.rs new file mode 100644 index 000000000..b78adba3c --- /dev/null +++ b/sentry-core/src/utils.rs @@ -0,0 +1,17 @@ +//! Utilities reused across dependant crates and integrations. + +const SENSITIVE_HEADERS_UPPERCASE: &[&str] = &[ + "AUTHORIZATION", + "PROXY_AUTHORIZATION", + "COOKIE", + "SET_COOKIE", + "X_FORWARDED_FOR", + "X_REAL_IP", + "X_API_KEY", +]; + +/// Determines if the HTTP header with the given name shall be considered as potentially carrying +/// sensitive data. +pub fn is_sensitive_header(name: &str) -> bool { + SENSITIVE_HEADERS_UPPERCASE.contains(&name.to_ascii_uppercase().replace("-", "_").as_str()) +} diff --git a/sentry-tower/src/http.rs b/sentry-tower/src/http.rs index ee159a99a..95b46ad39 100644 --- a/sentry-tower/src/http.rs +++ b/sentry-tower/src/http.rs @@ -5,13 +5,14 @@ use std::task::{Context, Poll}; use http::{header, uri, Request, Response, StatusCode}; use pin_project::pinned_drop; -use sentry_core::protocol; +use sentry_core::utils::is_sensitive_header; +use sentry_core::{protocol, Hub}; use tower_layer::Layer; use tower_service::Service; -/// Tower Layer that logs Http Request Headers. +/// Tower Layer that captures Http Request information. /// -/// The Service created by this Layer can also optionally start a new +/// The Service created by this Layer can optionally start a new /// performance monitoring transaction for each incoming request, /// continuing the trace based on incoming distributed tracing headers. /// @@ -20,35 +21,63 @@ use tower_service::Service; /// or similar. In this case, users should manually override the transaction name /// in the request handler using the [`Scope::set_transaction`](sentry_core::Scope::set_transaction) /// method. +/// +/// By default, the service will filter out potentially sensitive headers from the captured +/// requests. By enabling `with_pii`, you can opt in to capturing all headers instead. #[derive(Clone, Default)] pub struct SentryHttpLayer { start_transaction: bool, + with_pii: bool, } impl SentryHttpLayer { - /// Creates a new Layer that only logs Request Headers. + /// Creates a new Layer that only captures request information. + /// If a client is bound to the main Hub (i.e. the SDK has already been initialized), set `with_pii` based on the `send_default_pii` client option. pub fn new() -> Self { - Self::default() + let mut slf = Self::default(); + Hub::main() + .client() + .inspect(|client| slf.with_pii = client.options().send_default_pii); + slf } /// Creates a new Layer which starts a new performance monitoring transaction /// for each incoming request. + #[deprecated(since = "0.38.0", note = "please use `enable_transaction` instead")] pub fn with_transaction() -> Self { Self { start_transaction: true, + with_pii: false, } } + + /// Enable starting a new performance monitoring transaction for each incoming request. + #[must_use] + pub fn enable_transaction(mut self) -> Self { + self.start_transaction = true; + self + } + + /// Include PII in captured requests. Potentially sensitive headers are not filtered out. + #[must_use] + pub fn enable_pii(mut self) -> Self { + self.with_pii = true; + self + } } -/// Tower Service that logs Http Request Headers. +/// Tower Service that captures Http Request information. /// -/// The Service can also optionally start a new performance monitoring transaction +/// The Service can optionally start a new performance monitoring transaction /// for each incoming request, continuing the trace based on incoming /// distributed tracing headers. +/// +/// If `with_pii` is disabled, sensitive headers will be filtered out. #[derive(Clone)] pub struct SentryHttpService { service: S, start_transaction: bool, + with_pii: bool, } impl Layer for SentryHttpLayer { @@ -58,6 +87,7 @@ impl Layer for SentryHttpLayer { Self::Service { service, start_transaction: self.start_transaction, + with_pii: self.with_pii, } } } @@ -161,6 +191,7 @@ where .headers() .into_iter() .filter(|(_, value)| !value.is_sensitive()) + .filter(|(header, _)| self.with_pii || !is_sensitive_header(header.as_str())) .map(|(header, value)| { ( header.to_string(), diff --git a/sentry-tower/src/lib.rs b/sentry-tower/src/lib.rs index cccf2e8fb..a97c068c9 100644 --- a/sentry-tower/src/lib.rs +++ b/sentry-tower/src/lib.rs @@ -126,7 +126,7 @@ //! # type Request = http::Request; //! let layer = tower::ServiceBuilder::new() //! .layer(sentry_tower::NewSentryLayer::::new_from_top()) -//! .layer(sentry_tower::SentryHttpLayer::with_transaction()); +//! .layer(sentry_tower::SentryHttpLayer::new().enable_transaction()); //! # } //! ``` //! From f005af8187ac510b1b92b58374dc801e989d6014 Mon Sep 17 00:00:00 2001 From: Falk Woldmann <52786457+FalkWoldmann@users.noreply.github.com> Date: Fri, 25 Apr 2025 09:44:42 +0200 Subject: [PATCH 070/148] Replace `once_cell` with `std::sync::LazyLock` (#776) --- Cargo.lock | 3 --- sentry-backtrace/Cargo.toml | 1 - sentry-backtrace/src/parse.rs | 5 +++-- sentry-backtrace/src/utils.rs | 11 +++++------ sentry-core/Cargo.toml | 1 - sentry-core/src/constants.rs | 4 ++-- sentry-core/src/hub_impl.rs | 6 ++---- sentry-core/src/test.rs | 7 +++---- sentry-debug-images/Cargo.toml | 1 - sentry-debug-images/src/integration.rs | 4 ++-- 10 files changed, 17 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 58e0fae16..5640f5d79 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3184,7 +3184,6 @@ name = "sentry-backtrace" version = "0.37.0" dependencies = [ "backtrace", - "once_cell", "regex", "sentry-core", ] @@ -3212,7 +3211,6 @@ dependencies = [ "criterion", "futures", "log", - "once_cell", "rand 0.9.0", "rayon", "regex", @@ -3230,7 +3228,6 @@ name = "sentry-debug-images" version = "0.37.0" dependencies = [ "findshlibs", - "once_cell", "sentry-core", ] diff --git a/sentry-backtrace/Cargo.toml b/sentry-backtrace/Cargo.toml index a3f58eb9e..30c9a63aa 100644 --- a/sentry-backtrace/Cargo.toml +++ b/sentry-backtrace/Cargo.toml @@ -14,7 +14,6 @@ rust-version = "1.81" [dependencies] backtrace = "0.3.44" -once_cell = "1" regex = { version = "1.5.5", default-features = false, features = [ "std", "unicode-perl", diff --git a/sentry-backtrace/src/parse.rs b/sentry-backtrace/src/parse.rs index 03f3df892..f2e82fc03 100644 --- a/sentry-backtrace/src/parse.rs +++ b/sentry-backtrace/src/parse.rs @@ -1,10 +1,11 @@ -use once_cell::sync::Lazy; +use std::sync::LazyLock; + use regex::Regex; use crate::utils::{demangle_symbol, filename, strip_symbol}; use crate::{Frame, Stacktrace}; -static FRAME_RE: Lazy = Lazy::new(|| { +static FRAME_RE: LazyLock = LazyLock::new(|| { Regex::new( r#"(?xm) ^ diff --git a/sentry-backtrace/src/utils.rs b/sentry-backtrace/src/utils.rs index f638eed45..fa8b04400 100644 --- a/sentry-backtrace/src/utils.rs +++ b/sentry-backtrace/src/utils.rs @@ -1,9 +1,8 @@ -use std::borrow::Cow; +use std::{borrow::Cow, sync::LazyLock}; -use once_cell::sync::Lazy; use regex::{Captures, Regex}; -static HASH_FUNC_RE: Lazy = Lazy::new(|| { +static HASH_FUNC_RE: LazyLock = LazyLock::new(|| { Regex::new( r#"(?x) ^(.*)::h[a-f0-9]{16}$ @@ -12,7 +11,7 @@ static HASH_FUNC_RE: Lazy = Lazy::new(|| { .unwrap() }); -static CRATE_HASH_RE: Lazy = Lazy::new(|| { +static CRATE_HASH_RE: LazyLock = LazyLock::new(|| { Regex::new( r"(?x) \b(\[[a-f0-9]{16}\]) @@ -21,7 +20,7 @@ static CRATE_HASH_RE: Lazy = Lazy::new(|| { .unwrap() }); -static CRATE_RE: Lazy = Lazy::new(|| { +static CRATE_RE: LazyLock = LazyLock::new(|| { Regex::new( r"(?x) ^ @@ -34,7 +33,7 @@ static CRATE_RE: Lazy = Lazy::new(|| { .unwrap() }); -static COMMON_RUST_SYMBOL_ESCAPES_RE: Lazy = Lazy::new(|| { +static COMMON_RUST_SYMBOL_ESCAPES_RE: LazyLock = LazyLock::new(|| { Regex::new( r"(?x) \$ diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index 09b4574bf..4c101ea25 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -32,7 +32,6 @@ release-health = [] cadence = { version = "1.4.0", optional = true } crc32fast = { version = "1.4.0", optional = true } log = { version = "0.4.8", optional = true, features = ["std"] } -once_cell = "1" rand = { version = "0.9.0", optional = true } regex = { version = "1.7.3", optional = true } sentry-types = { version = "0.37.0", path = "../sentry-types" } diff --git a/sentry-core/src/constants.rs b/sentry-core/src/constants.rs index f33a606b4..d2ce87fb2 100644 --- a/sentry-core/src/constants.rs +++ b/sentry-core/src/constants.rs @@ -1,7 +1,7 @@ // Not all constants are used when building without the "client" feature #![allow(dead_code)] -use once_cell::sync::Lazy; +use std::sync::LazyLock; use crate::protocol::{ClientSdkInfo, ClientSdkPackage}; @@ -9,7 +9,7 @@ use crate::protocol::{ClientSdkInfo, ClientSdkPackage}; const VERSION: &str = env!("CARGO_PKG_VERSION"); pub(crate) const USER_AGENT: &str = concat!("sentry.rust/", env!("CARGO_PKG_VERSION")); -pub(crate) static SDK_INFO: Lazy = Lazy::new(|| ClientSdkInfo { +pub(crate) static SDK_INFO: LazyLock = LazyLock::new(|| ClientSdkInfo { name: "sentry.rust".into(), version: VERSION.into(), packages: vec![ClientSdkPackage { diff --git a/sentry-core/src/hub_impl.rs b/sentry-core/src/hub_impl.rs index 42d1fa6b3..5786daa36 100644 --- a/sentry-core/src/hub_impl.rs +++ b/sentry-core/src/hub_impl.rs @@ -1,13 +1,11 @@ use std::cell::{Cell, UnsafeCell}; -use std::sync::{Arc, PoisonError, RwLock}; +use std::sync::{Arc, LazyLock, PoisonError, RwLock}; use std::thread; use crate::Scope; use crate::{scope::Stack, Client, Hub}; -use once_cell::sync::Lazy; - -static PROCESS_HUB: Lazy<(Arc, thread::ThreadId)> = Lazy::new(|| { +static PROCESS_HUB: LazyLock<(Arc, thread::ThreadId)> = LazyLock::new(|| { ( Arc::new(Hub::new(None, Arc::new(Default::default()))), thread::current().id(), diff --git a/sentry-core/src/test.rs b/sentry-core/src/test.rs index ed92c1c48..a2e150f8e 100644 --- a/sentry-core/src/test.rs +++ b/sentry-core/src/test.rs @@ -19,15 +19,14 @@ //! assert_eq!(events[0].message.as_ref().unwrap(), "Hello World!"); //! ``` -use std::sync::{Arc, Mutex}; - -use once_cell::sync::Lazy; +use std::sync::{Arc, LazyLock, Mutex}; use crate::protocol::Event; use crate::types::Dsn; use crate::{ClientOptions, Envelope, Hub, Transport}; -static TEST_DSN: Lazy = Lazy::new(|| "https://public@sentry.invalid/1".parse().unwrap()); +static TEST_DSN: LazyLock = + LazyLock::new(|| "https://public@sentry.invalid/1".parse().unwrap()); /// Collects events instead of sending them. /// diff --git a/sentry-debug-images/Cargo.toml b/sentry-debug-images/Cargo.toml index 7f4df4c28..035dcc57f 100644 --- a/sentry-debug-images/Cargo.toml +++ b/sentry-debug-images/Cargo.toml @@ -14,5 +14,4 @@ rust-version = "1.81" [dependencies] findshlibs = "=0.10.2" -once_cell = "1" sentry-core = { version = "0.37.0", path = "../sentry-core" } diff --git a/sentry-debug-images/src/integration.rs b/sentry-debug-images/src/integration.rs index 2a60e1713..0039045ca 100644 --- a/sentry-debug-images/src/integration.rs +++ b/sentry-debug-images/src/integration.rs @@ -1,6 +1,6 @@ use std::borrow::Cow; +use std::sync::LazyLock; -use once_cell::sync::Lazy; use sentry_core::protocol::{DebugMeta, Event}; use sentry_core::{ClientOptions, Integration}; @@ -56,7 +56,7 @@ impl Integration for DebugImagesIntegration { mut event: Event<'static>, _opts: &ClientOptions, ) -> Option> { - static DEBUG_META: Lazy = Lazy::new(|| DebugMeta { + static DEBUG_META: LazyLock = LazyLock::new(|| DebugMeta { images: crate::debug_images(), ..Default::default() }); From 4db8c35173437c6866881b37eabc2bccd435ad0f Mon Sep 17 00:00:00 2001 From: Stephanie Anderson Date: Mon, 28 Apr 2025 11:27:18 +0200 Subject: [PATCH 071/148] chore: update GH issue templates for Linear compatibility (#777) --- .github/ISSUE_TEMPLATE/01-feature.yml | 30 +++++++++++++ .github/ISSUE_TEMPLATE/02-improvement.yml | 30 +++++++++++++ .github/ISSUE_TEMPLATE/03-bug.yml | 51 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/config.yml | 5 +++ 4 files changed, 116 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/01-feature.yml create mode 100644 .github/ISSUE_TEMPLATE/02-improvement.yml create mode 100644 .github/ISSUE_TEMPLATE/03-bug.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml diff --git a/.github/ISSUE_TEMPLATE/01-feature.yml b/.github/ISSUE_TEMPLATE/01-feature.yml new file mode 100644 index 000000000..210af979e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/01-feature.yml @@ -0,0 +1,30 @@ +name: 💡 Feature Request +description: Propose new functionality for the SDK +labels: ["Rust", "Feature"] +body: + - type: markdown + attributes: + value: Thanks for taking the time to file a feature request! Please fill out this form as completely as possible. + - type: textarea + id: problem + attributes: + label: Problem Statement + description: A clear and concise description of what you want and what your use case is. + placeholder: |- + I want to make whirled peas, but Sentry doesn't blend. + validations: + required: true + - type: textarea + id: expected + attributes: + label: Solution Brainstorm + description: We know you have bright ideas to share ... share away, friend. + placeholder: |- + Add a blender to Sentry. + validations: + required: true + - type: markdown + attributes: + value: |- + ## Thanks 🙏 + Check our [triage docs](https://open.sentry.io/triage/) for what to expect next. diff --git a/.github/ISSUE_TEMPLATE/02-improvement.yml b/.github/ISSUE_TEMPLATE/02-improvement.yml new file mode 100644 index 000000000..3e4ac56c0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/02-improvement.yml @@ -0,0 +1,30 @@ +name: 💡 Improvement +description: Propose an improvement for existing functionality of the SDK +labels: ["Rust", "Improvement"] +body: + - type: markdown + attributes: + value: Thanks for taking the time to file a request! Please fill out this form as completely as possible. + - type: textarea + id: problem + attributes: + label: Problem Statement + description: A clear and concise description of what you want and what your use case is. + placeholder: |- + I want to make whirled peas, but Sentry doesn't blend. + validations: + required: true + - type: textarea + id: expected + attributes: + label: Solution Brainstorm + description: We know you have bright ideas to share ... share away, friend. + placeholder: |- + Add a blender to Sentry. + validations: + required: true + - type: markdown + attributes: + value: |- + ## Thanks 🙏 + Check our [triage docs](https://open.sentry.io/triage/) for what to expect next. diff --git a/.github/ISSUE_TEMPLATE/03-bug.yml b/.github/ISSUE_TEMPLATE/03-bug.yml new file mode 100644 index 000000000..b9ba538dc --- /dev/null +++ b/.github/ISSUE_TEMPLATE/03-bug.yml @@ -0,0 +1,51 @@ +name: 🐞 Bug Report +description: Tell us about something that's not working the way we (probably) intend. +labels: ["Rust", "Bug"] +body: + - type: dropdown + id: type + attributes: + label: How do you use Sentry? + options: + - Sentry SaaS (sentry.io) + - Self-hosted / on-premises + validations: + required: true + - type: input + id: version + attributes: + label: SDK version + description: Which SDK version do you use? + placeholder: e.g. 4.9.2 + validations: + required: true + - type: textarea + id: repro + attributes: + label: Steps to reproduce + description: How can we see what you're seeing? Specific is terrific. + placeholder: |- + 1. What + 2. you + 3. did. + validations: + required: true + - type: textarea + id: expected + attributes: + label: Expected result + validations: + required: true + - type: textarea + id: actual + attributes: + label: Actual result + description: Logs? Screenshots? Yes, please. + validations: + required: true + - type: markdown + attributes: + value: |- + ## Thanks 🙏 + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..17d8a34dc --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: Support Request + url: https://sentry.io/support + about: Use our dedicated support channel for paid accounts. From 28f47d360413afdfe4039cabd575089b4262bd13 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Mon, 28 Apr 2025 11:54:48 +0200 Subject: [PATCH 072/148] refactor(debug-images): force init `DEBUG_META` on integration init (#773) * refactor(debug-images): force init `DebugMeta` immediately * import --- sentry-debug-images/src/integration.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sentry-debug-images/src/integration.rs b/sentry-debug-images/src/integration.rs index 0039045ca..780304973 100644 --- a/sentry-debug-images/src/integration.rs +++ b/sentry-debug-images/src/integration.rs @@ -4,6 +4,11 @@ use std::sync::LazyLock; use sentry_core::protocol::{DebugMeta, Event}; use sentry_core::{ClientOptions, Integration}; +static DEBUG_META: LazyLock = LazyLock::new(|| DebugMeta { + images: crate::debug_images(), + ..Default::default() +}); + /// The Sentry Debug Images Integration. pub struct DebugImagesIntegration { filter: Box) -> bool + Send + Sync>, @@ -30,6 +35,7 @@ impl DebugImagesIntegration { impl Default for DebugImagesIntegration { fn default() -> Self { + LazyLock::force(&DEBUG_META); Self { filter: Box::new(|_| true), } @@ -56,11 +62,6 @@ impl Integration for DebugImagesIntegration { mut event: Event<'static>, _opts: &ClientOptions, ) -> Option> { - static DEBUG_META: LazyLock = LazyLock::new(|| DebugMeta { - images: crate::debug_images(), - ..Default::default() - }); - if event.debug_meta.is_empty() && (self.filter)(&event) { event.debug_meta = Cow::Borrowed(&DEBUG_META); } From 4028856949f74500e7665cb73d06f78be56caf90 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Tue, 29 Apr 2025 15:40:04 +0200 Subject: [PATCH 073/148] chore: update issue templates with blank issue and Discord link (#778) --- .github/ISSUE_TEMPLATE/04-blank.yml | 11 +++++++++++ .github/ISSUE_TEMPLATE/config.yml | 4 ++++ 2 files changed, 15 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/04-blank.yml diff --git a/.github/ISSUE_TEMPLATE/04-blank.yml b/.github/ISSUE_TEMPLATE/04-blank.yml new file mode 100644 index 000000000..544fe60f5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/04-blank.yml @@ -0,0 +1,11 @@ +name: Blank Issue +description: Blank Issue. Reserved for maintainers. +labels: ["Rust"] +body: + - type: textarea + id: description + attributes: + label: Description + description: Please describe the issue. + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 17d8a34dc..ec915930a 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,5 +1,9 @@ blank_issues_enabled: false contact_links: + - name: Join Sentry Discord + url: https://discord.com/invite/sentry + about: A place to talk about SDK development and other Sentry related topics. It's not meant as a support channel. - name: Support Request url: https://sentry.io/support about: Use our dedicated support channel for paid accounts. + From f34aa3ea3234e2989ffd9e7d04295adbc025caaf Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Wed, 30 Apr 2025 18:57:32 +0200 Subject: [PATCH 074/148] refactor(core): fail with message if TLS backend not available (#784) --- sentry/src/transports/reqwest.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sentry/src/transports/reqwest.rs b/sentry/src/transports/reqwest.rs index 8e79896f0..9e21364a0 100644 --- a/sentry/src/transports/reqwest.rs +++ b/sentry/src/transports/reqwest.rs @@ -53,7 +53,9 @@ impl ReqwestHttpTransport { } } }; - builder.build().unwrap() + builder + .build() + .expect("Failed to build `reqwest` client as a TLS backend is not available. Enable either the `native-tls` or the `rustls` feature of the `sentry` crate.") }); let dsn = options.dsn.as_ref().unwrap(); let user_agent = options.user_agent.clone(); From 3cc461a279d5a6ac45ea73268344d01318d8719e Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Wed, 7 May 2025 15:39:17 +0200 Subject: [PATCH 075/148] feat(otel): add OpenTelemetry SpanProcessor, Propagator, Extractor (#779) * feat(otel): add OpenTelemetry SpanProcessor, Propagator, Extractor * update * set kind on transaction as well * replace unknown span op with empty string * replace empty op with description * try serializing tests * on test init, close existing client if any * remove useless line * address comments * simplify logic and capture span attributes * fix tests * restructure tests * clippy * Update shared.rs * Update shared.rs * address comments * move comment * nit * fix test warnings --- Cargo.lock | 51 ++++ sentry-core/src/performance.rs | 255 ++++++++++++++++-- sentry-opentelemetry/Cargo.toml | 37 +++ sentry-opentelemetry/src/converters.rs | 56 ++++ sentry-opentelemetry/src/lib.rs | 51 ++++ sentry-opentelemetry/src/processor.rs | 187 +++++++++++++ sentry-opentelemetry/src/propagator.rs | 82 ++++++ .../tests/associates_event_with_span.rs | 83 ++++++ .../tests/captures_transaction.rs | 42 +++ .../captures_transaction_with_nested_spans.rs | 72 +++++ .../tests/creates_distributed_trace.rs | 121 +++++++++ sentry-opentelemetry/tests/shared.rs | 21 ++ sentry-types/src/protocol/v7.rs | 48 +++- sentry/Cargo.toml | 2 + sentry/src/lib.rs | 4 + 15 files changed, 1085 insertions(+), 27 deletions(-) create mode 100644 sentry-opentelemetry/Cargo.toml create mode 100644 sentry-opentelemetry/src/converters.rs create mode 100644 sentry-opentelemetry/src/lib.rs create mode 100644 sentry-opentelemetry/src/processor.rs create mode 100644 sentry-opentelemetry/src/propagator.rs create mode 100644 sentry-opentelemetry/tests/associates_event_with_span.rs create mode 100644 sentry-opentelemetry/tests/captures_transaction.rs create mode 100644 sentry-opentelemetry/tests/captures_transaction_with_nested_spans.rs create mode 100644 sentry-opentelemetry/tests/creates_distributed_trace.rs create mode 100644 sentry-opentelemetry/tests/shared.rs diff --git a/Cargo.lock b/Cargo.lock index 5640f5d79..655d6a95c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2447,6 +2447,45 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "opentelemetry" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e87237e2775f74896f9ad219d26a2081751187eb7c9f5c58dde20a23b95d16c" +dependencies = [ + "futures-core", + "futures-sink", + "js-sys", + "pin-project-lite", + "thiserror 2.0.12", + "tracing", +] + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84b29a9f89f1a954936d5aa92f19b2feec3c8f3971d3e96206640db7f9706ae3" + +[[package]] +name = "opentelemetry_sdk" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afdefb21d1d47394abc1ba6c57363ab141be19e27cc70d0e422b7f303e4d290b" +dependencies = [ + "futures-channel", + "futures-executor", + "futures-util", + "glob", + "opentelemetry", + "percent-encoding", + "rand 0.9.0", + "serde_json", + "thiserror 2.0.12", + "tokio", + "tokio-stream", +] + [[package]] name = "os_info" version = "3.10.0" @@ -3141,6 +3180,7 @@ dependencies = [ "sentry-core", "sentry-debug-images", "sentry-log", + "sentry-opentelemetry", "sentry-panic", "sentry-slog", "sentry-tower", @@ -3241,6 +3281,17 @@ dependencies = [ "sentry-core", ] +[[package]] +name = "sentry-opentelemetry" +version = "0.37.0" +dependencies = [ + "opentelemetry", + "opentelemetry-semantic-conventions", + "opentelemetry_sdk", + "sentry", + "sentry-core", +] + [[package]] name = "sentry-panic" version = "0.37.0" diff --git a/sentry-core/src/performance.rs b/sentry-core/src/performance.rs index 740cd0ba2..43ccd6a49 100644 --- a/sentry-core/src/performance.rs +++ b/sentry-core/src/performance.rs @@ -2,6 +2,9 @@ use std::borrow::Cow; use std::collections::BTreeMap; use std::ops::{Deref, DerefMut}; use std::sync::{Arc, Mutex, MutexGuard}; +use std::time::SystemTime; + +use sentry_types::protocol::v7::SpanId; use crate::{protocol, Hub}; @@ -31,6 +34,23 @@ pub fn start_transaction(ctx: TransactionContext) -> Transaction { } } +/// Start a new Performance Monitoring Transaction with the provided start timestamp. +/// +/// The transaction needs to be explicitly finished via [`Transaction::finish`], +/// otherwise it will be discarded. +/// The transaction itself also represents the root span in the span hierarchy. +/// Child spans can be started with the [`Transaction::start_child`] method. +pub fn start_transaction_with_timestamp( + ctx: TransactionContext, + timestamp: SystemTime, +) -> Transaction { + let transaction = start_transaction(ctx); + if let Some(tx) = transaction.inner.lock().unwrap().transaction.as_mut() { + tx.start_timestamp = timestamp; + } + transaction +} + // Hub API: impl Hub { @@ -47,6 +67,21 @@ impl Hub { Transaction::new_noop(ctx) } } + + /// Start a new Performance Monitoring Transaction with the provided start timestamp. + /// + /// See the global [`start_transaction_with_timestamp`] for more documentation. + pub fn start_transaction_with_timestamp( + &self, + ctx: TransactionContext, + timestamp: SystemTime, + ) -> Transaction { + let transaction = start_transaction(ctx); + if let Some(tx) = transaction.inner.lock().unwrap().transaction.as_mut() { + tx.start_timestamp = timestamp; + } + transaction + } } // "Context" Types: @@ -110,6 +145,29 @@ impl TransactionContext { } } + /// Creates a new Transaction Context with the given `name`, `op`, `trace_id`, and + /// possibly the given `span_id` and `parent_span_id`. + /// + /// See + /// for an explanation of a Transaction's `name`, and + /// for conventions + /// around an `operation`'s value. + #[must_use = "this must be used with `start_transaction`"] + pub fn new_with_details( + name: &str, + op: &str, + trace_id: protocol::TraceId, + span_id: Option, + parent_span_id: Option, + ) -> Self { + let mut slf = Self::new_with_trace_id(name, op, trace_id); + if let Some(span_id) = span_id { + slf.span_id = span_id; + } + slf.parent_span_id = parent_span_id; + slf + } + /// Creates a new Transaction Context based on the distributed tracing `headers`. /// /// The `headers` in particular need to include either the `sentry-trace` or W3C @@ -121,23 +179,23 @@ impl TransactionContext { op: &str, headers: I, ) -> Self { - let mut trace = None; - for (k, v) in headers.into_iter() { - if k.eq_ignore_ascii_case("sentry-trace") { - trace = parse_sentry_trace(v); - break; - } - - if k.eq_ignore_ascii_case("traceparent") { - trace = parse_w3c_traceparent(v); - } - } - - let (trace_id, parent_span_id, sampled) = match trace { - Some(trace) => (trace.0, Some(trace.1), trace.2), - None => (protocol::TraceId::default(), None, None), - }; - + parse_headers(headers) + .map(|sentry_trace| Self::continue_from_sentry_trace(name, op, &sentry_trace)) + .unwrap_or_else(|| Self { + name: name.into(), + op: op.into(), + trace_id: Default::default(), + parent_span_id: None, + span_id: Default::default(), + sampled: None, + custom: None, + }) + } + + /// Creates a new Transaction Context based on the provided distributed tracing data. + pub fn continue_from_sentry_trace(name: &str, op: &str, sentry_trace: &SentryTrace) -> Self { + let (trace_id, parent_span_id, sampled) = + (sentry_trace.0, Some(sentry_trace.1), sentry_trace.2); Self { name: name.into(), op: op.into(), @@ -440,6 +498,28 @@ impl TransactionOrSpan { } } + /// Starts a new child Span with the given `op`, `description` and `id`. + /// + /// The span must be explicitly finished via [`Span::finish`], as it will + /// otherwise not be sent to Sentry. + #[must_use = "a span must be explicitly closed via `finish()`"] + pub fn start_child_with_details( + &self, + op: &str, + description: &str, + id: SpanId, + timestamp: SystemTime, + ) -> Span { + match self { + TransactionOrSpan::Transaction(transaction) => { + transaction.start_child_with_details(op, description, id, timestamp) + } + TransactionOrSpan::Span(span) => { + span.start_child_with_details(op, description, id, timestamp) + } + } + } + #[cfg(feature = "client")] pub(crate) fn apply_to_event(&self, event: &mut protocol::Event<'_>) { if event.contexts.contains_key("trace") { @@ -462,10 +542,23 @@ impl TransactionOrSpan { event.contexts.insert("trace".into(), context.into()); } - /// Finishes the Transaction/Span. + /// Finishes the Transaction/Span with the provided end timestamp. /// /// This records the end timestamp and either sends the inner [`Transaction`] /// directly to Sentry, or adds the [`Span`] to its transaction. + pub fn finish_with_timestamp(self, timestamp: SystemTime) { + match self { + TransactionOrSpan::Transaction(transaction) => { + transaction.finish_with_timestamp(timestamp) + } + TransactionOrSpan::Span(span) => span.finish_with_timestamp(timestamp), + } + } + + /// Finishes the Transaction/Span. + /// + /// This records the current timestamp as the end timestamp and either sends the inner [`Transaction`] + /// directly to Sentry, or adds the [`Span`] to its transaction. pub fn finish(self) { match self { TransactionOrSpan::Transaction(transaction) => transaction.finish(), @@ -693,11 +786,11 @@ impl Transaction { self.inner.lock().unwrap().sampled } - /// Finishes the Transaction. + /// Finishes the Transaction with the provided end timestamp. /// /// This records the end timestamp and sends the transaction together with /// all finished child spans to Sentry. - pub fn finish(self) { + pub fn finish_with_timestamp(self, _timestamp: SystemTime) { with_client_impl! {{ let mut inner = self.inner.lock().unwrap(); @@ -708,7 +801,7 @@ impl Transaction { if let Some(mut transaction) = inner.transaction.take() { if let Some(client) = inner.client.take() { - transaction.finish(); + transaction.finish_with_timestamp(_timestamp); transaction .contexts .insert("trace".into(), inner.context.clone().into()); @@ -731,6 +824,14 @@ impl Transaction { }} } + /// Finishes the Transaction. + /// + /// This records the current timestamp as the end timestamp and sends the transaction together with + /// all finished child spans to Sentry. + pub fn finish(self) { + self.finish_with_timestamp(SystemTime::now()); + } + /// Starts a new child Span with the given `op` and `description`. /// /// The span must be explicitly finished via [`Span::finish`]. @@ -754,6 +855,38 @@ impl Transaction { span: Arc::new(Mutex::new(span)), } } + + /// Starts a new child Span with the given `op` and `description`. + /// + /// The span must be explicitly finished via [`Span::finish`]. + #[must_use = "a span must be explicitly closed via `finish()`"] + pub fn start_child_with_details( + &self, + op: &str, + description: &str, + id: SpanId, + timestamp: SystemTime, + ) -> Span { + let inner = self.inner.lock().unwrap(); + let span = protocol::Span { + trace_id: inner.context.trace_id, + parent_span_id: Some(inner.context.span_id), + op: Some(op.into()), + description: if description.is_empty() { + None + } else { + Some(description.into()) + }, + span_id: id, + start_timestamp: timestamp, + ..Default::default() + }; + Span { + transaction: Arc::clone(&self.inner), + sampled: inner.sampled, + span: Arc::new(Mutex::new(span)), + } + } } /// A smart pointer to a span's [`data` field](protocol::Span::data). @@ -901,18 +1034,18 @@ impl Span { self.sampled } - /// Finishes the Span. + /// Finishes the Span with the provided end timestamp. /// /// This will record the end timestamp and add the span to the transaction /// in which it was started. - pub fn finish(self) { + pub fn finish_with_timestamp(self, _timestamp: SystemTime) { with_client_impl! {{ let mut span = self.span.lock().unwrap(); if span.timestamp.is_some() { // the span was already finished return; } - span.finish(); + span.finish_with_timestamp(_timestamp); let mut inner = self.transaction.lock().unwrap(); if let Some(transaction) = inner.transaction.as_mut() { if transaction.spans.len() <= MAX_SPANS { @@ -922,6 +1055,14 @@ impl Span { }} } + /// Finishes the Span. + /// + /// This will record the current timestamp as the end timestamp and add the span to the + /// transaction in which it was started. + pub fn finish(self) { + self.finish_with_timestamp(SystemTime::now()); + } + /// Starts a new child Span with the given `op` and `description`. /// /// The span must be explicitly finished via [`Span::finish`]. @@ -945,6 +1086,38 @@ impl Span { span: Arc::new(Mutex::new(span)), } } + + /// Starts a new child Span with the given `op` and `description`. + /// + /// The span must be explicitly finished via [`Span::finish`]. + #[must_use = "a span must be explicitly closed via `finish()`"] + fn start_child_with_details( + &self, + op: &str, + description: &str, + id: SpanId, + timestamp: SystemTime, + ) -> Span { + let span = self.span.lock().unwrap(); + let span = protocol::Span { + trace_id: span.trace_id, + parent_span_id: Some(span.span_id), + op: Some(op.into()), + description: if description.is_empty() { + None + } else { + Some(description.into()) + }, + span_id: id, + start_timestamp: timestamp, + ..Default::default() + }; + Span { + transaction: self.transaction.clone(), + sampled: self.sampled, + span: Arc::new(Mutex::new(span)), + } + } } /// An Iterator over HTTP header names and values needed for distributed tracing. @@ -963,8 +1136,21 @@ impl Iterator for TraceHeadersIter { } } +/// A container for distributed tracing metadata that can be extracted from e.g. HTTP headers such as +/// `sentry-trace` and `traceparent`. #[derive(Debug, PartialEq)] -struct SentryTrace(protocol::TraceId, protocol::SpanId, Option); +pub struct SentryTrace(protocol::TraceId, protocol::SpanId, Option); + +impl SentryTrace { + /// Creates a new [`SentryTrace`] from the provided parameters + pub fn new( + trace_id: protocol::TraceId, + span_id: protocol::SpanId, + sampled: Option, + ) -> Self { + SentryTrace(trace_id, span_id, sampled) + } +} fn parse_sentry_trace(header: &str) -> Option { let header = header.trim(); @@ -998,6 +1184,25 @@ fn parse_w3c_traceparent(header: &str) -> Option { Some(SentryTrace(trace_id, parent_span_id, parent_sampled)) } +/// Extracts distributed tracing metadata from headers (or, generally, key-value pairs), +/// considering the values for both `sentry-trace` (prioritized) and `traceparent`. +pub fn parse_headers<'a, I: IntoIterator>( + headers: I, +) -> Option { + let mut trace = None; + for (k, v) in headers.into_iter() { + if k.eq_ignore_ascii_case("sentry-trace") { + trace = parse_sentry_trace(v); + break; + } + + if k.eq_ignore_ascii_case("traceparent") { + trace = parse_w3c_traceparent(v); + } + } + trace +} + impl std::fmt::Display for SentryTrace { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}-{}", self.0, self.1)?; diff --git a/sentry-opentelemetry/Cargo.toml b/sentry-opentelemetry/Cargo.toml new file mode 100644 index 000000000..9f889dc25 --- /dev/null +++ b/sentry-opentelemetry/Cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "sentry-opentelemetry" +version = "0.37.0" +authors = ["Sentry "] +license = "MIT" +readme = "README.md" +repository = "https://github.com/getsentry/sentry-rust" +homepage = "https://sentry.io/welcome/" +description = """ +Sentry integration for OpenTelemetry. +""" +edition = "2021" +rust-version = "1.81" + +[package.metadata.docs.rs] +all-features = true + +[dependencies] +sentry-core = { version = "0.37.0", path = "../sentry-core", features = [ + "client", + "release-health" +] } +opentelemetry = { version = "0.29.0", default-features = false } +opentelemetry_sdk = { version = "0.29.0", default-features = false, features = [ + "trace", +] } +opentelemetry-semantic-conventions = "0.29.0" + +[dev-dependencies] +sentry = { version = "0.37.0", path = "../sentry", features = ["test"] } +sentry-core = { version = "0.37.0", path = "../sentry-core", features = [ + "test", +] } +opentelemetry_sdk = { version = "0.29.0", default-features = false, features = [ + "trace", + "testing", +] } diff --git a/sentry-opentelemetry/src/converters.rs b/sentry-opentelemetry/src/converters.rs new file mode 100644 index 000000000..0f6645142 --- /dev/null +++ b/sentry-opentelemetry/src/converters.rs @@ -0,0 +1,56 @@ +use sentry_core::protocol::{value::Number, SpanId, SpanStatus, TraceId, Value}; + +pub(crate) fn convert_span_id(span_id: &opentelemetry::SpanId) -> SpanId { + span_id.to_bytes().into() +} + +pub(crate) fn convert_trace_id(trace_id: &opentelemetry::TraceId) -> TraceId { + trace_id.to_bytes().into() +} + +pub(crate) fn convert_span_status(status: &opentelemetry::trace::Status) -> SpanStatus { + match status { + opentelemetry::trace::Status::Unset | opentelemetry::trace::Status::Ok => SpanStatus::Ok, + opentelemetry::trace::Status::Error { description } => { + description.parse().unwrap_or(SpanStatus::UnknownError) + } + } +} + +pub(crate) fn convert_span_kind(kind: opentelemetry::trace::SpanKind) -> Value { + format!("{:?}", kind).to_lowercase().into() +} + +pub(crate) fn convert_value(value: opentelemetry::Value) -> Value { + match value { + opentelemetry::Value::Bool(x) => Value::Bool(x), + opentelemetry::Value::I64(x) => Value::Number(x.into()), + opentelemetry::Value::F64(x) => Number::from_f64(x) + .map(Value::Number) + .unwrap_or(Value::Null), + opentelemetry::Value::String(x) => Value::String(x.into()), + opentelemetry::Value::Array(arr) => match arr { + opentelemetry::Array::Bool(items) => { + Value::Array(items.iter().map(|x| Value::Bool(*x)).collect()) + } + opentelemetry::Array::I64(items) => Value::Array( + items + .iter() + .map(|x| Value::Number(Number::from(*x))) + .collect(), + ), + opentelemetry::Array::F64(items) => Value::Array( + items + .iter() + .filter_map(|x| Number::from_f64(*x)) + .map(Value::Number) + .collect(), + ), + opentelemetry::Array::String(items) => { + Value::Array(items.iter().map(|x| x.as_str().into()).collect()) + } + _ => Value::Null, // non-exhaustive + }, + _ => Value::Null, // non-exhaustive + } +} diff --git a/sentry-opentelemetry/src/lib.rs b/sentry-opentelemetry/src/lib.rs new file mode 100644 index 000000000..d9de713ba --- /dev/null +++ b/sentry-opentelemetry/src/lib.rs @@ -0,0 +1,51 @@ +//! OpenTelemetry support for Sentry. +//! +//! This integration allows you to capture spans from your existing OpenTelemetry setup and send +//! them to Sentry, with support for distributed tracing. +//! It's assumed that only the [OpenTelemetry tracing +//! API](https://opentelemetry.io/docs/specs/otel/trace/api/) is used to start/end/modify Spans. +//! Mixing it with the Sentry tracing API (e.g. `sentry_core::start_transaction(ctx)`) will not +//! work, as the spans created with the two methods will not be nested properly. +//! Capturing events (either manually with e.g. `sentry::capture_event`, or automatically with e.g. the +//! `sentry-panic` integration) will send them to Sentry with the correct trace and span +//! association. +//! +//! # Configuration +//! +//! Initialize Sentry, then register the [`SentryPropagator`] and the [`SentrySpanProcessor`]: +//! +//! ``` +//! use opentelemetry::{global}; +//! use opentelemetry_sdk::{ +//! propagation::TraceContextPropagator, trace::SdkTracerProvider, +//! }; +//! +//! // Initialize the Sentry SDK +//! let _guard = sentry::init(sentry::ClientOptions { +//! // Enable capturing of traces; set this a to lower value in production. +//! // For more sophisticated behavior use a custom +//! // [`sentry::ClientOptions::traces_sampler`] instead. +//! // That's the equivalent of a tail sampling processor in OpenTelemetry. +//! // These options will only affect sampling of the spans that are sent to Sentry, +//! // not of the underlying OpenTelemetry spans. +//! traces_sample_rate: 1.0, +//! ..sentry::ClientOptions::default() +//! }); +//! +//! // Register the Sentry propagator to enable distributed tracing +//! global::set_text_map_propagator(sentry_opentelemetry::SentryPropagator::new()); +//! +//! let tracer_provider = SdkTracerProvider::builder() +//! // Register the Sentry span processor to send OpenTelemetry spans to Sentry +//! .with_span_processor(sentry_opentelemetry::SentrySpanProcessor::new()) +//! .build(); +//! +//! global::set_tracer_provider(tracer_provider); +//! ``` + +mod converters; +mod processor; +mod propagator; + +pub use processor::*; +pub use propagator::*; diff --git a/sentry-opentelemetry/src/processor.rs b/sentry-opentelemetry/src/processor.rs new file mode 100644 index 000000000..d1a273380 --- /dev/null +++ b/sentry-opentelemetry/src/processor.rs @@ -0,0 +1,187 @@ +//! An OpenTelemetry [SpanProcessor](https://opentelemetry.io/docs/specs/otel/trace/sdk/#span-processor) for Sentry. +//! +//! [`SentrySpanProcessor`] allows the Sentry Rust SDK to integrate with OpenTelemetry. +//! It transforms OpenTelemetry spans into Sentry transactions/spans and sends them to Sentry. +//! +//! # Configuration +//! +//! Unless you have no need for distributed tracing, this should be used together with [`crate::propagator::SentryPropagator`]. An example of +//! setting up both is provided in the [crate-level documentation](../). + +use std::collections::HashMap; +use std::sync::{Arc, Mutex}; +use std::time::SystemTime; + +use opentelemetry::global::ObjectSafeSpan; +use opentelemetry::trace::{get_active_span, SpanId}; +use opentelemetry::Context; +use opentelemetry_sdk::error::OTelSdkResult; +use opentelemetry_sdk::trace::{Span, SpanData, SpanProcessor}; + +use opentelemetry_sdk::Resource; +use sentry_core::SentryTrace; +use sentry_core::{TransactionContext, TransactionOrSpan}; + +use crate::converters::{ + convert_span_id, convert_span_kind, convert_span_status, convert_trace_id, convert_value, +}; + +/// A mapping from Sentry span IDs to Sentry spans/transactions. +/// Sentry spans are created with the same SpanId as the corresponding OTEL span, so this is used +/// to track OTEL spans across start/end calls. +type SpanMap = Arc>>; + +/// An OpenTelemetry SpanProcessor that converts OTEL spans to Sentry spans/transactions and sends +/// them to Sentry. +#[derive(Debug, Clone)] +pub struct SentrySpanProcessor { + span_map: SpanMap, +} + +impl SentrySpanProcessor { + /// Creates a new `SentrySpanProcessor`. + pub fn new() -> Self { + sentry_core::configure_scope(|scope| { + // Associate Sentry events with the correct span and trace. + // This works as long as all Sentry spans/transactions are managed exclusively through OTEL APIs. + scope.add_event_processor(|mut event| { + get_active_span(|otel_span| { + let (span_id, trace_id) = ( + convert_span_id(&otel_span.span_context().span_id()), + convert_trace_id(&otel_span.span_context().trace_id()), + ); + + if let Some(sentry_core::protocol::Context::Trace(trace_context)) = + event.contexts.get_mut("trace") + { + trace_context.trace_id = trace_id; + trace_context.span_id = span_id; + } else { + event.contexts.insert( + "trace".into(), + sentry_core::protocol::TraceContext { + span_id, + trace_id, + ..Default::default() + } + .into(), + ); + } + }); + Some(event) + }); + }); + Self { + span_map: Default::default(), + } + } +} + +impl Default for SentrySpanProcessor { + /// Creates a default `SentrySpanProcessor`. + fn default() -> Self { + Self::new() + } +} + +impl SpanProcessor for SentrySpanProcessor { + fn on_start(&self, span: &mut Span, ctx: &Context) { + let span_id = span.span_context().span_id(); + let trace_id = span.span_context().trace_id(); + + let mut span_map = self.span_map.lock().unwrap(); + + let mut span_description = String::new(); + let mut span_op = String::new(); + let mut span_start_timestamp = SystemTime::now(); + let mut parent_sentry_span = None; + if let Some(data) = span.exported_data() { + span_description = data.name.to_string(); + span_op = span_description.clone(); // TODO: infer this from OTEL span attributes + span_start_timestamp = data.start_time; + if data.parent_span_id != SpanId::INVALID { + parent_sentry_span = span_map.get(&convert_span_id(&data.parent_span_id)); + }; + } + let span_description = span_description.as_str(); + let span_op = span_op.as_str(); + + let sentry_span = { + if let Some(parent_sentry_span) = parent_sentry_span { + // continue local trace + TransactionOrSpan::Span(parent_sentry_span.start_child_with_details( + span_op, + span_description, + convert_span_id(&span_id), + span_start_timestamp, + )) + } else { + let sentry_ctx = { + if let Some(sentry_trace) = ctx.get::() { + // continue remote trace + TransactionContext::continue_from_sentry_trace( + span_description, + span_op, + sentry_trace, + ) + } else { + // start a new trace + TransactionContext::new_with_details( + span_description, + span_op, + convert_trace_id(&trace_id), + Some(convert_span_id(&span_id)), + None, + ) + } + }; + let tx = + sentry_core::start_transaction_with_timestamp(sentry_ctx, span_start_timestamp); + TransactionOrSpan::Transaction(tx) + } + }; + span_map.insert(convert_span_id(&span_id), sentry_span); + } + + fn on_end(&self, data: SpanData) { + let span_id = data.span_context.span_id(); + + let mut span_map = self.span_map.lock().unwrap(); + + let Some(sentry_span) = span_map.remove(&convert_span_id(&span_id)) else { + return; + }; + + // TODO: read OTEL span events and convert them to Sentry breadcrumbs/events + + sentry_span.set_data("otel.kind", convert_span_kind(data.span_kind)); + for attribute in data.attributes { + sentry_span.set_data(attribute.key.as_str(), convert_value(attribute.value)); + } + // TODO: read OTEL semantic convention span attributes and map them to the appropriate + // Sentry span attributes/context values + sentry_span.set_status(convert_span_status(&data.status)); + sentry_span.finish_with_timestamp(data.end_time); + } + + fn force_flush(&self) -> OTelSdkResult { + Ok(()) + } + + fn shutdown(&self) -> OTelSdkResult { + Ok(()) + } + + fn set_resource(&mut self, resource: &Resource) { + sentry_core::configure_scope(|scope| { + let otel_context = sentry_core::protocol::OtelContext { + resource: resource + .iter() + .map(|(key, value)| (key.as_str().into(), convert_value(value.clone()))) + .collect(), + ..Default::default() + }; + scope.set_context("otel", sentry_core::protocol::Context::from(otel_context)); + }); + } +} diff --git a/sentry-opentelemetry/src/propagator.rs b/sentry-opentelemetry/src/propagator.rs new file mode 100644 index 000000000..396f95f7b --- /dev/null +++ b/sentry-opentelemetry/src/propagator.rs @@ -0,0 +1,82 @@ +//! An OpenTelemetry [Propagator](https://opentelemetry.io/docs/specs/otel/context/api-propagators/) for Sentry. +//! +//! [`SentryPropagator`] serves two purposes: +//! - extracts incoming Sentry tracing metadata from incoming traces, and stores it in +//! [`opentelemetry::baggage::Baggage`]. This information can then be used by +//! [`crate::processor::SentrySpanProcessor`] to achieve distributed tracing. +//! - injects Sentry tracing metadata in outgoing traces. This information can be used by +//! downstream Sentry SDKs to achieve distributed tracing. +//! +//! # Configuration +//! +//! This should be used together with [`crate::processor::SentrySpanProcessor`]. An example of +//! setting up both is provided in the [crate-level documentation](../). + +use std::sync::LazyLock; + +use opentelemetry::{ + propagation::{text_map_propagator::FieldIter, Extractor, Injector, TextMapPropagator}, + trace::TraceContextExt, + Context, SpanId, TraceId, +}; +use sentry_core::parse_headers; +use sentry_core::SentryTrace; + +use crate::converters::{convert_span_id, convert_trace_id}; + +const SENTRY_TRACE_KEY: &str = "sentry-trace"; + +// list of headers used in the inject operation +static SENTRY_PROPAGATOR_FIELDS: LazyLock<[String; 1]> = + LazyLock::new(|| [SENTRY_TRACE_KEY.to_owned()]); + +/// An OpenTelemetry Propagator that injects and extracts Sentry's tracing headers to achieve +/// distributed tracing. +#[derive(Debug, Copy, Clone)] +pub struct SentryPropagator {} + +impl SentryPropagator { + /// Creates a new `SentryPropagator` + pub fn new() -> Self { + Self {} + } +} + +impl Default for SentryPropagator { + /// Creates a default `SentryPropagator`. + fn default() -> Self { + Self::new() + } +} + +impl TextMapPropagator for SentryPropagator { + fn inject_context(&self, ctx: &Context, injector: &mut dyn Injector) { + let trace_id = ctx.span().span_context().trace_id(); + let span_id = ctx.span().span_context().span_id(); + let sampled = ctx.span().span_context().is_sampled(); + if trace_id == TraceId::INVALID || span_id == SpanId::INVALID { + return; + } + let sentry_trace = SentryTrace::new( + convert_trace_id(&trace_id), + convert_span_id(&span_id), + Some(sampled), + ); + injector.set(SENTRY_TRACE_KEY, sentry_trace.to_string()); + } + + fn extract_with_context(&self, ctx: &Context, extractor: &dyn Extractor) -> Context { + let keys = extractor.keys(); + let pairs = keys + .iter() + .filter_map(|&key| extractor.get(key).map(|value| (key, value))); + if let Some(sentry_trace) = parse_headers(pairs) { + return ctx.with_value(sentry_trace); + } + ctx.clone() + } + + fn fields(&self) -> FieldIter<'_> { + FieldIter::new(&*SENTRY_PROPAGATOR_FIELDS) + } +} diff --git a/sentry-opentelemetry/tests/associates_event_with_span.rs b/sentry-opentelemetry/tests/associates_event_with_span.rs new file mode 100644 index 000000000..2e7b411f8 --- /dev/null +++ b/sentry-opentelemetry/tests/associates_event_with_span.rs @@ -0,0 +1,83 @@ +mod shared; + +use opentelemetry::{ + global, + trace::{Tracer, TracerProvider}, +}; +use opentelemetry_sdk::trace::SdkTracerProvider; +use sentry_core::protocol::Transaction; +use sentry_opentelemetry::{SentryPropagator, SentrySpanProcessor}; + +#[test] +fn test_associates_event_with_span() { + let transport = shared::init_sentry(1.0); // Sample all spans + + // Set up OpenTelemetry + global::set_text_map_propagator(SentryPropagator::new()); + let tracer_provider = SdkTracerProvider::builder() + .with_span_processor(SentrySpanProcessor::new()) + .build(); + let tracer = tracer_provider.tracer("test".to_string()); + + // Create root span and execute test within it + tracer.in_span("root_span", |_| { + // Create child span and execute within it + tracer.in_span("child_span", |_| { + // Capture an event while the child span is active + sentry::capture_message("Test message", sentry::Level::Error); + }); + }); + + // Capture the event and spans + let envelopes = transport.fetch_and_clear_envelopes(); + + // Find event and transaction + let mut transaction: Option = None; + let mut span_id: Option = None; + + let mut trace_id_from_event: Option = None; + let mut span_id_from_event: Option = None; + + for envelope in &envelopes { + for item in envelope.items() { + match item { + sentry::protocol::EnvelopeItem::Event(event) => { + trace_id_from_event = event.contexts.get("trace").and_then(|c| match c { + sentry::protocol::Context::Trace(trace) => Some(trace.trace_id.to_string()), + _ => unreachable!(), + }); + span_id_from_event = event.contexts.get("trace").and_then(|c| match c { + sentry::protocol::Context::Trace(trace) => Some(trace.span_id.to_string()), + _ => unreachable!(), + }); + } + sentry::protocol::EnvelopeItem::Transaction(tx) => { + transaction = Some(tx.clone()); + tx.spans.iter().for_each(|span| { + span_id = Some(span.span_id.to_string()); + }); + } + _ => (), + } + } + } + + let transaction = transaction.expect("Should have a transaction"); + let span_id = span_id.expect("Transaction should have a child span"); + + let trace_id_from_event = trace_id_from_event.expect("Event should have a trace ID"); + let span_id_from_event = span_id_from_event.expect("Event should have a span ID"); + + // Verify that the transaction ID and span ID in the event match with the transaction and span + assert_eq!( + { + let context = transaction.contexts.get("trace").unwrap().clone(); + match context { + sentry::protocol::Context::Trace(context) => context.trace_id.to_string(), + _ => unreachable!(), + } + }, + trace_id_from_event + ); + assert_eq!(span_id, span_id_from_event); +} diff --git a/sentry-opentelemetry/tests/captures_transaction.rs b/sentry-opentelemetry/tests/captures_transaction.rs new file mode 100644 index 000000000..c8ca55d0d --- /dev/null +++ b/sentry-opentelemetry/tests/captures_transaction.rs @@ -0,0 +1,42 @@ +mod shared; + +use opentelemetry::{ + global, + trace::{Tracer, TracerProvider}, +}; +use opentelemetry_sdk::trace::SdkTracerProvider; +use sentry_opentelemetry::{SentryPropagator, SentrySpanProcessor}; + +#[test] +fn test_captures_transaction() { + // Initialize Sentry + let transport = shared::init_sentry(1.0); // Sample all spans + + // Set up OpenTelemetry + global::set_text_map_propagator(SentryPropagator::new()); + let tracer_provider = SdkTracerProvider::builder() + .with_span_processor(SentrySpanProcessor::new()) + .build(); + let tracer = tracer_provider.tracer("test".to_string()); + + // Create and end a root span + tracer.in_span("root_span", |_| { + // Span body is empty, just creating the span + }); + + // Check that data was sent to Sentry + let envelopes = transport.fetch_and_clear_envelopes(); + assert_eq!( + envelopes.len(), + 1, + "Expected one transaction to be sent to Sentry" + ); + + let transaction = envelopes[0].items().next().unwrap(); + match transaction { + sentry::protocol::EnvelopeItem::Transaction(tx) => { + assert_eq!(tx.name.as_deref(), Some("root_span")); + } + unexpected => panic!("Expected transaction, but got {:#?}", unexpected), + } +} diff --git a/sentry-opentelemetry/tests/captures_transaction_with_nested_spans.rs b/sentry-opentelemetry/tests/captures_transaction_with_nested_spans.rs new file mode 100644 index 000000000..4b47efa63 --- /dev/null +++ b/sentry-opentelemetry/tests/captures_transaction_with_nested_spans.rs @@ -0,0 +1,72 @@ +mod shared; + +use opentelemetry::{ + global, + trace::{Status, TraceContextExt, Tracer, TracerProvider}, + KeyValue, +}; +use opentelemetry_sdk::trace::SdkTracerProvider; +use sentry_opentelemetry::{SentryPropagator, SentrySpanProcessor}; + +#[test] +fn test_captures_transaction_with_nested_spans() { + // Initialize Sentry + let transport = shared::init_sentry(1.0); // Sample all spans + + // Set up OpenTelemetry + global::set_text_map_propagator(SentryPropagator::new()); + let tracer_provider = SdkTracerProvider::builder() + .with_span_processor(SentrySpanProcessor::new()) + .build(); + let tracer = tracer_provider.tracer("test".to_string()); + + // Create nested spans using in_span + tracer.in_span("root_span", |_| { + tracer.in_span("child_span", |_| { + tracer.in_span("grandchild_span", |cx| { + // Add some attributes to the grandchild + cx.span() + .set_attribute(KeyValue::new("test.key", "test.value")); + cx.span().set_status(Status::Ok); + }); + }); + }); + + // Check that data was sent to Sentry + let envelopes = transport.fetch_and_clear_envelopes(); + assert_eq!( + envelopes.len(), + 1, + "Expected one transaction to be sent to Sentry" + ); + + let transaction = envelopes[0].items().next().unwrap(); + match transaction { + sentry::protocol::EnvelopeItem::Transaction(tx) => { + assert_eq!(tx.name.as_deref(), Some("root_span")); + assert_eq!(tx.spans.len(), 2); // Should have 2 child spans + + let child_span = tx + .spans + .iter() + .find(|s| s.description.as_deref() == Some("child_span")) + .expect("Child span should exist"); + let grandchild_span = tx + .spans + .iter() + .find(|s| s.description.as_deref() == Some("grandchild_span")) + .expect("Grandchild span should exist"); + + // Get transaction span ID from trace context + let tx_span_id = match &tx.contexts.get("trace") { + Some(sentry::protocol::Context::Trace(trace)) => trace.span_id, + _ => panic!("Missing trace context in transaction"), + }; + + // Check parent-child relationship + assert_eq!(grandchild_span.parent_span_id, Some(child_span.span_id)); + assert_eq!(child_span.parent_span_id, Some(tx_span_id)); + } + unexpected => panic!("Expected transaction, but got {:#?}", unexpected), + } +} diff --git a/sentry-opentelemetry/tests/creates_distributed_trace.rs b/sentry-opentelemetry/tests/creates_distributed_trace.rs new file mode 100644 index 000000000..e57fb5b4f --- /dev/null +++ b/sentry-opentelemetry/tests/creates_distributed_trace.rs @@ -0,0 +1,121 @@ +mod shared; + +use opentelemetry::{ + global, + propagation::TextMapPropagator, + trace::{TraceContextExt, Tracer, TracerProvider}, + Context, +}; +use opentelemetry_sdk::trace::SdkTracerProvider; +use sentry_opentelemetry::{SentryPropagator, SentrySpanProcessor}; +use std::collections::HashMap; + +#[test] +fn test_creates_distributed_trace() { + let transport = shared::init_sentry(1.0); // Sample all spans + + // Set up OpenTelemetry + global::set_text_map_propagator(SentryPropagator::new()); + let tracer_provider = SdkTracerProvider::builder() + .with_span_processor(SentrySpanProcessor::new()) + .build(); + let tracer = tracer_provider.tracer("test".to_string()); + + // We need to store the context to pass between services, so we'll use a mutable variable + let mut headers = HashMap::new(); + let propagator = SentryPropagator::new(); + + // Create a "first service" span and store context in headers + tracer.in_span("first_service", |first_service_ctx| { + // Simulate passing the context to another service by extracting and injecting e.g. HTTP headers + propagator.inject_context(&first_service_ctx, &mut TestInjector(&mut headers)); + }); + + // Now simulate the second service receiving the headers and continuing the trace + let second_service_ctx = + propagator.extract_with_context(&Context::current(), &TestExtractor(&headers)); + + // Create a second service span that continues the trace + // We need to use start_with_context here to connect with the previous context + let second_service_span = tracer.start_with_context("second_service", &second_service_ctx); + let second_service_ctx = second_service_ctx.with_span(second_service_span); + + // End the second service span + second_service_ctx.span().end(); + + // Get both transactions at once + let envelopes = transport.fetch_and_clear_envelopes(); + assert_eq!( + envelopes.len(), + 2, + "Expected two transactions to be sent to Sentry" + ); + + // Find transactions for first and second services + let mut first_tx = None; + let mut second_tx = None; + + for envelope in &envelopes { + let tx = match envelope.items().next().unwrap() { + sentry::protocol::EnvelopeItem::Transaction(tx) => tx.clone(), + unexpected => panic!("Expected transaction, but got {:#?}", unexpected), + }; + + // Determine which service this transaction belongs to based on name + match tx.name.as_deref() { + Some("first_service") => first_tx = Some(tx), + Some("second_service") => second_tx = Some(tx), + name => panic!("Unexpected transaction name: {:?}", name), + } + } + + let first_tx = first_tx.expect("Missing first service transaction"); + let second_tx = second_tx.expect("Missing second service transaction"); + + // Get first service trace ID and span ID + let (first_trace_id, first_span_id) = match &first_tx.contexts.get("trace") { + Some(sentry::protocol::Context::Trace(trace)) => (trace.trace_id, trace.span_id), + _ => panic!("Missing trace context in first transaction"), + }; + + // Get second service trace ID and span ID + let (second_trace_id, second_span_id, second_parent_span_id) = + match &second_tx.contexts.get("trace") { + Some(sentry::protocol::Context::Trace(trace)) => { + (trace.trace_id, trace.span_id, trace.parent_span_id) + } + _ => panic!("Missing trace context in second transaction"), + }; + + // Verify the distributed trace - same trace ID, different span IDs + assert_eq!(first_trace_id, second_trace_id, "Trace IDs should match"); + assert_ne!( + first_span_id, second_span_id, + "Span IDs should be different" + ); + assert_eq!( + second_parent_span_id, + Some(first_span_id), + "Second service's parent span ID should match first service's span ID" + ); +} + +struct TestInjector<'a>(&'a mut HashMap); + +impl opentelemetry::propagation::Injector for TestInjector<'_> { + fn set(&mut self, key: &str, value: String) { + self.0.insert(key.to_string(), value); + } +} + +struct TestExtractor<'a>(&'a HashMap); + +impl opentelemetry::propagation::Extractor for TestExtractor<'_> { + fn get(&self, key: &str) -> Option<&str> { + self.0.get(key).map(|s| s.as_str()) + } + + fn keys(&self) -> Vec<&str> { + self.0.keys().map(|k| k.as_str()).collect() + } +} diff --git a/sentry-opentelemetry/tests/shared.rs b/sentry-opentelemetry/tests/shared.rs new file mode 100644 index 000000000..5189da054 --- /dev/null +++ b/sentry-opentelemetry/tests/shared.rs @@ -0,0 +1,21 @@ +use sentry::{ClientOptions, Hub}; +use sentry_core::test::TestTransport; + +use std::sync::Arc; + +pub fn init_sentry(traces_sample_rate: f32) -> Arc { + let transport = TestTransport::new(); + let options = ClientOptions { + dsn: Some( + "https://test@sentry-opentelemetry.com/test" + .parse() + .unwrap(), + ), + transport: Some(Arc::new(transport.clone())), + sample_rate: 1.0, + traces_sample_rate, + ..ClientOptions::default() + }; + Hub::current().bind_client(Some(Arc::new(options.into()))); + transport +} diff --git a/sentry-types/src/protocol/v7.rs b/sentry-types/src/protocol/v7.rs index badeaa0b5..bb2008f60 100644 --- a/sentry-types/src/protocol/v7.rs +++ b/sentry-types/src/protocol/v7.rs @@ -1096,8 +1096,10 @@ pub enum Context { Browser(Box), /// Tracing data. Trace(Box), - /// GPU data + /// GPU data. Gpu(Box), + /// OpenTelemetry data. + Otel(Box), /// Generic other context data. #[serde(rename = "unknown")] Other(Map), @@ -1114,6 +1116,7 @@ impl Context { Context::Browser(..) => "browser", Context::Trace(..) => "trace", Context::Gpu(..) => "gpu", + Context::Otel(..) => "otel", Context::Other(..) => "unknown", } } @@ -1332,6 +1335,22 @@ pub struct GpuContext { pub other: Map, } +/// OpenTelemetry context +#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)] +pub struct OtelContext { + /// OpenTelemetry [general + /// attributes](https://opentelemetry.io/docs/specs/semconv/general/attributes/). + #[serde(default, skip_serializing_if = "Map::is_empty")] + pub attributes: Map, + /// OpenTelemetry [resource attributes](https://opentelemetry.io/docs/specs/semconv/resource/), + /// describing the entity producing telemetry. + #[serde(default, skip_serializing_if = "Map::is_empty")] + pub resource: Map, + /// Additional arbitrary fields for forwards compatibility. + #[serde(flatten)] + pub other: Map, +} + /// Holds the identifier for a Span #[derive(Serialize, Deserialize, Debug, Copy, Clone, Eq, PartialEq, Hash)] #[serde(try_from = "String", into = "String")] @@ -1373,6 +1392,12 @@ impl TryFrom for SpanId { } } +impl From<[u8; 8]> for SpanId { + fn from(value: [u8; 8]) -> Self { + Self(value) + } +} + /// Holds the identifier for a Trace #[derive(Serialize, Deserialize, Debug, Copy, Clone, Eq, PartialEq, Hash)] #[serde(try_from = "String", into = "String")] @@ -1414,6 +1439,12 @@ impl TryFrom for TraceId { } } +impl From<[u8; 16]> for TraceId { + fn from(value: [u8; 16]) -> Self { + Self(value) + } +} + /// Holds information about a tracing event. #[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)] pub struct TraceContext { @@ -1457,8 +1488,11 @@ into_context!(Runtime, RuntimeContext); into_context!(Browser, BrowserContext); into_context!(Trace, TraceContext); into_context!(Gpu, GpuContext); +into_context!(Otel, OtelContext); -const INFERABLE_CONTEXTS: &[&str] = &["device", "os", "runtime", "app", "browser", "trace", "gpu"]; +const INFERABLE_CONTEXTS: &[&str] = &[ + "device", "os", "runtime", "app", "browser", "trace", "gpu", "otel", +]; struct ContextsVisitor; @@ -1803,6 +1837,11 @@ impl Span { Default::default() } + /// Finalizes the span with the provided timestamp. + pub fn finish_with_timestamp(&mut self, timestamp: SystemTime) { + self.timestamp = Some(timestamp); + } + /// Finalizes the span. pub fn finish(&mut self) { self.timestamp = Some(SystemTime::now()); @@ -2050,6 +2089,11 @@ impl<'a> Transaction<'a> { pub fn finish(&mut self) { self.timestamp = Some(SystemTime::now()); } + + /// Finalizes the transaction to be dispatched with the given end timestamp. + pub fn finish_with_timestamp(&mut self, timestamp: SystemTime) { + self.timestamp = Some(timestamp); + } } impl fmt::Display for Transaction<'_> { diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index 5d77a6299..03a8f1bf4 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -43,6 +43,7 @@ tower = ["sentry-tower"] tower-http = ["tower", "sentry-tower/http"] tower-axum-matched-path = ["tower-http", "sentry-tower/axum-matched-path"] tracing = ["sentry-tracing"] +opentelemetry = ["sentry-opentelemetry"] # other features test = ["sentry-core/test"] debug-logs = ["dep:log", "sentry-core/debug-logs"] @@ -70,6 +71,7 @@ sentry-panic = { version = "0.37.0", path = "../sentry-panic", optional = true } sentry-slog = { version = "0.37.0", path = "../sentry-slog", optional = true } sentry-tower = { version = "0.37.0", path = "../sentry-tower", optional = true } sentry-tracing = { version = "0.37.0", path = "../sentry-tracing", optional = true } +sentry-opentelemetry = { version = "0.37.0", path = "../sentry-opentelemetry", optional = true } log = { version = "0.4.8", optional = true, features = ["std"] } reqwest = { version = "0.12", optional = true, features = [ "blocking", diff --git a/sentry/src/lib.rs b/sentry/src/lib.rs index be98796ff..352094d75 100644 --- a/sentry/src/lib.rs +++ b/sentry/src/lib.rs @@ -204,6 +204,10 @@ pub mod integrations { #[cfg_attr(doc_cfg, doc(cfg(feature = "log")))] #[doc(inline)] pub use sentry_log as log; + #[cfg(feature = "opentelemetry")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "opentelemetry")))] + #[doc(inline)] + pub use sentry_opentelemetry as opentelemetry; #[cfg(feature = "panic")] #[cfg_attr(doc_cfg, doc(cfg(feature = "panic")))] #[doc(inline)] From 2eb09ec0017c2a8a8a5ffdc7ac0a0cb95f382084 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Wed, 7 May 2025 17:36:51 +0200 Subject: [PATCH 076/148] build: add `sentry-opentelemetry` to workspace (#789) --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 48263534c..1b39197e6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ members = [ "sentry-core", "sentry-debug-images", "sentry-log", + "sentry-opentelemetry", "sentry-panic", "sentry-slog", "sentry-tower", From 701c3580a80dd60c67bc94236393467c8337be92 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Wed, 7 May 2025 18:35:05 +0200 Subject: [PATCH 077/148] feat: expose `sentry-actix` as a feature of `sentry` (#788) --- Cargo.lock | 1 + sentry/Cargo.toml | 4 +++- sentry/src/lib.rs | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 655d6a95c..0ce9ce288 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3174,6 +3174,7 @@ dependencies = [ "pretty_env_logger", "reqwest", "rustls", + "sentry-actix", "sentry-anyhow", "sentry-backtrace", "sentry-contexts", diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index 03a8f1bf4..a1b8f3ab1 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -36,6 +36,7 @@ contexts = ["sentry-contexts"] panic = ["sentry-panic"] # other integrations anyhow = ["sentry-anyhow"] +actix = ["sentry-actix"] debug-images = ["sentry-debug-images"] log = ["sentry-log"] slog = ["sentry-slog"] @@ -47,7 +48,7 @@ opentelemetry = ["sentry-opentelemetry"] # other features test = ["sentry-core/test"] debug-logs = ["dep:log", "sentry-core/debug-logs"] -release-health = ["sentry-core/release-health"] +release-health = ["sentry-core/release-health", "sentry-actix/release-health"] # transports transport = ["reqwest", "native-tls"] reqwest = ["dep:reqwest", "httpdate", "tokio"] @@ -63,6 +64,7 @@ sentry-core = { version = "0.37.0", path = "../sentry-core", features = [ "client", ] } sentry-anyhow = { version = "0.37.0", path = "../sentry-anyhow", optional = true } +sentry-actix = { version = "0.37.0", path = "../sentry-actix", optional = true, default-features = false } sentry-backtrace = { version = "0.37.0", path = "../sentry-backtrace", optional = true } sentry-contexts = { version = "0.37.0", path = "../sentry-contexts", optional = true } sentry-debug-images = { version = "0.37.0", path = "../sentry-debug-images", optional = true } diff --git a/sentry/src/lib.rs b/sentry/src/lib.rs index 352094d75..f80f72511 100644 --- a/sentry/src/lib.rs +++ b/sentry/src/lib.rs @@ -184,6 +184,10 @@ pub use crate::init::{init, ClientInitGuard}; /// [`ClientOptions::default_integrations`]: crate::ClientOptions::default_integrations /// [`apply_defaults()`]: ../fn.apply_defaults.html pub mod integrations { + #[cfg(feature = "actix")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "actix")))] + #[doc(inline)] + pub use sentry_actix as actix; #[cfg(feature = "anyhow")] #[cfg_attr(doc_cfg, doc(cfg(feature = "anyhow")))] #[doc(inline)] From c3987a6ec47bcd2ccd56e74a813909beda849177 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Thu, 8 May 2025 10:50:23 +0200 Subject: [PATCH 078/148] docs: update docs including OTEL and other integrations (#790) * docs: update docs including OTEL and other integrations * fix * fix * fix --- README.md | 6 +++ sentry-opentelemetry/README.md | 94 +++++++++++++++++++++++++++++++++ sentry-opentelemetry/src/lib.rs | 71 +++++++++++++++++++------ sentry/README.md | 13 ++++- sentry/src/lib.rs | 14 ++++- 5 files changed, 177 insertions(+), 21 deletions(-) create mode 100644 sentry-opentelemetry/README.md diff --git a/README.md b/README.md index 5913abf8b..6370374e3 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,12 @@ This workspace contains various crates that provide support for logging events a An integration for the `log` and `env_logger` crate. +- [sentry-opentelemetry](./sentry-opentelemetry) + [![crates.io](https://img.shields.io/crates/v/sentry-opentelemetry.svg)](https://crates.io/crates/sentry-opentelemetry) + [![docs.rs](https://docs.rs/sentry-opentelemetry/badge.svg)](https://docs.rs/sentry-opentelemetry) + + An integration for the `opentelemetry` crate. + - [sentry-panic](./sentry-panic) [![crates.io](https://img.shields.io/crates/v/sentry-panic.svg)](https://crates.io/crates/sentry-panic) [![docs.rs](https://docs.rs/sentry-panic/badge.svg)](https://docs.rs/sentry-panic) diff --git a/sentry-opentelemetry/README.md b/sentry-opentelemetry/README.md new file mode 100644 index 000000000..9a01766cb --- /dev/null +++ b/sentry-opentelemetry/README.md @@ -0,0 +1,94 @@ +

+ + Sentry + +

+ +# Sentry Rust SDK: sentry-opentelemetry + +Support for capturing Sentry spans from OpenTelemetry spans. + +Sentry spans are automatically captured from OpenTelemetry spans via `SentrySpanProcessor`. +Distributed tracing is supported via `SentryPropagator`. +Note that it's assumed that only the OTEL API is used to create and manage spans. +Mixing the OTEL and Sentry tracing API will not work, and will result in separate traces being captured. +Using the Sentry API for other purposes is supported. +For example, capturing an error inside a span will correctly send it to Sentry with the span association. + +If you're using `tracing-opentelemetry`, use `sentry-tracing` instead. + +# Configuration + +Add the necessary dependencies to your Cargo.toml: + +```toml +[dependencies] +opentelemetry = { version = "0.29.1", features = ["trace"] } +opentelemetry_sdk = { version = "0.29.0", features = ["trace"] } +sentry = { version = "0.38.0", features = ["opentelemetry"] } +``` + +Initialize Sentry with a `traces_sample_rate`, then register the [`SentryPropagator`] and the +[`SentrySpanProcessor`]: + +```rust +use opentelemetry::{ + global, + trace::{TraceContextExt, Tracer}, + KeyValue, +}; +use opentelemetry_sdk::trace::SdkTracerProvider; +use sentry::integrations::opentelemetry as sentry_opentelemetry; + +// Initialize the Sentry SDK +let _guard = sentry::init(( + "https://your-dsn@sentry.io/0", + sentry::ClientOptions { + // Enable capturing of traces; set this a to lower value in production. + // For more sophisticated behavior use a custom + // [`sentry::ClientOptions::traces_sampler`] instead. + // That's the equivalent of a tail sampling processor in OpenTelemetry. + // These options will only affect sampling of the spans that are sent to Sentry, + // not of the underlying OpenTelemetry spans. + traces_sample_rate: 1.0, + debug: true, + ..sentry::ClientOptions::default() + }, +)); + +// Register the Sentry propagator to enable distributed tracing +global::set_text_map_propagator(sentry_opentelemetry::SentryPropagator::new()); + +let tracer_provider = SdkTracerProvider::builder() + // Register the Sentry span processor to send OpenTelemetry spans to Sentry + .with_span_processor(sentry_opentelemetry::SentrySpanProcessor::new()) + .build(); + +global::set_tracer_provider(tracer_provider); +``` + +# Usage + +Use the OpenTelemetry API to create spans. They will be captured by Sentry: + +```rust +let tracer = global::tracer("tracer"); +// Creates a Sentry span (transaction) with the name set to "example" +tracer.in_span("example", |_| { + // Creates a Sentry child span with the name set to "child" + tracer.in_span("child", |cx| { + // OTEL span attributes are captured as data attributes on the Sentry span + cx.span().set_attribute(KeyValue::new("my", "attribute")); + + // Captures a Sentry error message and associates it with the ongoing child span + sentry::capture_message("Everything is on fire!", sentry::Level::Error); + }); +}); +``` + +## Resources + +License: MIT + +- [Discord](https://discord.gg/ez5KZN7) server for project discussions. +- Follow [@getsentry](https://twitter.com/getsentry) on Twitter for updates diff --git a/sentry-opentelemetry/src/lib.rs b/sentry-opentelemetry/src/lib.rs index d9de713ba..95c7edc0d 100644 --- a/sentry-opentelemetry/src/lib.rs +++ b/sentry-opentelemetry/src/lib.rs @@ -2,35 +2,53 @@ //! //! This integration allows you to capture spans from your existing OpenTelemetry setup and send //! them to Sentry, with support for distributed tracing. +//! //! It's assumed that only the [OpenTelemetry tracing //! API](https://opentelemetry.io/docs/specs/otel/trace/api/) is used to start/end/modify Spans. //! Mixing it with the Sentry tracing API (e.g. `sentry_core::start_transaction(ctx)`) will not //! work, as the spans created with the two methods will not be nested properly. -//! Capturing events (either manually with e.g. `sentry::capture_event`, or automatically with e.g. the -//! `sentry-panic` integration) will send them to Sentry with the correct trace and span -//! association. +//! +//! Capturing events with `sentry::capture_event` will send them to Sentry with the correct +//! trace and span association. //! //! # Configuration //! -//! Initialize Sentry, then register the [`SentryPropagator`] and the [`SentrySpanProcessor`]: +//! Add the necessary dependencies to your Cargo.toml: +//! +//! ```toml +//! [dependencies] +//! opentelemetry = { version = "0.29.1", features = ["trace"] } +//! opentelemetry_sdk = { version = "0.29.0", features = ["trace"] } +//! sentry = { version = "0.38.0", features = ["opentelemetry"] } +//! ``` +//! +//! Initialize Sentry with a `traces_sample_rate`, then register the [`SentryPropagator`] and the +//! [`SentrySpanProcessor`]: //! //! ``` -//! use opentelemetry::{global}; -//! use opentelemetry_sdk::{ -//! propagation::TraceContextPropagator, trace::SdkTracerProvider, +//! use opentelemetry::{ +//! global, +//! trace::{TraceContextExt, Tracer}, +//! KeyValue, //! }; +//! use opentelemetry_sdk::trace::SdkTracerProvider; +//! use sentry::integrations::opentelemetry as sentry_opentelemetry; //! //! // Initialize the Sentry SDK -//! let _guard = sentry::init(sentry::ClientOptions { -//! // Enable capturing of traces; set this a to lower value in production. -//! // For more sophisticated behavior use a custom -//! // [`sentry::ClientOptions::traces_sampler`] instead. -//! // That's the equivalent of a tail sampling processor in OpenTelemetry. -//! // These options will only affect sampling of the spans that are sent to Sentry, -//! // not of the underlying OpenTelemetry spans. -//! traces_sample_rate: 1.0, -//! ..sentry::ClientOptions::default() -//! }); +//! let _guard = sentry::init(( +//! "https://your-dsn@sentry.io/0", +//! sentry::ClientOptions { +//! // Enable capturing of traces; set this a to lower value in production. +//! // For more sophisticated behavior use a custom +//! // [`sentry::ClientOptions::traces_sampler`] instead. +//! // That's the equivalent of a tail sampling processor in OpenTelemetry. +//! // These options will only affect sampling of the spans that are sent to Sentry, +//! // not of the underlying OpenTelemetry spans. +//! traces_sample_rate: 1.0, +//! debug: true, +//! ..sentry::ClientOptions::default() +//! }, +//! )); //! //! // Register the Sentry propagator to enable distributed tracing //! global::set_text_map_propagator(sentry_opentelemetry::SentryPropagator::new()); @@ -42,6 +60,25 @@ //! //! global::set_tracer_provider(tracer_provider); //! ``` +//! +//! # Usage +//! +//! Use the OpenTelemetry API to create spans. They will be captured by Sentry: +//! +//! ```no_run +//! let tracer = global::tracer("tracer"); +//! // Creates a Sentry span (transaction) with the name set to "example" +//! tracer.in_span("example", |_| { +//! // Creates a Sentry child span with the name set to "child" +//! tracer.in_span("child", |cx| { +//! // OTEL span attributes are captured as data attributes on the Sentry span +//! cx.span().set_attribute(KeyValue::new("my", "attribute")); +//! +//! // Captures a Sentry error message and associates it with the ongoing child span +//! sentry::capture_message("Everything is on fire!", sentry::Level::Error); +//! }); +//! }); +//! ``` mod converters; mod processor; diff --git a/sentry/README.md b/sentry/README.md index 9da99f0b5..38b794521 100644 --- a/sentry/README.md +++ b/sentry/README.md @@ -80,14 +80,20 @@ extra setup to function properly. | `reqwest` | ✅ | | | | | `native-tls` | ✅ | | | `reqwest` must be enabled. | | `rustls` | | | | `reqwest` must be enabled. `native-tls` must be disabled via `default-features = false`. | -| `curl` | | | | | -| `tower` | | 🔌 | | Requires extra setup; See [`sentry-tower`]'s documentation. | | `ureq` | | | | `ureq` transport support using `rustls` by default | | `ureq-native-tls` | | | | | +| `curl` | | | | | +| `actix` | | 🔌 | | Requires extra setup; See [`sentry-actix`]'s documentation. | +| `tower` | | 🔌 | | Requires extra setup; See [`sentry-tower`]'s documentation. | +| `tracing` | | 🔌 | | Requires extra setup; See [`sentry-tracing`]'s documentation. | +| `opentelemetry` | | 🔌 | | Requires extra setup; See [`sentry-opentelemetry`]'s documentation. | [`sentry-log`]: https://crates.io/crates/sentry-log [`sentry-slog`]: https://crates.io/crates/sentry-slog +[`sentry-actix`]: https://crates.io/crates/sentry-actix [`sentry-tower`]: https://crates.io/crates/sentry-tower +[`sentry-tracing`]: https://crates.io/crates/sentry-tracing +[`sentry-opentelemetry`]: https://crates.io/crates/sentry-opentelemetry ### Default features - `backtrace`: Enables backtrace support. @@ -116,7 +122,10 @@ extra setup to function properly. - `ureq-native-tls`: Enables the `ureq` transport using `native-tls`. ### Integrations +- `actix`: Enables support for the `actix-web` crate. - `tower`: Enables support for the `tower` crate and those using it. +- `tracing`: Enables support for the `tracing` crate and those using it. +- `opentelemetry`: Enables support for the `opentelemetry` and `opentelemetry-sdk` crates. ## Resources diff --git a/sentry/src/lib.rs b/sentry/src/lib.rs index f80f72511..6e9c49022 100644 --- a/sentry/src/lib.rs +++ b/sentry/src/lib.rs @@ -52,6 +52,7 @@ //! [`Transport`]: trait.Transport.html //! [`sentry-core`]: https://crates.io/crates/sentry-core //! +//! //! # Features //! //! Additional functionality and integrations are enabled via feature flags. Some features require @@ -72,14 +73,20 @@ //! | `reqwest` | ✅ | | | | //! | `native-tls` | ✅ | | | `reqwest` must be enabled. | //! | `rustls` | | | | `reqwest` must be enabled. `native-tls` must be disabled via `default-features = false`. | -//! | `curl` | | | | | -//! | `tower` | | 🔌 | | Requires extra setup; See [`sentry-tower`]'s documentation. | //! | `ureq` | | | | `ureq` transport support using `rustls` by default | //! | `ureq-native-tls` | | | | | +//! | `curl` | | | | | +//! | `actix` | | 🔌 | | Requires extra setup; See [`sentry-actix`]'s documentation. | +//! | `tower` | | 🔌 | | Requires extra setup; See [`sentry-tower`]'s documentation. | +//! | `tracing` | | 🔌 | | Requires extra setup; See [`sentry-tracing`]'s documentation. | +//! | `opentelemetry` | | 🔌 | | Requires extra setup; See [`sentry-opentelemetry`]'s documentation. | //! //! [`sentry-log`]: https://crates.io/crates/sentry-log //! [`sentry-slog`]: https://crates.io/crates/sentry-slog +//! [`sentry-actix`]: https://crates.io/crates/sentry-actix //! [`sentry-tower`]: https://crates.io/crates/sentry-tower +//! [`sentry-tracing`]: https://crates.io/crates/sentry-tracing +//! [`sentry-opentelemetry`]: https://crates.io/crates/sentry-opentelemetry //! //! ## Default features //! - `backtrace`: Enables backtrace support. @@ -108,7 +115,10 @@ //! - `ureq-native-tls`: Enables the `ureq` transport using `native-tls`. //! //! ## Integrations +//! - `actix`: Enables support for the `actix-web` crate. //! - `tower`: Enables support for the `tower` crate and those using it. +//! - `tracing`: Enables support for the `tracing` crate and those using it. +//! - `opentelemetry`: Enables support for the `opentelemetry` and `opentelemetry-sdk` crates. #![doc(html_favicon_url = "https://sentry-brand.storage.googleapis.com/favicon.ico")] #![doc(html_logo_url = "https://sentry-brand.storage.googleapis.com/sentry-glyph-black.png")] From b69d82a516be577d776bde29eb89dacd052fb1fe Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Thu, 8 May 2025 17:40:15 +0200 Subject: [PATCH 079/148] fix: use `release-health` flag in `sentry-actix` and remove it from subcrates where unneeded (#787) * fix: use `release-health` flag in `sentry-actix` and remove it from subcrates where not needed * Update lib.rs * Update lib.rs * gate options as well * tests * Update lib.rs * remove unnecessary cfg macros --- sentry-actix/src/lib.rs | 21 ++++++++++++++------- sentry-core/src/clientoptions.rs | 22 +++++++++++++--------- sentry-core/src/session.rs | 7 ------- sentry-opentelemetry/Cargo.toml | 1 - sentry-tower/Cargo.toml | 3 +-- sentry-tracing/Cargo.toml | 3 +-- sentry/src/init.rs | 4 ++-- 7 files changed, 31 insertions(+), 30 deletions(-) diff --git a/sentry-actix/src/lib.rs b/sentry-actix/src/lib.rs index fe447704c..78938d548 100644 --- a/sentry-actix/src/lib.rs +++ b/sentry-actix/src/lib.rs @@ -284,18 +284,24 @@ where )); let client = hub.client(); - let track_sessions = client.as_ref().is_some_and(|client| { - let options = client.options(); - options.auto_session_tracking - && options.session_mode == sentry_core::SessionMode::Request - }); + let max_request_body_size = client .as_ref() .map(|client| client.options().max_request_body_size) .unwrap_or(MaxRequestBodySize::None); - if track_sessions { - hub.start_session(); + + #[cfg(feature = "release-health")] + { + let track_sessions = client.as_ref().is_some_and(|client| { + let options = client.options(); + options.auto_session_tracking + && options.session_mode == sentry_core::SessionMode::Request + }); + if track_sessions { + hub.start_session(); + } } + let with_pii = client .as_ref() .is_some_and(|client| client.options().send_default_pii); @@ -673,6 +679,7 @@ mod tests { assert_eq!(request.method, Some("GET".into())); } + #[cfg(feature = "release-health")] #[actix_web::test] async fn test_track_session() { let envelopes = sentry::test::with_captured_envelopes_options( diff --git a/sentry-core/src/clientoptions.rs b/sentry-core/src/clientoptions.rs index b05767e20..70b0fcaac 100644 --- a/sentry-core/src/clientoptions.rs +++ b/sentry-core/src/clientoptions.rs @@ -174,14 +174,10 @@ pub struct ClientOptions { /// When automatic session tracking is enabled, a new "user-mode" session /// is started at the time of `sentry::init`, and will persist for the /// application lifetime. - /// - /// **NOTE**: The `release-health` feature (enabled by default) needs to be enabled for this option to have - /// any effect. + #[cfg(feature = "release-health")] pub auto_session_tracking: bool, /// Determine how Sessions are being tracked. - /// - /// **NOTE**: The `release-health` feature (enabled by default) needs to be enabled for this option to have - /// any effect. + #[cfg(feature = "release-health")] pub session_mode: SessionMode, /// Border frames which indicate a border from a backtrace to /// useless internals. Some are automatically included. @@ -232,7 +228,8 @@ impl fmt::Debug for ClientOptions { let integrations: Vec<_> = self.integrations.iter().map(|i| i.name()).collect(); - f.debug_struct("ClientOptions") + let mut debug_struct = f.debug_struct("ClientOptions"); + debug_struct .field("dsn", &self.dsn) .field("debug", &self.debug) .field("release", &self.release) @@ -260,9 +257,14 @@ impl fmt::Debug for ClientOptions { .field("http_proxy", &self.http_proxy) .field("https_proxy", &self.https_proxy) .field("shutdown_timeout", &self.shutdown_timeout) - .field("accept_invalid_certs", &self.accept_invalid_certs) + .field("accept_invalid_certs", &self.accept_invalid_certs); + + #[cfg(feature = "release-health")] + debug_struct .field("auto_session_tracking", &self.auto_session_tracking) - .field("session_mode", &self.session_mode) + .field("session_mode", &self.session_mode); + + debug_struct .field("extra_border_frames", &self.extra_border_frames) .field("trim_backtraces", &self.trim_backtraces) .field("user_agent", &self.user_agent) @@ -295,7 +297,9 @@ impl Default for ClientOptions { https_proxy: None, shutdown_timeout: Duration::from_secs(2), accept_invalid_certs: false, + #[cfg(feature = "release-health")] auto_session_tracking: false, + #[cfg(feature = "release-health")] session_mode: SessionMode::Application, extra_border_frames: vec![], trim_backtraces: true, diff --git a/sentry-core/src/session.rs b/sentry-core/src/session.rs index 00739872f..e9fd2f298 100644 --- a/sentry-core/src/session.rs +++ b/sentry-core/src/session.rs @@ -20,10 +20,8 @@ mod session_impl { SessionStatus, SessionUpdate, }; - #[cfg(feature = "release-health")] use crate::scope::StackLayer; - #[cfg(feature = "release-health")] use crate::types::random_uuid; use crate::{Client, Envelope}; @@ -45,7 +43,6 @@ mod session_impl { } impl Session { - #[cfg(feature = "release-health")] pub fn from_stack(stack: &StackLayer) -> Option { let client = stack.client.as_ref()?; let options = client.options(); @@ -121,7 +118,6 @@ mod session_impl { } } - #[cfg(feature = "release-health")] pub(crate) fn create_envelope_item(&mut self) -> Option { if self.dirty { let item = self.session_update.clone().into(); @@ -135,7 +131,6 @@ mod session_impl { // as defined here: https://develop.sentry.dev/sdk/envelopes/#size-limits const MAX_SESSION_ITEMS: usize = 100; - #[cfg(feature = "release-health")] const FLUSH_INTERVAL: Duration = Duration::from_secs(60); #[derive(Debug, Default)] @@ -202,7 +197,6 @@ mod session_impl { impl SessionFlusher { /// Creates a new Flusher that will submit envelopes to the given `transport`. - #[cfg(feature = "release-health")] pub fn new(transport: TransportArc, mode: SessionMode) -> Self { let queue = Arc::new(Mutex::new(Default::default())); #[allow(clippy::mutex_atomic)] @@ -464,7 +458,6 @@ mod session_impl { }, crate::ClientOptions { release: Some("some-release".into()), - #[cfg(feature = "release-health")] session_mode: SessionMode::Request, ..Default::default() }, diff --git a/sentry-opentelemetry/Cargo.toml b/sentry-opentelemetry/Cargo.toml index 9f889dc25..86db5d4c3 100644 --- a/sentry-opentelemetry/Cargo.toml +++ b/sentry-opentelemetry/Cargo.toml @@ -18,7 +18,6 @@ all-features = true [dependencies] sentry-core = { version = "0.37.0", path = "../sentry-core", features = [ "client", - "release-health" ] } opentelemetry = { version = "0.29.0", default-features = false } opentelemetry_sdk = { version = "0.29.0", default-features = false, features = [ diff --git a/sentry-tower/Cargo.toml b/sentry-tower/Cargo.toml index 8be3a7212..d79d3cb5b 100644 --- a/sentry-tower/Cargo.toml +++ b/sentry-tower/Cargo.toml @@ -16,10 +16,9 @@ rust-version = "1.81" all-features = true [features] -default = ["release-health"] +default = [] http = ["dep:http", "pin-project", "url"] axum-matched-path = ["http", "axum/matched-path"] -release-health = ["sentry-core/release-health"] [dependencies] axum = { version = "0.8", optional = true, default-features = false } diff --git a/sentry-tracing/Cargo.toml b/sentry-tracing/Cargo.toml index 190f6a4d0..79289a505 100644 --- a/sentry-tracing/Cargo.toml +++ b/sentry-tracing/Cargo.toml @@ -16,9 +16,8 @@ rust-version = "1.81" all-features = true [features] -default = ["release-health"] +default = [] backtrace = ["dep:sentry-backtrace"] -release-health = ["sentry-core/release-health"] [dependencies] sentry-core = { version = "0.37.0", path = "../sentry-core", features = [ diff --git a/sentry/src/init.rs b/sentry/src/init.rs index 27fdbce29..12527f0d3 100644 --- a/sentry/src/init.rs +++ b/sentry/src/init.rs @@ -97,9 +97,9 @@ where { let opts = apply_defaults(opts.into()); - #[allow(unused)] + #[cfg(feature = "release-health")] let auto_session_tracking = opts.auto_session_tracking; - #[allow(unused)] + #[cfg(feature = "release-health")] let session_mode = opts.session_mode; let client = Arc::new(Client::from(opts)); From 1de559b7f7affad051bd50d043fb96089741f6e9 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Thu, 8 May 2025 17:42:06 +0200 Subject: [PATCH 080/148] fix(otel): fix doctests (#794) * docs(otel): use ignore attribute in doctests * create dependency infinite loop --- sentry-opentelemetry/Cargo.toml | 2 +- sentry-opentelemetry/src/lib.rs | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/sentry-opentelemetry/Cargo.toml b/sentry-opentelemetry/Cargo.toml index 86db5d4c3..3bc087b96 100644 --- a/sentry-opentelemetry/Cargo.toml +++ b/sentry-opentelemetry/Cargo.toml @@ -26,7 +26,7 @@ opentelemetry_sdk = { version = "0.29.0", default-features = false, features = [ opentelemetry-semantic-conventions = "0.29.0" [dev-dependencies] -sentry = { version = "0.37.0", path = "../sentry", features = ["test"] } +sentry = { version = "0.37.0", path = "../sentry", features = ["test", "opentelemetry"] } sentry-core = { version = "0.37.0", path = "../sentry-core", features = [ "test", ] } diff --git a/sentry-opentelemetry/src/lib.rs b/sentry-opentelemetry/src/lib.rs index 95c7edc0d..226b7a18b 100644 --- a/sentry-opentelemetry/src/lib.rs +++ b/sentry-opentelemetry/src/lib.rs @@ -65,7 +65,13 @@ //! //! Use the OpenTelemetry API to create spans. They will be captured by Sentry: //! -//! ```no_run +//! ``` +//! # use opentelemetry::{ +//! # global, +//! # trace::{TraceContextExt, Tracer}, +//! # KeyValue, +//! # }; +//! //! let tracer = global::tracer("tracer"); //! // Creates a Sentry span (transaction) with the name set to "example" //! tracer.in_span("example", |_| { From 69ce4817fecf9133e8e60fdb8c397c8a8f611a8c Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Fri, 9 May 2025 11:55:20 +0200 Subject: [PATCH 081/148] chore: prepare changelog for 0.38 release (#800) * chore: prepare changelog for 0.38 release * update * update * reorder --- CHANGELOG.md | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 02daa3530..1ced47b04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,65 @@ # Changelog +## Unreleased + +### OpenTelemetry integration + +An OpenTelemetry integration has been released. Please refer to the changelog entry below for the details. + +### Breaking changes + +- refactor(tracing): remove `EventFilter::exception` and always attach exception (#768) by @lcian + - The `EventFilter::Exception` enum variant has been removed. Please use `EventFilter::Event` instead to achieve the same behavior. + - Using `EventFilter::Event` will always attach any error struct used within the `error` field passed to the `tracing` macro, as `EventFilter::Exception` did previously. + - The `error` field will also be attached to breadcrumbs as an `errors` field resembling the structure of Sentry events created from error structs. +- fix: use `release-health` flag in `sentry-actix` and remove it from subcrates where unneeded (#787) by @lcian + - As a follow-up from the changes in the previous release, the `ClientOptions` fields `auto_session_tracking` and `session_mode` are now gated behind the `release-health` feature flag of the `sentry` crate. + - If you depend on `sentry` with `default-features = false`, you need to include the `release-health` feature flag to benefit from the [Release Health](https://docs.sentry.io/product/releases/health/) features of Sentry and have access to the aforementioned client options. + - The `release-health` feature flag is used correctly in `sentry-actix` to enable compilation of that subcrate when it's disabled. + - The `release-health` has been removed from the `sentry-tracing` and `sentry-tower` subcrates, where it was unnecessary. +- refactor: remove Surf transport (#766) by @lcian + - The Surf transport has been removed as the `surf` crate is unmaintained and it was holding back dependency upgrades. + - If you really want to still use Surf, you can define a custom `TransportFactory` and pass it as the `transport` in your `ClientOptions` + +### Behavioral changes + +- refactor: honor `send_default_pii` in `sentry-actix` and `sentry-tower` (#771) by @lcian + - The client option `send_default_pii` (disabled by default) is now honored by `sentry-actix` and `sentry-tower`. + - This means that potentially sensitive headers such as authorization, cookies, and those that usually contain the user's IP address are filtered and not sent to Sentry. + - If you want to get back to the previous behavior and capture all headers, please set `send_default_pii` to `true` in your `ClientOptions`. + - Please refer to our [Data Collected](https://docs.sentry.io/platforms/rust/data-management/data-collected/) page for a comprehensive view of the data collected by the SDK. +- refactor(debug-images): force init `DEBUG_META` on integration init (#773) by @lcian + - The `DebugImages` integration has been updated to init the `DEBUG_META` `Lazy` immediately. + - Using this integration is known to cause issues in specific versions of the Linux kernel due to issues in a library it depends on. + - Previously, on problematic systems the SDK would cause deadlock after capturing the first event. Now the SDK will panic on initialization instead. Please open an issue if you're affected. + +### Features + +- feat(otel): add OpenTelemetry SpanProcessor, Propagator, Extractor (#779) by @lcian + - A new integration for the `opentelemetry` crate has been released. + - It can be used to capture spans created using the `opentelemetry` API and send them to Sentry. + - Distributed tracing is also supported, provided that the upstream/downstream services support the Sentry or W3C distributed tracing metadata format. + - Please refer to the subcrate's README or the crate docs to see an example of setup and usage. +- feat: expose `sentry-actix` as a feature of `sentry` (#788) by @lcian + - `sentry-actix` is now exposed by the `sentry` crate as `sentry::integrations::actix`, gated behind the `actix` feature flag. + - Please update your dependencies to not depend on the `sentry-actix` subcrate directly. + +### Dependencies + +- build(deps): bump openssl from 0.10.71 to 0.10.72 (#762) by @dependabot +- build(deps): bump tokio from 1.44.1 to 1.44.2 (#763) by @dependabot +- chore(deps): bump some dependencies and update `Cargo.lock` (#772) by @lcian + +### Various fixes & improvements + +- Replace `once_cell` with `std::sync::LazyLock` (#776) by @FalkWoldmann +- chore: update GH issue templates for Linear compatibility (#777) by @stephanie-anderson +- chore: update issue templates with blank issue and Discord link (#778) by @lcian +- refactor(core): fail with message if TLS backend not available (#784) by @lcian +- build: add `sentry-opentelemetry` to workspace (#789) by @lcian +- docs: update docs including OTEL and other integrations (#790) by @lcian +- fix(otel): fix doctests (#794) by @lcian + ## 0.37.0 ### Breaking changes From 7074891ab55611391ca4d909ce8e9d1a1bbb0a57 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Fri, 9 May 2025 15:41:30 +0200 Subject: [PATCH 082/148] fix(otel): fix span and trace ids for distributed tracing (#801) * fix(otel): fix span and trace ids for distributed tracing * formatting * remove prints * changelog * doc * dot * default calls new --- CHANGELOG.md | 1 + sentry-core/src/performance.rs | 14 +++++-- sentry-opentelemetry/src/processor.rs | 38 ++++++++++++------- .../tests/creates_distributed_trace.rs | 7 +++- 4 files changed, 42 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ced47b04..e948ffa3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,7 @@ An OpenTelemetry integration has been released. Please refer to the changelog en - build: add `sentry-opentelemetry` to workspace (#789) by @lcian - docs: update docs including OTEL and other integrations (#790) by @lcian - fix(otel): fix doctests (#794) by @lcian +- fix(otel): fix span and trace ids for distributed tracing (#801) by @lcian ## 0.37.0 diff --git a/sentry-core/src/performance.rs b/sentry-core/src/performance.rs index 43ccd6a49..216b15a40 100644 --- a/sentry-core/src/performance.rs +++ b/sentry-core/src/performance.rs @@ -180,7 +180,7 @@ impl TransactionContext { headers: I, ) -> Self { parse_headers(headers) - .map(|sentry_trace| Self::continue_from_sentry_trace(name, op, &sentry_trace)) + .map(|sentry_trace| Self::continue_from_sentry_trace(name, op, &sentry_trace, None)) .unwrap_or_else(|| Self { name: name.into(), op: op.into(), @@ -192,8 +192,14 @@ impl TransactionContext { }) } - /// Creates a new Transaction Context based on the provided distributed tracing data. - pub fn continue_from_sentry_trace(name: &str, op: &str, sentry_trace: &SentryTrace) -> Self { + /// Creates a new Transaction Context based on the provided distributed tracing data, + /// optionally creating the `TransactionContext` with the provided `span_id`. + pub fn continue_from_sentry_trace( + name: &str, + op: &str, + sentry_trace: &SentryTrace, + span_id: Option, + ) -> Self { let (trace_id, parent_span_id, sampled) = (sentry_trace.0, Some(sentry_trace.1), sentry_trace.2); Self { @@ -201,8 +207,8 @@ impl TransactionContext { op: op.into(), trace_id, parent_span_id, - span_id: Default::default(), sampled, + span_id: span_id.unwrap_or_default(), custom: None, } } diff --git a/sentry-opentelemetry/src/processor.rs b/sentry-opentelemetry/src/processor.rs index d1a273380..4c115cb94 100644 --- a/sentry-opentelemetry/src/processor.rs +++ b/sentry-opentelemetry/src/processor.rs @@ -9,7 +9,7 @@ //! setting up both is provided in the [crate-level documentation](../). use std::collections::HashMap; -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, LazyLock, Mutex}; use std::time::SystemTime; use opentelemetry::global::ObjectSafeSpan; @@ -31,12 +31,12 @@ use crate::converters::{ /// to track OTEL spans across start/end calls. type SpanMap = Arc>>; +static SPAN_MAP: LazyLock = LazyLock::new(|| Arc::new(Mutex::new(HashMap::new()))); + /// An OpenTelemetry SpanProcessor that converts OTEL spans to Sentry spans/transactions and sends /// them to Sentry. #[derive(Debug, Clone)] -pub struct SentrySpanProcessor { - span_map: SpanMap, -} +pub struct SentrySpanProcessor {} impl SentrySpanProcessor { /// Creates a new `SentrySpanProcessor`. @@ -46,10 +46,23 @@ impl SentrySpanProcessor { // This works as long as all Sentry spans/transactions are managed exclusively through OTEL APIs. scope.add_event_processor(|mut event| { get_active_span(|otel_span| { - let (span_id, trace_id) = ( - convert_span_id(&otel_span.span_context().span_id()), - convert_trace_id(&otel_span.span_context().trace_id()), - ); + let span_map = SPAN_MAP.lock().unwrap(); + + let Some(sentry_span) = + span_map.get(&convert_span_id(&otel_span.span_context().span_id())) + else { + return; + }; + + let (span_id, trace_id) = match sentry_span { + TransactionOrSpan::Transaction(transaction) => ( + transaction.get_trace_context().span_id, + transaction.get_trace_context().trace_id, + ), + TransactionOrSpan::Span(span) => { + (span.get_span_id(), span.get_trace_context().trace_id) + } + }; if let Some(sentry_core::protocol::Context::Trace(trace_context)) = event.contexts.get_mut("trace") @@ -71,9 +84,7 @@ impl SentrySpanProcessor { Some(event) }); }); - Self { - span_map: Default::default(), - } + Self {} } } @@ -89,7 +100,7 @@ impl SpanProcessor for SentrySpanProcessor { let span_id = span.span_context().span_id(); let trace_id = span.span_context().trace_id(); - let mut span_map = self.span_map.lock().unwrap(); + let mut span_map = SPAN_MAP.lock().unwrap(); let mut span_description = String::new(); let mut span_op = String::new(); @@ -123,6 +134,7 @@ impl SpanProcessor for SentrySpanProcessor { span_description, span_op, sentry_trace, + Some(convert_span_id(&span_id)), ) } else { // start a new trace @@ -146,7 +158,7 @@ impl SpanProcessor for SentrySpanProcessor { fn on_end(&self, data: SpanData) { let span_id = data.span_context.span_id(); - let mut span_map = self.span_map.lock().unwrap(); + let mut span_map = SPAN_MAP.lock().unwrap(); let Some(sentry_span) = span_map.remove(&convert_span_id(&span_id)) else { return; diff --git a/sentry-opentelemetry/tests/creates_distributed_trace.rs b/sentry-opentelemetry/tests/creates_distributed_trace.rs index e57fb5b4f..7ae4297c9 100644 --- a/sentry-opentelemetry/tests/creates_distributed_trace.rs +++ b/sentry-opentelemetry/tests/creates_distributed_trace.rs @@ -32,8 +32,13 @@ fn test_creates_distributed_trace() { }); // Now simulate the second service receiving the headers and continuing the trace + let tracer_provider = SdkTracerProvider::builder() + .with_span_processor(SentrySpanProcessor::new()) + .build(); + let tracer = tracer_provider.tracer("test_2".to_string()); + let propagator = SentryPropagator::new(); let second_service_ctx = - propagator.extract_with_context(&Context::current(), &TestExtractor(&headers)); + propagator.extract_with_context(&Context::new(), &TestExtractor(&headers)); // Create a second service span that continues the trace // We need to use start_with_context here to connect with the previous context From f41d60a975e3b711a9d8096cf022fe2ef1726585 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Fri, 9 May 2025 16:16:40 +0200 Subject: [PATCH 083/148] build(otel): exclude version from circular dev-dependencies (#802) * build(otel): exclude version from circular dev-dependencies * changelog --- CHANGELOG.md | 1 + sentry-opentelemetry/Cargo.toml | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e948ffa3f..d1753de04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -60,6 +60,7 @@ An OpenTelemetry integration has been released. Please refer to the changelog en - docs: update docs including OTEL and other integrations (#790) by @lcian - fix(otel): fix doctests (#794) by @lcian - fix(otel): fix span and trace ids for distributed tracing (#801) by @lcian +- build(otel): exclude version from circular dev-dependencies (#802) by @lcian ## 0.37.0 diff --git a/sentry-opentelemetry/Cargo.toml b/sentry-opentelemetry/Cargo.toml index 3bc087b96..13af21dc4 100644 --- a/sentry-opentelemetry/Cargo.toml +++ b/sentry-opentelemetry/Cargo.toml @@ -26,10 +26,8 @@ opentelemetry_sdk = { version = "0.29.0", default-features = false, features = [ opentelemetry-semantic-conventions = "0.29.0" [dev-dependencies] -sentry = { version = "0.37.0", path = "../sentry", features = ["test", "opentelemetry"] } -sentry-core = { version = "0.37.0", path = "../sentry-core", features = [ - "test", -] } +sentry = { path = "../sentry", features = ["test", "opentelemetry"] } +sentry-core = { path = "../sentry-core", features = [ "test" ] } opentelemetry_sdk = { version = "0.29.0", default-features = false, features = [ "trace", "testing", From 8d72c988a9986bdfe285e0ac07deed29eea1af73 Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Fri, 9 May 2025 14:18:05 +0000 Subject: [PATCH 084/148] release: 0.38.0 --- CHANGELOG.md | 2 +- sentry-actix/Cargo.toml | 4 ++-- sentry-anyhow/Cargo.toml | 6 +++--- sentry-backtrace/Cargo.toml | 4 ++-- sentry-contexts/Cargo.toml | 4 ++-- sentry-core/Cargo.toml | 4 ++-- sentry-core/README.md | 2 +- sentry-debug-images/Cargo.toml | 4 ++-- sentry-debug-images/README.md | 2 +- sentry-log/Cargo.toml | 4 ++-- sentry-opentelemetry/Cargo.toml | 4 ++-- sentry-opentelemetry/README.md | 23 +++++++++++++---------- sentry-panic/Cargo.toml | 6 +++--- sentry-slog/Cargo.toml | 4 ++-- sentry-tower/Cargo.toml | 4 ++-- sentry-tower/README.md | 4 ++-- sentry-tracing/Cargo.toml | 6 +++--- sentry-tracing/README.md | 2 +- sentry-types/Cargo.toml | 2 +- sentry/Cargo.toml | 26 +++++++++++++------------- sentry/README.md | 15 ++++++++------- 21 files changed, 68 insertions(+), 64 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d1753de04..c78676970 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 0.38.0 ### OpenTelemetry integration diff --git a/sentry-actix/Cargo.toml b/sentry-actix/Cargo.toml index 30658b7bf..c3885446b 100644 --- a/sentry-actix/Cargo.toml +++ b/sentry-actix/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-actix" -version = "0.37.0" +version = "0.38.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -20,7 +20,7 @@ release-health = ["sentry-core/release-health"] actix-web = { version = "4", default-features = false } bytes = "1.2" futures-util = { version = "0.3.5", default-features = false } -sentry-core = { version = "0.37.0", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.38.0", path = "../sentry-core", default-features = false, features = [ "client", ] } actix-http = "3.10" diff --git a/sentry-anyhow/Cargo.toml b/sentry-anyhow/Cargo.toml index 17376cab8..b5efa6cad 100644 --- a/sentry-anyhow/Cargo.toml +++ b/sentry-anyhow/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-anyhow" -version = "0.37.0" +version = "0.38.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -17,8 +17,8 @@ default = ["backtrace"] backtrace = ["anyhow/backtrace"] [dependencies] -sentry-backtrace = { version = "0.37.0", path = "../sentry-backtrace" } -sentry-core = { version = "0.37.0", path = "../sentry-core" } +sentry-backtrace = { version = "0.38.0", path = "../sentry-backtrace" } +sentry-core = { version = "0.38.0", path = "../sentry-core" } anyhow = "1.0.39" [dev-dependencies] diff --git a/sentry-backtrace/Cargo.toml b/sentry-backtrace/Cargo.toml index 30c9a63aa..5eb597068 100644 --- a/sentry-backtrace/Cargo.toml +++ b/sentry-backtrace/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-backtrace" -version = "0.37.0" +version = "0.38.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -18,4 +18,4 @@ regex = { version = "1.5.5", default-features = false, features = [ "std", "unicode-perl", ] } -sentry-core = { version = "0.37.0", path = "../sentry-core" } +sentry-core = { version = "0.38.0", path = "../sentry-core" } diff --git a/sentry-contexts/Cargo.toml b/sentry-contexts/Cargo.toml index 03c2096a9..0b3853c27 100644 --- a/sentry-contexts/Cargo.toml +++ b/sentry-contexts/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-contexts" -version = "0.37.0" +version = "0.38.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -14,7 +14,7 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.37.0", path = "../sentry-core" } +sentry-core = { version = "0.38.0", path = "../sentry-core" } libc = "0.2.66" hostname = "0.4" diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index 4c101ea25..a5aa050fe 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-core" -version = "0.37.0" +version = "0.38.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -34,7 +34,7 @@ crc32fast = { version = "1.4.0", optional = true } log = { version = "0.4.8", optional = true, features = ["std"] } rand = { version = "0.9.0", optional = true } regex = { version = "1.7.3", optional = true } -sentry-types = { version = "0.37.0", path = "../sentry-types" } +sentry-types = { version = "0.38.0", path = "../sentry-types" } serde = { version = "1.0.104", features = ["derive"] } serde_json = { version = "1.0.46" } uuid = { version = "1.0.0", features = ["v4", "serde"], optional = true } diff --git a/sentry-core/README.md b/sentry-core/README.md index 645a051cc..450b0941c 100644 --- a/sentry-core/README.md +++ b/sentry-core/README.md @@ -102,7 +102,7 @@ functionality. [Sentry]: https://sentry.io/ [`sentry`]: https://crates.io/crates/sentry [Unified API]: https://develop.sentry.dev/sdk/unified-api/ -[`test`]: https://docs.rs/sentry-core/0.37.0/sentry_core/test/index.html +[`test`]: https://docs.rs/sentry-core/0.38.0/sentry_core/test/index.html ## Resources diff --git a/sentry-debug-images/Cargo.toml b/sentry-debug-images/Cargo.toml index 035dcc57f..4bd7900a6 100644 --- a/sentry-debug-images/Cargo.toml +++ b/sentry-debug-images/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-debug-images" -version = "0.37.0" +version = "0.38.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -14,4 +14,4 @@ rust-version = "1.81" [dependencies] findshlibs = "=0.10.2" -sentry-core = { version = "0.37.0", path = "../sentry-core" } +sentry-core = { version = "0.38.0", path = "../sentry-core" } diff --git a/sentry-debug-images/README.md b/sentry-debug-images/README.md index 0629301be..3b664ed8e 100644 --- a/sentry-debug-images/README.md +++ b/sentry-debug-images/README.md @@ -22,7 +22,7 @@ let integration = sentry_debug_images::DebugImagesIntegration::new() .filter(|event| event.level >= Level::Warning); ``` -[`Event`]: https://docs.rs/sentry-debug-images/0.37.0/sentry_debug_images/sentry_core::protocol::Event +[`Event`]: https://docs.rs/sentry-debug-images/0.38.0/sentry_debug_images/sentry_core::protocol::Event ## Resources diff --git a/sentry-log/Cargo.toml b/sentry-log/Cargo.toml index 2b31c45a7..53339aafe 100644 --- a/sentry-log/Cargo.toml +++ b/sentry-log/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-log" -version = "0.37.0" +version = "0.38.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.37.0", path = "../sentry-core" } +sentry-core = { version = "0.38.0", path = "../sentry-core" } log = { version = "0.4.8", features = ["std"] } [dev-dependencies] diff --git a/sentry-opentelemetry/Cargo.toml b/sentry-opentelemetry/Cargo.toml index 13af21dc4..3b477b456 100644 --- a/sentry-opentelemetry/Cargo.toml +++ b/sentry-opentelemetry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-opentelemetry" -version = "0.37.0" +version = "0.38.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -16,7 +16,7 @@ rust-version = "1.81" all-features = true [dependencies] -sentry-core = { version = "0.37.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.38.0", path = "../sentry-core", features = [ "client", ] } opentelemetry = { version = "0.29.0", default-features = false } diff --git a/sentry-opentelemetry/README.md b/sentry-opentelemetry/README.md index 9a01766cb..21533437e 100644 --- a/sentry-opentelemetry/README.md +++ b/sentry-opentelemetry/README.md @@ -6,18 +6,20 @@ # Sentry Rust SDK: sentry-opentelemetry -Support for capturing Sentry spans from OpenTelemetry spans. +OpenTelemetry support for Sentry. -Sentry spans are automatically captured from OpenTelemetry spans via `SentrySpanProcessor`. -Distributed tracing is supported via `SentryPropagator`. -Note that it's assumed that only the OTEL API is used to create and manage spans. -Mixing the OTEL and Sentry tracing API will not work, and will result in separate traces being captured. -Using the Sentry API for other purposes is supported. -For example, capturing an error inside a span will correctly send it to Sentry with the span association. +This integration allows you to capture spans from your existing OpenTelemetry setup and send +them to Sentry, with support for distributed tracing. -If you're using `tracing-opentelemetry`, use `sentry-tracing` instead. +It's assumed that only the [OpenTelemetry tracing +API](https://opentelemetry.io/docs/specs/otel/trace/api/) is used to start/end/modify Spans. +Mixing it with the Sentry tracing API (e.g. `sentry_core::start_transaction(ctx)`) will not +work, as the spans created with the two methods will not be nested properly. -# Configuration +Capturing events with `sentry::capture_event` will send them to Sentry with the correct +trace and span association. + +## Configuration Add the necessary dependencies to your Cargo.toml: @@ -67,11 +69,12 @@ let tracer_provider = SdkTracerProvider::builder() global::set_tracer_provider(tracer_provider); ``` -# Usage +## Usage Use the OpenTelemetry API to create spans. They will be captured by Sentry: ```rust + let tracer = global::tracer("tracer"); // Creates a Sentry span (transaction) with the name set to "example" tracer.in_span("example", |_| { diff --git a/sentry-panic/Cargo.toml b/sentry-panic/Cargo.toml index 0ad95881e..2526dc701 100644 --- a/sentry-panic/Cargo.toml +++ b/sentry-panic/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-panic" -version = "0.37.0" +version = "0.38.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -13,8 +13,8 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.37.0", path = "../sentry-core" } -sentry-backtrace = { version = "0.37.0", path = "../sentry-backtrace" } +sentry-core = { version = "0.38.0", path = "../sentry-core" } +sentry-backtrace = { version = "0.38.0", path = "../sentry-backtrace" } [dev-dependencies] sentry = { path = "../sentry", default-features = false, features = ["test"] } diff --git a/sentry-slog/Cargo.toml b/sentry-slog/Cargo.toml index 4028bc748..bf617011e 100644 --- a/sentry-slog/Cargo.toml +++ b/sentry-slog/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-slog" -version = "0.37.0" +version = "0.38.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.37.0", path = "../sentry-core" } +sentry-core = { version = "0.38.0", path = "../sentry-core" } slog = { version = "2.5.2", features = ["nested-values"] } serde_json = "1.0.46" diff --git a/sentry-tower/Cargo.toml b/sentry-tower/Cargo.toml index d79d3cb5b..5ab2b8135 100644 --- a/sentry-tower/Cargo.toml +++ b/sentry-tower/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tower" -version = "0.37.0" +version = "0.38.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -26,7 +26,7 @@ tower-layer = "0.3" tower-service = "0.3" http = { version = "1.0.0", optional = true } pin-project = { version = "1.0.10", optional = true } -sentry-core = { version = "0.37.0", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.38.0", path = "../sentry-core", default-features = false, features = [ "client", ] } url = { version = "2.2.2", optional = true } diff --git a/sentry-tower/README.md b/sentry-tower/README.md index 6aaba0bd9..b4a94778e 100644 --- a/sentry-tower/README.md +++ b/sentry-tower/README.md @@ -103,7 +103,7 @@ feature of the `sentry` crate instead of the `tower` feature. The created transaction will automatically use the request URI as its name. This is sometimes not desirable in case the request URI contains unique IDs or similar. In this case, users should manually override the transaction name -in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.37.0/sentry_tower/sentry_core::Scope::set_transaction) +in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.38.0/sentry_tower/sentry_core::Scope::set_transaction) method. When combining both layers, take care of the ordering of both. For example @@ -113,7 +113,7 @@ one, like so: ```rust let layer = tower::ServiceBuilder::new() .layer(sentry_tower::NewSentryLayer::::new_from_top()) - .layer(sentry_tower::SentryHttpLayer::with_transaction()); + .layer(sentry_tower::SentryHttpLayer::new().enable_transaction()); ``` [`tower::ServiceBuilder`]: https://docs.rs/tower/latest/tower/struct.ServiceBuilder.html diff --git a/sentry-tracing/Cargo.toml b/sentry-tracing/Cargo.toml index 79289a505..921fdeed6 100644 --- a/sentry-tracing/Cargo.toml +++ b/sentry-tracing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tracing" -version = "0.37.0" +version = "0.38.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -20,14 +20,14 @@ default = [] backtrace = ["dep:sentry-backtrace"] [dependencies] -sentry-core = { version = "0.37.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.38.0", path = "../sentry-core", features = [ "client", ] } tracing-core = "0.1" tracing-subscriber = { version = "0.3.1", default-features = false, features = [ "std", ] } -sentry-backtrace = { version = "0.37.0", path = "../sentry-backtrace", optional = true } +sentry-backtrace = { version = "0.38.0", path = "../sentry-backtrace", optional = true } [dev-dependencies] log = "0.4" diff --git a/sentry-tracing/README.md b/sentry-tracing/README.md index 7ed9411d5..752163648 100644 --- a/sentry-tracing/README.md +++ b/sentry-tracing/README.md @@ -83,7 +83,7 @@ tracing::error!( ); ``` -To track [error structs](https://docs.rs/sentry-tracing/0.37.0/sentry_tracing/std::error::Error), assign a reference to error trait object as field +To track [error structs](https://docs.rs/sentry-tracing/0.38.0/sentry_tracing/std::error::Error), assign a reference to error trait object as field in one of the logging macros. By convention, it is recommended to use the `ERROR` level and assign it to a field called `error`, although the integration will also work with all other levels and field names. diff --git a/sentry-types/Cargo.toml b/sentry-types/Cargo.toml index c634bc0b0..9b3cd9018 100644 --- a/sentry-types/Cargo.toml +++ b/sentry-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-types" -version = "0.37.0" +version = "0.38.0" authors = ["Sentry "] license = "MIT" readme = "README.md" diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index a1b8f3ab1..f62a38f35 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry" -version = "0.37.0" +version = "0.38.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -60,20 +60,20 @@ rustls = ["dep:rustls", "reqwest?/rustls-tls", "ureq?/tls", "webpki-roots"] embedded-svc-http = ["dep:embedded-svc", "dep:esp-idf-svc"] [dependencies] -sentry-core = { version = "0.37.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.38.0", path = "../sentry-core", features = [ "client", ] } -sentry-anyhow = { version = "0.37.0", path = "../sentry-anyhow", optional = true } -sentry-actix = { version = "0.37.0", path = "../sentry-actix", optional = true, default-features = false } -sentry-backtrace = { version = "0.37.0", path = "../sentry-backtrace", optional = true } -sentry-contexts = { version = "0.37.0", path = "../sentry-contexts", optional = true } -sentry-debug-images = { version = "0.37.0", path = "../sentry-debug-images", optional = true } -sentry-log = { version = "0.37.0", path = "../sentry-log", optional = true } -sentry-panic = { version = "0.37.0", path = "../sentry-panic", optional = true } -sentry-slog = { version = "0.37.0", path = "../sentry-slog", optional = true } -sentry-tower = { version = "0.37.0", path = "../sentry-tower", optional = true } -sentry-tracing = { version = "0.37.0", path = "../sentry-tracing", optional = true } -sentry-opentelemetry = { version = "0.37.0", path = "../sentry-opentelemetry", optional = true } +sentry-anyhow = { version = "0.38.0", path = "../sentry-anyhow", optional = true } +sentry-actix = { version = "0.38.0", path = "../sentry-actix", optional = true, default-features = false } +sentry-backtrace = { version = "0.38.0", path = "../sentry-backtrace", optional = true } +sentry-contexts = { version = "0.38.0", path = "../sentry-contexts", optional = true } +sentry-debug-images = { version = "0.38.0", path = "../sentry-debug-images", optional = true } +sentry-log = { version = "0.38.0", path = "../sentry-log", optional = true } +sentry-panic = { version = "0.38.0", path = "../sentry-panic", optional = true } +sentry-slog = { version = "0.38.0", path = "../sentry-slog", optional = true } +sentry-tower = { version = "0.38.0", path = "../sentry-tower", optional = true } +sentry-tracing = { version = "0.38.0", path = "../sentry-tracing", optional = true } +sentry-opentelemetry = { version = "0.38.0", path = "../sentry-opentelemetry", optional = true } log = { version = "0.4.8", optional = true, features = ["std"] } reqwest = { version = "0.12", optional = true, features = [ "blocking", diff --git a/sentry/README.md b/sentry/README.md index 38b794521..6efb52e6c 100644 --- a/sentry/README.md +++ b/sentry/README.md @@ -34,8 +34,8 @@ sentry::capture_message("Hello World!", sentry::Level::Info); More complex examples on how to use sentry can also be found in [examples]. Extended instructions may also be found on [Sentry itself]. -[`sentry::init`]: https://docs.rs/sentry/0.37.0/sentry/fn.init.html -[`Hub`]: https://docs.rs/sentry/0.37.0/sentry/struct.Hub.html +[`sentry::init`]: https://docs.rs/sentry/0.38.0/sentry/fn.init.html +[`Hub`]: https://docs.rs/sentry/0.38.0/sentry/struct.Hub.html [examples]: https://github.com/getsentry/sentry-rust/tree/master/sentry/examples [Sentry itself]: https://docs.sentry.io/platforms/rust @@ -47,8 +47,8 @@ the ecosystem require a feature flag. For available integrations and how to use [integrations] and [apply_defaults]. [Features]: #features -[integrations]: https://docs.rs/sentry/0.37.0/sentry/integrations/index.html -[apply_defaults]: https://docs.rs/sentry/0.37.0/sentry/fn.apply_defaults.html +[integrations]: https://docs.rs/sentry/0.38.0/sentry/integrations/index.html +[apply_defaults]: https://docs.rs/sentry/0.38.0/sentry/fn.apply_defaults.html ## Minimal API @@ -56,10 +56,11 @@ This crate comes fully-featured. If the goal is to instrument libraries for usag with sentry, or to extend sentry with a custom [`Integration`] or a [`Transport`], one should use the [`sentry-core`] crate instead. -[`Integration`]: https://docs.rs/sentry/0.37.0/sentry/trait.Integration.html -[`Transport`]: https://docs.rs/sentry/0.37.0/sentry/trait.Transport.html +[`Integration`]: https://docs.rs/sentry/0.38.0/sentry/trait.Integration.html +[`Transport`]: https://docs.rs/sentry/0.38.0/sentry/trait.Transport.html [`sentry-core`]: https://crates.io/crates/sentry-core + ## Features Additional functionality and integrations are enabled via feature flags. Some features require @@ -125,7 +126,7 @@ extra setup to function properly. - `actix`: Enables support for the `actix-web` crate. - `tower`: Enables support for the `tower` crate and those using it. - `tracing`: Enables support for the `tracing` crate and those using it. -- `opentelemetry`: Enables support for the `opentelemetry` and `opentelemetry-sdk` crates. +- `opentelemetry`: Enables support for the `opentelemetry` and `opentelemetry-sdk` crates. ## Resources From 7ba4b453a53c947d64bbdd8d26cd126ac4fd604a Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Tue, 13 May 2025 09:26:16 +0200 Subject: [PATCH 085/148] build: include `sentry-actix` optionally when `release-health` is enabled (#806) * build: pull in `sentry-actix` optionally when `release-health` is enabled * changelog * Update CHANGELOG.md --- CHANGELOG.md | 8 ++++++++ Cargo.lock | 28 ++++++++++++++-------------- sentry/Cargo.toml | 2 +- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c78676970..d4ab0ef29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## Unreleased + +### Fixes + +- build: include `sentry-actix` optionally when `release-health` is enabled (#806) by @lcian + - `sentry-actix` is now being included as a dependency only when explicitly added, either as a direct dependency or through the `actix` feature flag of the `sentry` crate. + - Due to a mistake in the `Cargo.toml`, it was previously being included as a dependency by default when using just the `sentry` crate with default features. + ## 0.38.0 ### OpenTelemetry integration diff --git a/Cargo.lock b/Cargo.lock index 0ce9ce288..71970158f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3161,7 +3161,7 @@ dependencies = [ [[package]] name = "sentry" -version = "0.37.0" +version = "0.38.0" dependencies = [ "actix-web", "anyhow", @@ -3198,7 +3198,7 @@ dependencies = [ [[package]] name = "sentry-actix" -version = "0.37.0" +version = "0.38.0" dependencies = [ "actix-http", "actix-web", @@ -3212,7 +3212,7 @@ dependencies = [ [[package]] name = "sentry-anyhow" -version = "0.37.0" +version = "0.38.0" dependencies = [ "anyhow", "sentry", @@ -3222,7 +3222,7 @@ dependencies = [ [[package]] name = "sentry-backtrace" -version = "0.37.0" +version = "0.38.0" dependencies = [ "backtrace", "regex", @@ -3231,7 +3231,7 @@ dependencies = [ [[package]] name = "sentry-contexts" -version = "0.37.0" +version = "0.38.0" dependencies = [ "hostname", "libc", @@ -3244,7 +3244,7 @@ dependencies = [ [[package]] name = "sentry-core" -version = "0.37.0" +version = "0.38.0" dependencies = [ "anyhow", "cadence", @@ -3266,7 +3266,7 @@ dependencies = [ [[package]] name = "sentry-debug-images" -version = "0.37.0" +version = "0.38.0" dependencies = [ "findshlibs", "sentry-core", @@ -3274,7 +3274,7 @@ dependencies = [ [[package]] name = "sentry-log" -version = "0.37.0" +version = "0.38.0" dependencies = [ "log", "pretty_env_logger", @@ -3284,7 +3284,7 @@ dependencies = [ [[package]] name = "sentry-opentelemetry" -version = "0.37.0" +version = "0.38.0" dependencies = [ "opentelemetry", "opentelemetry-semantic-conventions", @@ -3295,7 +3295,7 @@ dependencies = [ [[package]] name = "sentry-panic" -version = "0.37.0" +version = "0.38.0" dependencies = [ "sentry", "sentry-backtrace", @@ -3304,7 +3304,7 @@ dependencies = [ [[package]] name = "sentry-slog" -version = "0.37.0" +version = "0.38.0" dependencies = [ "erased-serde", "sentry", @@ -3316,7 +3316,7 @@ dependencies = [ [[package]] name = "sentry-tower" -version = "0.37.0" +version = "0.38.0" dependencies = [ "anyhow", "axum 0.8.3", @@ -3336,7 +3336,7 @@ dependencies = [ [[package]] name = "sentry-tracing" -version = "0.37.0" +version = "0.38.0" dependencies = [ "log", "sentry", @@ -3351,7 +3351,7 @@ dependencies = [ [[package]] name = "sentry-types" -version = "0.37.0" +version = "0.38.0" dependencies = [ "debugid", "hex", diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index f62a38f35..871be7ec9 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -48,7 +48,7 @@ opentelemetry = ["sentry-opentelemetry"] # other features test = ["sentry-core/test"] debug-logs = ["dep:log", "sentry-core/debug-logs"] -release-health = ["sentry-core/release-health", "sentry-actix/release-health"] +release-health = ["sentry-core/release-health", "sentry-actix?/release-health"] # transports transport = ["reqwest", "native-tls"] reqwest = ["dep:reqwest", "httpdate", "tokio"] From ece62934fb7d8639ac44f288d3d880d0b89b9cf5 Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Tue, 13 May 2025 07:33:27 +0000 Subject: [PATCH 086/148] release: 0.38.1 --- CHANGELOG.md | 2 +- sentry-actix/Cargo.toml | 4 ++-- sentry-anyhow/Cargo.toml | 6 +++--- sentry-backtrace/Cargo.toml | 4 ++-- sentry-contexts/Cargo.toml | 4 ++-- sentry-core/Cargo.toml | 4 ++-- sentry-core/README.md | 2 +- sentry-debug-images/Cargo.toml | 4 ++-- sentry-debug-images/README.md | 2 +- sentry-log/Cargo.toml | 4 ++-- sentry-opentelemetry/Cargo.toml | 4 ++-- sentry-panic/Cargo.toml | 6 +++--- sentry-slog/Cargo.toml | 4 ++-- sentry-tower/Cargo.toml | 4 ++-- sentry-tower/README.md | 2 +- sentry-tracing/Cargo.toml | 6 +++--- sentry-tracing/README.md | 2 +- sentry-types/Cargo.toml | 2 +- sentry/Cargo.toml | 26 +++++++++++++------------- sentry/README.md | 12 ++++++------ 20 files changed, 52 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4ab0ef29..687a9227c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 0.38.1 ### Fixes diff --git a/sentry-actix/Cargo.toml b/sentry-actix/Cargo.toml index c3885446b..1adbe2a48 100644 --- a/sentry-actix/Cargo.toml +++ b/sentry-actix/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-actix" -version = "0.38.0" +version = "0.38.1" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -20,7 +20,7 @@ release-health = ["sentry-core/release-health"] actix-web = { version = "4", default-features = false } bytes = "1.2" futures-util = { version = "0.3.5", default-features = false } -sentry-core = { version = "0.38.0", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.38.1", path = "../sentry-core", default-features = false, features = [ "client", ] } actix-http = "3.10" diff --git a/sentry-anyhow/Cargo.toml b/sentry-anyhow/Cargo.toml index b5efa6cad..1d0abab81 100644 --- a/sentry-anyhow/Cargo.toml +++ b/sentry-anyhow/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-anyhow" -version = "0.38.0" +version = "0.38.1" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -17,8 +17,8 @@ default = ["backtrace"] backtrace = ["anyhow/backtrace"] [dependencies] -sentry-backtrace = { version = "0.38.0", path = "../sentry-backtrace" } -sentry-core = { version = "0.38.0", path = "../sentry-core" } +sentry-backtrace = { version = "0.38.1", path = "../sentry-backtrace" } +sentry-core = { version = "0.38.1", path = "../sentry-core" } anyhow = "1.0.39" [dev-dependencies] diff --git a/sentry-backtrace/Cargo.toml b/sentry-backtrace/Cargo.toml index 5eb597068..a5d7a6931 100644 --- a/sentry-backtrace/Cargo.toml +++ b/sentry-backtrace/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-backtrace" -version = "0.38.0" +version = "0.38.1" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -18,4 +18,4 @@ regex = { version = "1.5.5", default-features = false, features = [ "std", "unicode-perl", ] } -sentry-core = { version = "0.38.0", path = "../sentry-core" } +sentry-core = { version = "0.38.1", path = "../sentry-core" } diff --git a/sentry-contexts/Cargo.toml b/sentry-contexts/Cargo.toml index 0b3853c27..8cceacb26 100644 --- a/sentry-contexts/Cargo.toml +++ b/sentry-contexts/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-contexts" -version = "0.38.0" +version = "0.38.1" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -14,7 +14,7 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.38.0", path = "../sentry-core" } +sentry-core = { version = "0.38.1", path = "../sentry-core" } libc = "0.2.66" hostname = "0.4" diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index a5aa050fe..f83b09183 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-core" -version = "0.38.0" +version = "0.38.1" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -34,7 +34,7 @@ crc32fast = { version = "1.4.0", optional = true } log = { version = "0.4.8", optional = true, features = ["std"] } rand = { version = "0.9.0", optional = true } regex = { version = "1.7.3", optional = true } -sentry-types = { version = "0.38.0", path = "../sentry-types" } +sentry-types = { version = "0.38.1", path = "../sentry-types" } serde = { version = "1.0.104", features = ["derive"] } serde_json = { version = "1.0.46" } uuid = { version = "1.0.0", features = ["v4", "serde"], optional = true } diff --git a/sentry-core/README.md b/sentry-core/README.md index 450b0941c..aa9a42242 100644 --- a/sentry-core/README.md +++ b/sentry-core/README.md @@ -102,7 +102,7 @@ functionality. [Sentry]: https://sentry.io/ [`sentry`]: https://crates.io/crates/sentry [Unified API]: https://develop.sentry.dev/sdk/unified-api/ -[`test`]: https://docs.rs/sentry-core/0.38.0/sentry_core/test/index.html +[`test`]: https://docs.rs/sentry-core/0.38.1/sentry_core/test/index.html ## Resources diff --git a/sentry-debug-images/Cargo.toml b/sentry-debug-images/Cargo.toml index 4bd7900a6..cce22992f 100644 --- a/sentry-debug-images/Cargo.toml +++ b/sentry-debug-images/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-debug-images" -version = "0.38.0" +version = "0.38.1" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -14,4 +14,4 @@ rust-version = "1.81" [dependencies] findshlibs = "=0.10.2" -sentry-core = { version = "0.38.0", path = "../sentry-core" } +sentry-core = { version = "0.38.1", path = "../sentry-core" } diff --git a/sentry-debug-images/README.md b/sentry-debug-images/README.md index 3b664ed8e..1065e0bf4 100644 --- a/sentry-debug-images/README.md +++ b/sentry-debug-images/README.md @@ -22,7 +22,7 @@ let integration = sentry_debug_images::DebugImagesIntegration::new() .filter(|event| event.level >= Level::Warning); ``` -[`Event`]: https://docs.rs/sentry-debug-images/0.38.0/sentry_debug_images/sentry_core::protocol::Event +[`Event`]: https://docs.rs/sentry-debug-images/0.38.1/sentry_debug_images/sentry_core::protocol::Event ## Resources diff --git a/sentry-log/Cargo.toml b/sentry-log/Cargo.toml index 53339aafe..ff92bafd1 100644 --- a/sentry-log/Cargo.toml +++ b/sentry-log/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-log" -version = "0.38.0" +version = "0.38.1" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.38.0", path = "../sentry-core" } +sentry-core = { version = "0.38.1", path = "../sentry-core" } log = { version = "0.4.8", features = ["std"] } [dev-dependencies] diff --git a/sentry-opentelemetry/Cargo.toml b/sentry-opentelemetry/Cargo.toml index 3b477b456..14f9a72dc 100644 --- a/sentry-opentelemetry/Cargo.toml +++ b/sentry-opentelemetry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-opentelemetry" -version = "0.38.0" +version = "0.38.1" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -16,7 +16,7 @@ rust-version = "1.81" all-features = true [dependencies] -sentry-core = { version = "0.38.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.38.1", path = "../sentry-core", features = [ "client", ] } opentelemetry = { version = "0.29.0", default-features = false } diff --git a/sentry-panic/Cargo.toml b/sentry-panic/Cargo.toml index 2526dc701..000ecfa6d 100644 --- a/sentry-panic/Cargo.toml +++ b/sentry-panic/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-panic" -version = "0.38.0" +version = "0.38.1" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -13,8 +13,8 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.38.0", path = "../sentry-core" } -sentry-backtrace = { version = "0.38.0", path = "../sentry-backtrace" } +sentry-core = { version = "0.38.1", path = "../sentry-core" } +sentry-backtrace = { version = "0.38.1", path = "../sentry-backtrace" } [dev-dependencies] sentry = { path = "../sentry", default-features = false, features = ["test"] } diff --git a/sentry-slog/Cargo.toml b/sentry-slog/Cargo.toml index bf617011e..964882882 100644 --- a/sentry-slog/Cargo.toml +++ b/sentry-slog/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-slog" -version = "0.38.0" +version = "0.38.1" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.38.0", path = "../sentry-core" } +sentry-core = { version = "0.38.1", path = "../sentry-core" } slog = { version = "2.5.2", features = ["nested-values"] } serde_json = "1.0.46" diff --git a/sentry-tower/Cargo.toml b/sentry-tower/Cargo.toml index 5ab2b8135..b72f53a14 100644 --- a/sentry-tower/Cargo.toml +++ b/sentry-tower/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tower" -version = "0.38.0" +version = "0.38.1" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -26,7 +26,7 @@ tower-layer = "0.3" tower-service = "0.3" http = { version = "1.0.0", optional = true } pin-project = { version = "1.0.10", optional = true } -sentry-core = { version = "0.38.0", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.38.1", path = "../sentry-core", default-features = false, features = [ "client", ] } url = { version = "2.2.2", optional = true } diff --git a/sentry-tower/README.md b/sentry-tower/README.md index b4a94778e..944dea7eb 100644 --- a/sentry-tower/README.md +++ b/sentry-tower/README.md @@ -103,7 +103,7 @@ feature of the `sentry` crate instead of the `tower` feature. The created transaction will automatically use the request URI as its name. This is sometimes not desirable in case the request URI contains unique IDs or similar. In this case, users should manually override the transaction name -in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.38.0/sentry_tower/sentry_core::Scope::set_transaction) +in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.38.1/sentry_tower/sentry_core::Scope::set_transaction) method. When combining both layers, take care of the ordering of both. For example diff --git a/sentry-tracing/Cargo.toml b/sentry-tracing/Cargo.toml index 921fdeed6..ec8d927fd 100644 --- a/sentry-tracing/Cargo.toml +++ b/sentry-tracing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tracing" -version = "0.38.0" +version = "0.38.1" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -20,14 +20,14 @@ default = [] backtrace = ["dep:sentry-backtrace"] [dependencies] -sentry-core = { version = "0.38.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.38.1", path = "../sentry-core", features = [ "client", ] } tracing-core = "0.1" tracing-subscriber = { version = "0.3.1", default-features = false, features = [ "std", ] } -sentry-backtrace = { version = "0.38.0", path = "../sentry-backtrace", optional = true } +sentry-backtrace = { version = "0.38.1", path = "../sentry-backtrace", optional = true } [dev-dependencies] log = "0.4" diff --git a/sentry-tracing/README.md b/sentry-tracing/README.md index 752163648..755b0323c 100644 --- a/sentry-tracing/README.md +++ b/sentry-tracing/README.md @@ -83,7 +83,7 @@ tracing::error!( ); ``` -To track [error structs](https://docs.rs/sentry-tracing/0.38.0/sentry_tracing/std::error::Error), assign a reference to error trait object as field +To track [error structs](https://docs.rs/sentry-tracing/0.38.1/sentry_tracing/std::error::Error), assign a reference to error trait object as field in one of the logging macros. By convention, it is recommended to use the `ERROR` level and assign it to a field called `error`, although the integration will also work with all other levels and field names. diff --git a/sentry-types/Cargo.toml b/sentry-types/Cargo.toml index 9b3cd9018..f5bec5620 100644 --- a/sentry-types/Cargo.toml +++ b/sentry-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-types" -version = "0.38.0" +version = "0.38.1" authors = ["Sentry "] license = "MIT" readme = "README.md" diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index 871be7ec9..5d6347c58 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry" -version = "0.38.0" +version = "0.38.1" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -60,20 +60,20 @@ rustls = ["dep:rustls", "reqwest?/rustls-tls", "ureq?/tls", "webpki-roots"] embedded-svc-http = ["dep:embedded-svc", "dep:esp-idf-svc"] [dependencies] -sentry-core = { version = "0.38.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.38.1", path = "../sentry-core", features = [ "client", ] } -sentry-anyhow = { version = "0.38.0", path = "../sentry-anyhow", optional = true } -sentry-actix = { version = "0.38.0", path = "../sentry-actix", optional = true, default-features = false } -sentry-backtrace = { version = "0.38.0", path = "../sentry-backtrace", optional = true } -sentry-contexts = { version = "0.38.0", path = "../sentry-contexts", optional = true } -sentry-debug-images = { version = "0.38.0", path = "../sentry-debug-images", optional = true } -sentry-log = { version = "0.38.0", path = "../sentry-log", optional = true } -sentry-panic = { version = "0.38.0", path = "../sentry-panic", optional = true } -sentry-slog = { version = "0.38.0", path = "../sentry-slog", optional = true } -sentry-tower = { version = "0.38.0", path = "../sentry-tower", optional = true } -sentry-tracing = { version = "0.38.0", path = "../sentry-tracing", optional = true } -sentry-opentelemetry = { version = "0.38.0", path = "../sentry-opentelemetry", optional = true } +sentry-anyhow = { version = "0.38.1", path = "../sentry-anyhow", optional = true } +sentry-actix = { version = "0.38.1", path = "../sentry-actix", optional = true, default-features = false } +sentry-backtrace = { version = "0.38.1", path = "../sentry-backtrace", optional = true } +sentry-contexts = { version = "0.38.1", path = "../sentry-contexts", optional = true } +sentry-debug-images = { version = "0.38.1", path = "../sentry-debug-images", optional = true } +sentry-log = { version = "0.38.1", path = "../sentry-log", optional = true } +sentry-panic = { version = "0.38.1", path = "../sentry-panic", optional = true } +sentry-slog = { version = "0.38.1", path = "../sentry-slog", optional = true } +sentry-tower = { version = "0.38.1", path = "../sentry-tower", optional = true } +sentry-tracing = { version = "0.38.1", path = "../sentry-tracing", optional = true } +sentry-opentelemetry = { version = "0.38.1", path = "../sentry-opentelemetry", optional = true } log = { version = "0.4.8", optional = true, features = ["std"] } reqwest = { version = "0.12", optional = true, features = [ "blocking", diff --git a/sentry/README.md b/sentry/README.md index 6efb52e6c..8924fe41e 100644 --- a/sentry/README.md +++ b/sentry/README.md @@ -34,8 +34,8 @@ sentry::capture_message("Hello World!", sentry::Level::Info); More complex examples on how to use sentry can also be found in [examples]. Extended instructions may also be found on [Sentry itself]. -[`sentry::init`]: https://docs.rs/sentry/0.38.0/sentry/fn.init.html -[`Hub`]: https://docs.rs/sentry/0.38.0/sentry/struct.Hub.html +[`sentry::init`]: https://docs.rs/sentry/0.38.1/sentry/fn.init.html +[`Hub`]: https://docs.rs/sentry/0.38.1/sentry/struct.Hub.html [examples]: https://github.com/getsentry/sentry-rust/tree/master/sentry/examples [Sentry itself]: https://docs.sentry.io/platforms/rust @@ -47,8 +47,8 @@ the ecosystem require a feature flag. For available integrations and how to use [integrations] and [apply_defaults]. [Features]: #features -[integrations]: https://docs.rs/sentry/0.38.0/sentry/integrations/index.html -[apply_defaults]: https://docs.rs/sentry/0.38.0/sentry/fn.apply_defaults.html +[integrations]: https://docs.rs/sentry/0.38.1/sentry/integrations/index.html +[apply_defaults]: https://docs.rs/sentry/0.38.1/sentry/fn.apply_defaults.html ## Minimal API @@ -56,8 +56,8 @@ This crate comes fully-featured. If the goal is to instrument libraries for usag with sentry, or to extend sentry with a custom [`Integration`] or a [`Transport`], one should use the [`sentry-core`] crate instead. -[`Integration`]: https://docs.rs/sentry/0.38.0/sentry/trait.Integration.html -[`Transport`]: https://docs.rs/sentry/0.38.0/sentry/trait.Transport.html +[`Integration`]: https://docs.rs/sentry/0.38.1/sentry/trait.Integration.html +[`Transport`]: https://docs.rs/sentry/0.38.1/sentry/trait.Transport.html [`sentry-core`]: https://crates.io/crates/sentry-core From 7dd572bf5b0ac9976a20aa391821ca720475f076 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Fri, 16 May 2025 11:46:47 +0200 Subject: [PATCH 087/148] ci: bump actions, move to `rustsec/audit-check` (#803) * [Do not merge] CI updates * add token * more updates * update audit-check * try different codecov layout * revert codecov config update --- .github/workflows/ci.yml | 15 ++++++++------- .github/workflows/release.yml | 2 +- .github/workflows/weekly.yml | 7 +++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 059333848..a26c3cf27 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@v3 + uses: actions/checkout@v4 - run: rustup component add rustfmt clippy @@ -36,7 +36,7 @@ jobs: steps: - name: Checkout sources - uses: actions/checkout@v3 + uses: actions/checkout@v4 - uses: Swatinem/rust-cache@v2 @@ -53,7 +53,7 @@ jobs: steps: - name: Checkout sources - uses: actions/checkout@v3 + uses: actions/checkout@v4 - uses: Swatinem/rust-cache@v2 @@ -72,7 +72,7 @@ jobs: steps: - name: Checkout sources - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install rust ${{ matrix.rust }} toolchain run: | @@ -90,7 +90,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: rustup component add llvm-tools-preview @@ -100,9 +100,10 @@ jobs: - run: cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info - - uses: codecov/codecov-action@e156083f13aff6830c92fc5faa23505779fbf649 + - uses: codecov/codecov-action@v5 with: files: lcov.info + token: ${{ secrets.CODECOV_TOKEN }} doc: name: Build-test documentation @@ -112,7 +113,7 @@ jobs: steps: - name: Checkout sources - uses: actions/checkout@v3 + uses: actions/checkout@v4 - run: rustup component add rust-docs diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fe9fe02ab..1f711e048 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -22,7 +22,7 @@ jobs: app-id: ${{ vars.SENTRY_RELEASE_BOT_CLIENT_ID }} private-key: ${{ secrets.SENTRY_RELEASE_BOT_PRIVATE_KEY }} - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: token: ${{ steps.token.outputs.token }} fetch-depth: 0 diff --git a/.github/workflows/weekly.yml b/.github/workflows/weekly.yml index 33f074294..4e37ca838 100644 --- a/.github/workflows/weekly.yml +++ b/.github/workflows/weekly.yml @@ -19,7 +19,7 @@ jobs: if: github.repository_owner == 'getsentry' steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install rust stable toolchain run: | @@ -36,9 +36,8 @@ jobs: if: github.repository_owner == 'getsentry' steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - # FIXME: find a maintained alternative to audit-check - - uses: actions-rs/audit-check@v1 + - uses: rustsec/audit-check@69366f33c96575abad1ee0dba8212993eecbe998 # v2.0.0 with: token: ${{ secrets.GITHUB_TOKEN }} From bec93d2096e3a538c48393446e1a82c49d8214db Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Fri, 16 May 2025 11:47:28 +0200 Subject: [PATCH 088/148] refactor(core): remove support for `traceparent` (#807) --- Cargo.lock | 28 +++++++++--------- sentry-core/src/performance.rs | 52 ++++------------------------------ 2 files changed, 19 insertions(+), 61 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 71970158f..f8172bb2d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3161,7 +3161,7 @@ dependencies = [ [[package]] name = "sentry" -version = "0.38.0" +version = "0.38.1" dependencies = [ "actix-web", "anyhow", @@ -3198,7 +3198,7 @@ dependencies = [ [[package]] name = "sentry-actix" -version = "0.38.0" +version = "0.38.1" dependencies = [ "actix-http", "actix-web", @@ -3212,7 +3212,7 @@ dependencies = [ [[package]] name = "sentry-anyhow" -version = "0.38.0" +version = "0.38.1" dependencies = [ "anyhow", "sentry", @@ -3222,7 +3222,7 @@ dependencies = [ [[package]] name = "sentry-backtrace" -version = "0.38.0" +version = "0.38.1" dependencies = [ "backtrace", "regex", @@ -3231,7 +3231,7 @@ dependencies = [ [[package]] name = "sentry-contexts" -version = "0.38.0" +version = "0.38.1" dependencies = [ "hostname", "libc", @@ -3244,7 +3244,7 @@ dependencies = [ [[package]] name = "sentry-core" -version = "0.38.0" +version = "0.38.1" dependencies = [ "anyhow", "cadence", @@ -3266,7 +3266,7 @@ dependencies = [ [[package]] name = "sentry-debug-images" -version = "0.38.0" +version = "0.38.1" dependencies = [ "findshlibs", "sentry-core", @@ -3274,7 +3274,7 @@ dependencies = [ [[package]] name = "sentry-log" -version = "0.38.0" +version = "0.38.1" dependencies = [ "log", "pretty_env_logger", @@ -3284,7 +3284,7 @@ dependencies = [ [[package]] name = "sentry-opentelemetry" -version = "0.38.0" +version = "0.38.1" dependencies = [ "opentelemetry", "opentelemetry-semantic-conventions", @@ -3295,7 +3295,7 @@ dependencies = [ [[package]] name = "sentry-panic" -version = "0.38.0" +version = "0.38.1" dependencies = [ "sentry", "sentry-backtrace", @@ -3304,7 +3304,7 @@ dependencies = [ [[package]] name = "sentry-slog" -version = "0.38.0" +version = "0.38.1" dependencies = [ "erased-serde", "sentry", @@ -3316,7 +3316,7 @@ dependencies = [ [[package]] name = "sentry-tower" -version = "0.38.0" +version = "0.38.1" dependencies = [ "anyhow", "axum 0.8.3", @@ -3336,7 +3336,7 @@ dependencies = [ [[package]] name = "sentry-tracing" -version = "0.38.0" +version = "0.38.1" dependencies = [ "log", "sentry", @@ -3351,7 +3351,7 @@ dependencies = [ [[package]] name = "sentry-types" -version = "0.38.0" +version = "0.38.1" dependencies = [ "debugid", "hex", diff --git a/sentry-core/src/performance.rs b/sentry-core/src/performance.rs index 216b15a40..f36ed6b93 100644 --- a/sentry-core/src/performance.rs +++ b/sentry-core/src/performance.rs @@ -170,9 +170,8 @@ impl TransactionContext { /// Creates a new Transaction Context based on the distributed tracing `headers`. /// - /// The `headers` in particular need to include either the `sentry-trace` or W3C - /// `traceparent` header, which is used to associate the transaction with a distributed - /// trace. If both are present, `sentry-trace` takes precedence. + /// The `headers` in particular need to include the `sentry-trace` header, + /// which is used to associate the transaction with a distributed trace. #[must_use = "this must be used with `start_transaction`"] pub fn continue_from_headers<'a, I: IntoIterator>( name: &str, @@ -1142,8 +1141,8 @@ impl Iterator for TraceHeadersIter { } } -/// A container for distributed tracing metadata that can be extracted from e.g. HTTP headers such as -/// `sentry-trace` and `traceparent`. +/// A container for distributed tracing metadata that can be extracted from e.g. the `sentry-trace` +/// HTTP header. #[derive(Debug, PartialEq)] pub struct SentryTrace(protocol::TraceId, protocol::SpanId, Option); @@ -1173,25 +1172,8 @@ fn parse_sentry_trace(header: &str) -> Option { Some(SentryTrace(trace_id, parent_span_id, parent_sampled)) } -/// Parses a W3C traceparent header. -/// Reference: -fn parse_w3c_traceparent(header: &str) -> Option { - let header = header.trim(); - let mut parts = header.splitn(4, '-'); - - let _version = parts.next()?; - let trace_id = parts.next()?.parse().ok()?; - let parent_span_id = parts.next()?.parse().ok()?; - let parent_sampled = parts - .next() - .and_then(|sampled| u8::from_str_radix(sampled, 16).ok()) - .map(|flag| flag & 1 != 0); - - Some(SentryTrace(trace_id, parent_span_id, parent_sampled)) -} - /// Extracts distributed tracing metadata from headers (or, generally, key-value pairs), -/// considering the values for both `sentry-trace` (prioritized) and `traceparent`. +/// considering the values for `sentry-trace`. pub fn parse_headers<'a, I: IntoIterator>( headers: I, ) -> Option { @@ -1201,10 +1183,6 @@ pub fn parse_headers<'a, I: IntoIterator>( trace = parse_sentry_trace(v); break; } - - if k.eq_ignore_ascii_case("traceparent") { - trace = parse_w3c_traceparent(v); - } } trace } @@ -1241,26 +1219,6 @@ mod tests { assert_eq!(parsed, Some(trace)); } - #[test] - fn parses_traceparent() { - let trace_id = protocol::TraceId::from_str("4bf92f3577b34da6a3ce929d0e0e4736").unwrap(); - let parent_trace_id = protocol::SpanId::from_str("00f067aa0ba902b7").unwrap(); - - let trace = - parse_w3c_traceparent("00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"); - assert_eq!( - trace, - Some(SentryTrace(trace_id, parent_trace_id, Some(true))) - ); - - let trace = - parse_w3c_traceparent("00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00"); - assert_eq!( - trace, - Some(SentryTrace(trace_id, parent_trace_id, Some(false))) - ); - } - #[test] fn disabled_forwards_trace_id() { let headers = [( From 622d49a5e9c20ff6b635d361280f5ba1252e1935 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Fri, 23 May 2025 16:09:33 +0200 Subject: [PATCH 089/148] ci: adopt Danger with Sentry's shared config (#815) * ci: adopt Danger with Sentry's shared config * retrigger CI * retrigger CI --- .github/workflows/danger.yml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .github/workflows/danger.yml diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml new file mode 100644 index 000000000..000b75ff3 --- /dev/null +++ b/.github/workflows/danger.yml @@ -0,0 +1,9 @@ +name: Danger + +on: + pull_request: + types: [opened, synchronize, reopened, edited, ready_for_review] + +jobs: + danger: + uses: getsentry/github-workflows/.github/workflows/danger.yml@v2 From b3d1d59acc5a070786ee728cc855298d7bcec027 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Tue, 27 May 2025 12:44:00 +0200 Subject: [PATCH 090/148] build: remove some unused dependencies (#819) --- Cargo.lock | 28 ---------------------------- sentry-core/Cargo.toml | 3 --- sentry-opentelemetry/Cargo.toml | 1 - 3 files changed, 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f8172bb2d..0bd5fa94b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -548,15 +548,6 @@ dependencies = [ "bytes", ] -[[package]] -name = "cadence" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62fd689c825a93386a2ac05a46f88342c6df9ec3e79416f665650614e92e7475" -dependencies = [ - "crossbeam-channel", -] - [[package]] name = "camino" version = "1.1.9" @@ -818,15 +809,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" -[[package]] -name = "crossbeam-channel" -version = "0.5.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" -dependencies = [ - "crossbeam-utils", -] - [[package]] name = "crossbeam-deque" version = "0.8.6" @@ -2461,12 +2443,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "opentelemetry-semantic-conventions" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84b29a9f89f1a954936d5aa92f19b2feec3c8f3971d3e96206640db7f9706ae3" - [[package]] name = "opentelemetry_sdk" version = "0.29.0" @@ -3247,14 +3223,11 @@ name = "sentry-core" version = "0.38.1" dependencies = [ "anyhow", - "cadence", - "crc32fast", "criterion", "futures", "log", "rand 0.9.0", "rayon", - "regex", "sentry", "sentry-types", "serde", @@ -3287,7 +3260,6 @@ name = "sentry-opentelemetry" version = "0.38.1" dependencies = [ "opentelemetry", - "opentelemetry-semantic-conventions", "opentelemetry_sdk", "sentry", "sentry-core", diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index f83b09183..0068335d8 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -29,11 +29,8 @@ test = ["client", "release-health"] release-health = [] [dependencies] -cadence = { version = "1.4.0", optional = true } -crc32fast = { version = "1.4.0", optional = true } log = { version = "0.4.8", optional = true, features = ["std"] } rand = { version = "0.9.0", optional = true } -regex = { version = "1.7.3", optional = true } sentry-types = { version = "0.38.1", path = "../sentry-types" } serde = { version = "1.0.104", features = ["derive"] } serde_json = { version = "1.0.46" } diff --git a/sentry-opentelemetry/Cargo.toml b/sentry-opentelemetry/Cargo.toml index 14f9a72dc..1bced8e73 100644 --- a/sentry-opentelemetry/Cargo.toml +++ b/sentry-opentelemetry/Cargo.toml @@ -23,7 +23,6 @@ opentelemetry = { version = "0.29.0", default-features = false } opentelemetry_sdk = { version = "0.29.0", default-features = false, features = [ "trace", ] } -opentelemetry-semantic-conventions = "0.29.0" [dev-dependencies] sentry = { path = "../sentry", features = ["test", "opentelemetry"] } From ae9779f9a9dd107e6ec9b2205f5929911eb05b03 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Tue, 27 May 2025 13:50:39 +0200 Subject: [PATCH 091/148] refactor: remove `debug-logs` feature (#820) --- CHANGELOG.md | 7 +++++++ sentry-core/Cargo.toml | 3 --- sentry-core/README.md | 3 --- sentry-core/src/lib.rs | 3 --- sentry-core/src/macros.rs | 17 ++++++----------- sentry/Cargo.toml | 2 -- sentry/README.md | 2 -- sentry/src/lib.rs | 2 -- 8 files changed, 13 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 687a9227c..aa586ef98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +### Unreleased + +### Breaking changes + +- refactor: remove `debug-logs` feature (#820) by @lcian + - The deprecated `debug-logs` feature of the `sentry` crate has been removed. + ## 0.38.1 ### Fixes diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index 0068335d8..572a3e040 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -22,9 +22,6 @@ harness = false [features] default = [] client = ["rand"] -# I would love to just have a `log` feature, but this is used inside a macro, -# and macros actually expand features (and extern crate) where they are used! -debug-logs = ["dep:log"] test = ["client", "release-health"] release-health = [] diff --git a/sentry-core/README.md b/sentry-core/README.md index aa9a42242..d6118d384 100644 --- a/sentry-core/README.md +++ b/sentry-core/README.md @@ -95,9 +95,6 @@ functionality. - `feature = "test"`: Activates the [`test`] module, which can be used to write integration tests. It comes with a test transport which can capture all sent events for inspection. -- `feature = "debug-logs"`: Uses the `log` crate for debug output, instead - of printing to `stderr`. This feature is **deprecated** and will be - replaced by a dedicated log callback in the future. [Sentry]: https://sentry.io/ [`sentry`]: https://crates.io/crates/sentry diff --git a/sentry-core/src/lib.rs b/sentry-core/src/lib.rs index db1b511ac..5b674db95 100644 --- a/sentry-core/src/lib.rs +++ b/sentry-core/src/lib.rs @@ -93,9 +93,6 @@ //! - `feature = "test"`: Activates the [`test`] module, which can be used to //! write integration tests. It comes with a test transport which can capture //! all sent events for inspection. -//! - `feature = "debug-logs"`: Uses the `log` crate for debug output, instead -//! of printing to `stderr`. This feature is **deprecated** and will be -//! replaced by a dedicated log callback in the future. //! //! [Sentry]: https://sentry.io/ //! [`sentry`]: https://crates.io/crates/sentry diff --git a/sentry-core/src/macros.rs b/sentry-core/src/macros.rs index 34209d05a..edb75dcd5 100644 --- a/sentry-core/src/macros.rs +++ b/sentry-core/src/macros.rs @@ -55,17 +55,12 @@ macro_rules! with_client_impl { #[doc(hidden)] macro_rules! sentry_debug { ($($arg:tt)*) => { - #[cfg(feature = "debug-logs")] { - ::log::debug!(target: "sentry", $($arg)*); - } - #[cfg(not(feature = "debug-logs"))] { - $crate::Hub::with(|hub| { - if hub.client().map_or(false, |c| c.options().debug) { - eprint!("[sentry] "); - eprintln!($($arg)*); - } - }); - } + $crate::Hub::with(|hub| { + if hub.client().map_or(false, |c| c.options().debug) { + eprint!("[sentry] "); + eprintln!($($arg)*); + } + }); } } diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index 5d6347c58..8e798195a 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -47,7 +47,6 @@ tracing = ["sentry-tracing"] opentelemetry = ["sentry-opentelemetry"] # other features test = ["sentry-core/test"] -debug-logs = ["dep:log", "sentry-core/debug-logs"] release-health = ["sentry-core/release-health", "sentry-actix?/release-health"] # transports transport = ["reqwest", "native-tls"] @@ -74,7 +73,6 @@ sentry-slog = { version = "0.38.1", path = "../sentry-slog", optional = true } sentry-tower = { version = "0.38.1", path = "../sentry-tower", optional = true } sentry-tracing = { version = "0.38.1", path = "../sentry-tracing", optional = true } sentry-opentelemetry = { version = "0.38.1", path = "../sentry-opentelemetry", optional = true } -log = { version = "0.4.8", optional = true, features = ["std"] } reqwest = { version = "0.12", optional = true, features = [ "blocking", "json", diff --git a/sentry/README.md b/sentry/README.md index 8924fe41e..c28116cca 100644 --- a/sentry/README.md +++ b/sentry/README.md @@ -76,7 +76,6 @@ extra setup to function properly. | `test` | | | | | | `debug-images` | ✅ | 🔌 | | | | `log` | | 🔌 | | Requires extra setup; See [`sentry-log`]'s documentation. | -| `debug-logs` | | | ❗ | Requires extra setup; See [`sentry-log`]'s documentation. | | `slog` | | 🔌 | | Requires extra setup; See [`sentry-slog`]'s documentation. | | `reqwest` | ✅ | | | | | `native-tls` | ✅ | | | `reqwest` must be enabled. | @@ -110,7 +109,6 @@ extra setup to function properly. ### Logging - `log`: Enables support for the `log` crate. - `slog`: Enables support for the `slog` crate. -- `debug-logs`: **Deprecated**. Uses the `log` crate for internal logging. ### Transports - `reqwest`: **Default**. Enables the `reqwest` transport. diff --git a/sentry/src/lib.rs b/sentry/src/lib.rs index 6e9c49022..a2d2d5178 100644 --- a/sentry/src/lib.rs +++ b/sentry/src/lib.rs @@ -68,7 +68,6 @@ //! | `test` | | | | | //! | `debug-images` | ✅ | 🔌 | | | //! | `log` | | 🔌 | | Requires extra setup; See [`sentry-log`]'s documentation. | -//! | `debug-logs` | | | ❗ | Requires extra setup; See [`sentry-log`]'s documentation. | //! | `slog` | | 🔌 | | Requires extra setup; See [`sentry-slog`]'s documentation. | //! | `reqwest` | ✅ | | | | //! | `native-tls` | ✅ | | | `reqwest` must be enabled. | @@ -102,7 +101,6 @@ //! ## Logging //! - `log`: Enables support for the `log` crate. //! - `slog`: Enables support for the `slog` crate. -//! - `debug-logs`: **Deprecated**. Uses the `log` crate for internal logging. //! //! ## Transports //! - `reqwest`: **Default**. Enables the `reqwest` transport. From cb7be0eb52aefaf12e2d1ccd8d53ccf95af2b694 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Tue, 27 May 2025 15:43:08 +0200 Subject: [PATCH 092/148] feat(core): implement Tracing without Performance (#811) Co-authored-by: Daniel Szoke <7881302+szokeasaurusrex@users.noreply.github.com> --- CHANGELOG.md | 11 ++++-- sentry-core/src/performance.rs | 61 ++++++++++++++++++++++++--------- sentry-core/src/scope/real.rs | 35 ++++++++++++++++++- sentry-types/src/protocol/v7.rs | 16 +++++++-- sentry/tests/test_basic.rs | 21 +++++++++++- 5 files changed, 121 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa586ef98..ba719c8e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,18 @@ # Changelog -### Unreleased +## Unreleased ### Breaking changes - refactor: remove `debug-logs` feature (#820) by @lcian - - The deprecated `debug-logs` feature of the `sentry` crate has been removed. + - The deprecated `debug-logs` feature of the `sentry` crate, used for the SDK's own internal logging, has been removed. + +### Behavioral changes + +- feat(core): implement Tracing without Performance (#811) by @lcian + - The SDK now implements Tracing without Performance, which makes it so that each `Scope` is associated with an object holding some tracing information. + - This information is used as a fallback when capturing an event with tracing disabled or otherwise no ongoing span, to still allow related events to be linked by a trace. + - A new API `Scope::iter_trace_propagation_headers` has been provided that will use the fallback tracing information if there is no current `Span` on the `Scope`. ## 0.38.1 diff --git a/sentry-core/src/performance.rs b/sentry-core/src/performance.rs index f36ed6b93..39ee2363e 100644 --- a/sentry-core/src/performance.rs +++ b/sentry-core/src/performance.rs @@ -199,14 +199,12 @@ impl TransactionContext { sentry_trace: &SentryTrace, span_id: Option, ) -> Self { - let (trace_id, parent_span_id, sampled) = - (sentry_trace.0, Some(sentry_trace.1), sentry_trace.2); Self { name: name.into(), op: op.into(), - trace_id, - parent_span_id, - sampled, + trace_id: sentry_trace.trace_id, + parent_span_id: Some(sentry_trace.span_id), + sampled: sentry_trace.sampled, span_id: span_id.unwrap_or_default(), custom: None, } @@ -476,6 +474,8 @@ impl TransactionOrSpan { } /// Returns the headers needed for distributed tracing. + /// Use [`crate::Scope::iter_trace_propagation_headers`] to obtain the active + /// trace's distributed tracing headers. pub fn iter_headers(&self) -> TraceHeadersIter { match self { TransactionOrSpan::Transaction(transaction) => transaction.iter_headers(), @@ -774,9 +774,11 @@ impl Transaction { } /// Returns the headers needed for distributed tracing. + /// Use [`crate::Scope::iter_trace_propagation_headers`] to obtain the active + /// trace's distributed tracing headers. pub fn iter_headers(&self) -> TraceHeadersIter { let inner = self.inner.lock().unwrap(); - let trace = SentryTrace( + let trace = SentryTrace::new( inner.context.trace_id, inner.context.span_id, Some(inner.sampled), @@ -1026,9 +1028,11 @@ impl Span { } /// Returns the headers needed for distributed tracing. + /// Use [`crate::Scope::iter_trace_propagation_headers`] to obtain the active + /// trace's distributed tracing headers. pub fn iter_headers(&self) -> TraceHeadersIter { let span = self.span.lock().unwrap(); - let trace = SentryTrace(span.trace_id, span.span_id, Some(self.sampled)); + let trace = SentryTrace::new(span.trace_id, span.span_id, Some(self.sampled)); TraceHeadersIter { sentry_trace: Some(trace.to_string()), } @@ -1125,6 +1129,9 @@ impl Span { } } +/// Represents a key-value pair such as an HTTP header. +pub type TraceHeader = (&'static str, String); + /// An Iterator over HTTP header names and values needed for distributed tracing. /// /// This currently only yields the `sentry-trace` header, but other headers @@ -1133,6 +1140,15 @@ pub struct TraceHeadersIter { sentry_trace: Option, } +impl TraceHeadersIter { + #[cfg(feature = "client")] + pub(crate) fn new(sentry_trace: String) -> Self { + Self { + sentry_trace: Some(sentry_trace), + } + } +} + impl Iterator for TraceHeadersIter { type Item = (&'static str, String); @@ -1143,8 +1159,12 @@ impl Iterator for TraceHeadersIter { /// A container for distributed tracing metadata that can be extracted from e.g. the `sentry-trace` /// HTTP header. -#[derive(Debug, PartialEq)] -pub struct SentryTrace(protocol::TraceId, protocol::SpanId, Option); +#[derive(Debug, PartialEq, Clone, Copy, Default)] +pub struct SentryTrace { + pub(crate) trace_id: protocol::TraceId, + pub(crate) span_id: protocol::SpanId, + pub(crate) sampled: Option, +} impl SentryTrace { /// Creates a new [`SentryTrace`] from the provided parameters @@ -1153,7 +1173,11 @@ impl SentryTrace { span_id: protocol::SpanId, sampled: Option, ) -> Self { - SentryTrace(trace_id, span_id, sampled) + SentryTrace { + trace_id, + span_id, + sampled, + } } } @@ -1169,7 +1193,7 @@ fn parse_sentry_trace(header: &str) -> Option { _ => None, }); - Some(SentryTrace(trace_id, parent_span_id, parent_sampled)) + Some(SentryTrace::new(trace_id, parent_span_id, parent_sampled)) } /// Extracts distributed tracing metadata from headers (or, generally, key-value pairs), @@ -1189,8 +1213,8 @@ pub fn parse_headers<'a, I: IntoIterator>( impl std::fmt::Display for SentryTrace { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}-{}", self.0, self.1)?; - if let Some(sampled) = self.2 { + write!(f, "{}-{}", self.trace_id, self.span_id)?; + if let Some(sampled) = self.sampled { write!(f, "-{}", if sampled { '1' } else { '0' })?; } Ok(()) @@ -1211,10 +1235,10 @@ mod tests { let trace = parse_sentry_trace("09e04486820349518ac7b5d2adbf6ba5-9cf635fa5b870b3a-0"); assert_eq!( trace, - Some(SentryTrace(trace_id, parent_trace_id, Some(false))) + Some(SentryTrace::new(trace_id, parent_trace_id, Some(false))) ); - let trace = SentryTrace(Default::default(), Default::default(), None); + let trace = SentryTrace::new(Default::default(), Default::default(), None); let parsed = parse_sentry_trace(&trace.to_string()); assert_eq!(parsed, Some(trace)); } @@ -1233,8 +1257,11 @@ mod tests { let header = span.iter_headers().next().unwrap().1; let parsed = parse_sentry_trace(&header).unwrap(); - assert_eq!(&parsed.0.to_string(), "09e04486820349518ac7b5d2adbf6ba5"); - assert_eq!(parsed.2, Some(true)); + assert_eq!( + &parsed.trace_id.to_string(), + "09e04486820349518ac7b5d2adbf6ba5" + ); + assert_eq!(parsed.sampled, Some(true)); } #[test] diff --git a/sentry-core/src/scope/real.rs b/sentry-core/src/scope/real.rs index 7c4eda471..47b1e9da0 100644 --- a/sentry-core/src/scope/real.rs +++ b/sentry-core/src/scope/real.rs @@ -5,11 +5,13 @@ use std::fmt; use std::sync::Mutex; use std::sync::{Arc, PoisonError, RwLock}; +use sentry_types::protocol::v7::TraceContext; + use crate::performance::TransactionOrSpan; use crate::protocol::{Attachment, Breadcrumb, Context, Event, Level, Transaction, User, Value}; #[cfg(feature = "release-health")] use crate::session::Session; -use crate::Client; +use crate::{Client, SentryTrace, TraceHeader, TraceHeadersIter}; #[derive(Debug)] pub struct Stack { @@ -52,6 +54,7 @@ pub struct Scope { pub(crate) session: Arc>>, pub(crate) span: Arc>, pub(crate) attachments: Arc>, + pub(crate) propagation_context: SentryTrace, } impl fmt::Debug for Scope { @@ -74,6 +77,7 @@ impl fmt::Debug for Scope { debug_struct .field("span", &self.span) .field("attachments", &self.attachments.len()) + .field("propagation_context", &self.propagation_context) .finish() } } @@ -289,6 +293,8 @@ impl Scope { if let Some(span) = self.span.as_ref() { span.apply_to_event(&mut event); + } else { + self.apply_propagation_context(&mut event); } if event.transaction.is_none() { @@ -357,4 +363,31 @@ impl Scope { session.update_from_event(event); } } + + pub(crate) fn apply_propagation_context(&self, event: &mut Event<'_>) { + if event.contexts.contains_key("trace") { + return; + } + + let context = TraceContext { + trace_id: self.propagation_context.trace_id, + span_id: self.propagation_context.span_id, + ..Default::default() + }; + event.contexts.insert("trace".into(), context.into()); + } + + /// Returns the headers needed for distributed tracing. + pub fn iter_trace_propagation_headers(&self) -> impl Iterator { + if let Some(span) = self.get_span() { + span.iter_headers() + } else { + let data = SentryTrace::new( + self.propagation_context.trace_id, + self.propagation_context.span_id, + None, + ); + TraceHeadersIter::new(data.to_string()) + } + } } diff --git a/sentry-types/src/protocol/v7.rs b/sentry-types/src/protocol/v7.rs index bb2008f60..12de86392 100644 --- a/sentry-types/src/protocol/v7.rs +++ b/sentry-types/src/protocol/v7.rs @@ -1352,7 +1352,7 @@ pub struct OtelContext { } /// Holds the identifier for a Span -#[derive(Serialize, Deserialize, Debug, Copy, Clone, Eq, PartialEq, Hash)] +#[derive(Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Hash)] #[serde(try_from = "String", into = "String")] pub struct SpanId([u8; 8]); @@ -1368,6 +1368,12 @@ impl fmt::Display for SpanId { } } +impl fmt::Debug for SpanId { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!(fmt, "SpanId({})", self) + } +} + impl From for String { fn from(span_id: SpanId) -> Self { span_id.to_string() @@ -1399,7 +1405,7 @@ impl From<[u8; 8]> for SpanId { } /// Holds the identifier for a Trace -#[derive(Serialize, Deserialize, Debug, Copy, Clone, Eq, PartialEq, Hash)] +#[derive(Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Hash)] #[serde(try_from = "String", into = "String")] pub struct TraceId([u8; 16]); @@ -1415,6 +1421,12 @@ impl fmt::Display for TraceId { } } +impl fmt::Debug for TraceId { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!(fmt, "TraceId({})", self) + } +} + impl From for String { fn from(trace_id: TraceId) -> Self { trace_id.to_string() diff --git a/sentry/tests/test_basic.rs b/sentry/tests/test_basic.rs index 3813b14ea..dac87e373 100644 --- a/sentry/tests/test_basic.rs +++ b/sentry/tests/test_basic.rs @@ -3,7 +3,7 @@ use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; -use sentry::protocol::{Attachment, EnvelopeItem}; +use sentry::protocol::{Attachment, Context, EnvelopeItem}; use sentry::types::Uuid; #[test] @@ -28,6 +28,25 @@ fn test_basic_capture_message() { assert_eq!(Some(event.event_id), last_event_id); } +#[test] +fn test_event_trace_context_from_propagation_context() { + let mut last_event_id = None::; + let mut span = None; + let events = sentry::test::with_captured_events(|| { + sentry::configure_scope(|scope| { + span = scope.get_span(); + }); + sentry::capture_message("Hello World!", sentry::Level::Warning); + last_event_id = sentry::last_event_id(); + }); + assert_eq!(events.len(), 1); + let event = events.into_iter().next().unwrap(); + + let trace_context = event.contexts.get("trace"); + assert!(span.is_none()); + assert!(matches!(trace_context, Some(Context::Trace(_)))); +} + #[test] fn test_breadcrumbs() { let events = sentry::test::with_captured_events(|| { From 9c65afef5b56958fba4bd2ac4f9f64c52b579d8c Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Tue, 27 May 2025 17:39:43 +0200 Subject: [PATCH 093/148] fix: fix clippy lints on stable (#822) --- sentry-actix/examples/basic.rs | 2 +- sentry-actix/src/lib.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sentry-actix/examples/basic.rs b/sentry-actix/examples/basic.rs index 6e4544fbc..acde8561a 100644 --- a/sentry-actix/examples/basic.rs +++ b/sentry-actix/examples/basic.rs @@ -11,7 +11,7 @@ async fn healthy(_req: HttpRequest) -> Result { #[get("/err")] async fn errors(_req: HttpRequest) -> Result { - Err(io::Error::new(io::ErrorKind::Other, "An error happens here").into()) + Err(io::Error::other("An error happens here").into()) } #[get("/msg")] diff --git a/sentry-actix/src/lib.rs b/sentry-actix/src/lib.rs index 78938d548..4a2de94fe 100644 --- a/sentry-actix/src/lib.rs +++ b/sentry-actix/src/lib.rs @@ -589,7 +589,7 @@ mod tests { // Current hub should have no events _assert_hub_no_events(); - Err(io::Error::new(io::ErrorKind::Other, "Test Error").into()) + Err(io::Error::other("Test Error").into()) } let app = init_service( @@ -652,7 +652,7 @@ mod tests { async fn original_transaction(_req: HttpRequest) -> Result { // Override transaction name sentry::configure_scope(|scope| scope.set_transaction(Some("new_transaction"))); - Err(io::Error::new(io::ErrorKind::Other, "Test Error").into()) + Err(io::Error::other("Test Error").into()) } let app = init_service( From 7abbb38d75f79c2c8e5afd350059dcc09fe77f9b Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Fri, 6 Jun 2025 09:47:17 +0200 Subject: [PATCH 094/148] feat(logs): add log protocol types (#821) --- CHANGELOG.md | 7 + sentry-types/src/protocol/envelope.rs | 141 ++++++++++++++-- sentry-types/src/protocol/v7.rs | 214 +++++++++++++++++++++++++ sentry-types/tests/test_protocol_v7.rs | 41 +++++ 4 files changed, 392 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba719c8e2..74b3b97bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,13 @@ - This information is used as a fallback when capturing an event with tracing disabled or otherwise no ongoing span, to still allow related events to be linked by a trace. - A new API `Scope::iter_trace_propagation_headers` has been provided that will use the fallback tracing information if there is no current `Span` on the `Scope`. +### Features + +- feat(logs): add log protocol types (#821) by @lcian + - Basic types for [Sentry structured logs](https://docs.sentry.io/product/explore/logs/) have been added. + - It's possible (but not recommended) to use them to send logs to Sentry by directly constructing an `Envelope` containing an `ItemContainer::Logs` envelope item and sending it through `Client::send_envelope`. + - A high-level API and integrations will come soon. + ## 0.38.1 ### Fixes diff --git a/sentry-types/src/protocol/envelope.rs b/sentry-types/src/protocol/envelope.rs index 1d7452f6d..006c59caf 100644 --- a/sentry-types/src/protocol/envelope.rs +++ b/sentry-types/src/protocol/envelope.rs @@ -1,13 +1,13 @@ use std::{io::Write, path::Path}; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; use thiserror::Error; use uuid::Uuid; use super::v7 as protocol; use protocol::{ - Attachment, AttachmentType, Event, MonitorCheckIn, SessionAggregates, SessionUpdate, + Attachment, AttachmentType, Event, Log, MonitorCheckIn, SessionAggregates, SessionUpdate, Transaction, }; @@ -61,9 +61,12 @@ enum EnvelopeItemType { /// An Attachment Item type. #[serde(rename = "attachment")] Attachment, - /// A Monitor Check In Item Type + /// A Monitor Check In Item Type. #[serde(rename = "check_in")] MonitorCheckIn, + /// A container of Log items. + #[serde(rename = "log")] + LogsContainer, } /// An Envelope Item Header. @@ -71,10 +74,11 @@ enum EnvelopeItemType { struct EnvelopeItemHeader { r#type: EnvelopeItemType, length: Option, - // Fields below apply only to Attachment Item type + // Applies both to Attachment and ItemContainer Item type + content_type: Option, + // Fields below apply only to Attachment Item types filename: Option, attachment_type: Option, - content_type: Option, } /// An Envelope Item. @@ -112,12 +116,64 @@ pub enum EnvelopeItem { Attachment(Attachment), /// A MonitorCheckIn item. MonitorCheckIn(MonitorCheckIn), + /// A container for a list of multiple items. + ItemContainer(ItemContainer), /// This is a sentinel item used to `filter` raw envelopes. Raw, // TODO: // etc… } +/// A container for a list of multiple items. +/// It's considered a single envelope item, with its `type` corresponding to the contained items' +/// `type`. +#[derive(Clone, Debug, PartialEq)] +#[non_exhaustive] +pub enum ItemContainer { + /// A list of logs. + Logs(Vec), +} + +#[allow(clippy::len_without_is_empty, reason = "is_empty is not needed")] +impl ItemContainer { + /// The number of items in this item container. + pub fn len(&self) -> usize { + match self { + Self::Logs(logs) => logs.len(), + } + } + + /// The `type` of this item container, which corresponds to the `type` of the contained items. + pub fn ty(&self) -> &'static str { + match self { + Self::Logs(_) => "log", + } + } + + /// The `content-type` expected by Relay for this item container. + pub fn content_type(&self) -> &'static str { + match self { + Self::Logs(_) => "application/vnd.sentry.items.log+json", + } + } +} + +impl From> for ItemContainer { + fn from(logs: Vec) -> Self { + Self::Logs(logs) + } +} + +#[derive(Serialize)] +struct LogsSerializationWrapper<'a> { + items: &'a [Log], +} + +#[derive(Deserialize)] +struct LogsDeserializationWrapper { + items: Vec, +} + impl From> for EnvelopeItem { fn from(event: Event<'static>) -> Self { EnvelopeItem::Event(event) @@ -154,6 +210,18 @@ impl From for EnvelopeItem { } } +impl From for EnvelopeItem { + fn from(container: ItemContainer) -> Self { + EnvelopeItem::ItemContainer(container) + } +} + +impl From> for EnvelopeItem { + fn from(logs: Vec) -> Self { + EnvelopeItem::ItemContainer(logs.into()) + } +} + /// An Iterator over the items of an Envelope. #[derive(Clone)] pub struct EnvelopeItemIter<'s> { @@ -352,6 +420,12 @@ impl Envelope { EnvelopeItem::MonitorCheckIn(check_in) => { serde_json::to_writer(&mut item_buf, check_in)? } + EnvelopeItem::ItemContainer(container) => match container { + ItemContainer::Logs(logs) => { + let wrapper = LogsSerializationWrapper { items: logs }; + serde_json::to_writer(&mut item_buf, &wrapper)? + } + }, EnvelopeItem::Raw => { continue; } @@ -362,14 +436,26 @@ impl Envelope { EnvelopeItem::SessionAggregates(_) => "sessions", EnvelopeItem::Transaction(_) => "transaction", EnvelopeItem::MonitorCheckIn(_) => "check_in", + EnvelopeItem::ItemContainer(container) => container.ty(), EnvelopeItem::Attachment(_) | EnvelopeItem::Raw => unreachable!(), }; - writeln!( - writer, - r#"{{"type":"{}","length":{}}}"#, - item_type, - item_buf.len() - )?; + + if let EnvelopeItem::ItemContainer(container) = item { + writeln!( + writer, + r#"{{"type":"{}","item_count":{},"content_type":"{}"}}"#, + item_type, + container.len(), + container.content_type() + )?; + } else { + writeln!( + writer, + r#"{{"type":"{}","length":{}}}"#, + item_type, + item_buf.len() + )?; + } writer.write_all(&item_buf)?; writeln!(writer)?; item_buf.clear(); @@ -506,6 +592,10 @@ impl Envelope { EnvelopeItemType::MonitorCheckIn => { serde_json::from_slice(payload).map(EnvelopeItem::MonitorCheckIn) } + EnvelopeItemType::LogsContainer => { + serde_json::from_slice::(payload) + .map(|x| EnvelopeItem::ItemContainer(ItemContainer::Logs(x.items))) + } } .map_err(EnvelopeError::InvalidItemPayload)?; @@ -536,6 +626,7 @@ mod test { use std::str::FromStr; use std::time::{Duration, SystemTime}; + use protocol::Map; use time::format_description::well_known::Rfc3339; use time::OffsetDateTime; @@ -969,12 +1060,40 @@ some content ..Default::default() }; + let mut attributes = Map::new(); + attributes.insert("key".into(), "value".into()); + attributes.insert("num".into(), 10.into()); + attributes.insert("val".into(), 10.2.into()); + attributes.insert("bool".into(), false.into()); + let mut attributes_2 = attributes.clone(); + attributes_2.insert("more".into(), true.into()); + let logs: EnvelopeItem = vec![ + Log { + level: protocol::LogLevel::Warn, + body: "test".to_owned(), + trace_id: "335e53d614474acc9f89e632b776cc28".parse().unwrap(), + timestamp: timestamp("2022-07-25T14:51:14.296Z"), + severity_number: Some(1.try_into().unwrap()), + attributes, + }, + Log { + level: protocol::LogLevel::Error, + body: "a body".to_owned(), + trace_id: "332253d614472a2c9f89e232b7762c28".parse().unwrap(), + timestamp: timestamp("2021-07-21T14:51:14.296Z"), + severity_number: Some(1.try_into().unwrap()), + attributes: attributes_2, + }, + ] + .into(); + let mut envelope: Envelope = Envelope::new(); envelope.add_item(event); envelope.add_item(transaction); envelope.add_item(session); envelope.add_item(attachment); + envelope.add_item(logs); let serialized = to_str(envelope); let deserialized = Envelope::from_slice(serialized.as_bytes()).unwrap(); diff --git a/sentry-types/src/protocol/v7.rs b/sentry-types/src/protocol/v7.rs index 12de86392..d984035a1 100644 --- a/sentry-types/src/protocol/v7.rs +++ b/sentry-types/src/protocol/v7.rs @@ -2118,3 +2118,217 @@ impl fmt::Display for Transaction<'_> { ) } } + +/// A single [structured log](https://docs.sentry.io/product/explore/logs/). +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct Log { + /// The severity of the log (required). + pub level: LogLevel, + /// The log body/message (required). + pub body: String, + /// The ID of the Trace in which this log happened (required). + pub trace_id: TraceId, + /// The timestamp of the log (required). + #[serde(with = "ts_seconds_float")] + pub timestamp: SystemTime, + /// The severity number of the log. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub severity_number: Option, + /// Additional arbitrary attributes attached to the log. + #[serde(default, skip_serializing_if = "Map::is_empty")] + pub attributes: Map, +} + +/// Indicates the severity of a log, according to the +/// OpenTelemetry [`SeverityText`](https://opentelemetry.io/docs/specs/otel/logs/data-model/#field-severitytext) spec. +#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq)] +#[serde(rename_all = "lowercase")] +pub enum LogLevel { + /// A fine-grained debugging event. + Trace, + /// A debugging event. + Debug, + /// An informational event. Indicates that an event happened. + Info, + /// A warning event. Not an error but is likely more important than an informational event. + Warn, + /// An error event. Something went wrong. + Error, + /// A fatal error such as application or system crash. + Fatal, +} + +/// A number indicating the severity of a log, according to the OpenTelemetry +/// [`SeverityNumber`](https://opentelemetry.io/docs/specs/otel/logs/data-model/#field-severitynumber) spec. +#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq)] +pub struct LogSeverityNumber(u8); + +impl LogSeverityNumber { + /// The minimum severity number. + pub const MIN: u8 = 1; + /// The maximum severity number. + pub const MAX: u8 = 24; +} + +impl TryFrom for LogSeverityNumber { + type Error = String; + + fn try_from(value: u8) -> Result { + if (LogSeverityNumber::MIN..=LogSeverityNumber::MAX).contains(&value) { + Ok(Self(value)) + } else { + Err(format!( + "Log severity number must be between {} and {}", + LogSeverityNumber::MIN, + LogSeverityNumber::MAX + )) + } + } +} + +/// An attribute that can be attached to a log. +#[derive(Clone, Debug, PartialEq)] +pub struct LogAttribute(pub Value); + +impl From for LogAttribute +where + Value: From, +{ + fn from(value: T) -> Self { + Self(Value::from(value)) + } +} + +impl Serialize for LogAttribute { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut state = serializer.serialize_struct("LogAttribute", 2)?; + + match &self.0 { + Value::String(s) => { + state.serialize_field("value", s.as_str())?; + state.serialize_field("type", "string")?; + } + Value::Number(n) => { + if let Some(i) = n.as_i64() { + state.serialize_field("value", &i)?; + state.serialize_field("type", "integer")?; + } else if let Some(f) = n.as_f64() { + state.serialize_field("value", &f)?; + state.serialize_field("type", "double")?; + } else { + // This should be unreachable, as a `Value::Number` can only be built from an i64, u64 or f64 + state.serialize_field("value", &n.to_string())?; + state.serialize_field("type", "string")?; + } + } + Value::Bool(b) => { + state.serialize_field("value", &b)?; + state.serialize_field("type", "boolean")?; + } + // For any other type (Null, Array, Object), convert to string with JSON representation + _ => { + state.serialize_field("value", &self.0.to_string())?; + state.serialize_field("type", "string")?; + } + } + + state.end() + } +} + +impl<'de> Deserialize<'de> for LogAttribute { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + use serde::de::{self, MapAccess, Visitor}; + use std::fmt; + + struct LogAttributeVisitor; + + impl<'de> Visitor<'de> for LogAttributeVisitor { + type Value = LogAttribute; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a LogAttribute with value and type fields") + } + + fn visit_map(self, mut map: V) -> Result + where + V: MapAccess<'de>, + { + let mut value: Option = None; + let mut type_str: Option = None; + + while let Some(key) = map.next_key::()? { + match key.as_str() { + "value" => { + if value.is_some() { + return Err(de::Error::duplicate_field("value")); + } + value = Some(map.next_value()?); + } + "type" => { + if type_str.is_some() { + return Err(de::Error::duplicate_field("type")); + } + type_str = Some(map.next_value()?); + } + _ => { + // Ignore unknown fields + let _: serde_json::Value = map.next_value()?; + } + } + } + + let value = value.ok_or_else(|| de::Error::missing_field("value"))?; + let type_str = type_str.ok_or_else(|| de::Error::missing_field("type"))?; + + match type_str.as_str() { + "string" => { + if !value.is_string() { + return Err(de::Error::custom( + "type is 'string' but value is not a string", + )); + } + } + "integer" => { + if !value.is_i64() { + return Err(de::Error::custom( + "type is 'integer' but value is not an integer", + )); + } + } + "double" => { + if !value.is_f64() { + return Err(de::Error::custom( + "type is 'double' but value is not a double", + )); + } + } + "boolean" => { + if !value.is_boolean() { + return Err(de::Error::custom( + "type is 'boolean' but value is not a boolean", + )); + } + } + _ => { + return Err(de::Error::custom(format!( + "expected type to be 'string' | 'integer' | 'double' | 'boolean', found {}", + type_str + ))) + } + } + + Ok(LogAttribute(value)) + } + } + + deserializer.deserialize_map(LogAttributeVisitor) + } +} diff --git a/sentry-types/tests/test_protocol_v7.rs b/sentry-types/tests/test_protocol_v7.rs index ea5b92756..88a567cc2 100644 --- a/sentry-types/tests/test_protocol_v7.rs +++ b/sentry-types/tests/test_protocol_v7.rs @@ -1523,3 +1523,44 @@ fn test_orientation() { "\"portrait\"" ); } + +mod test_logs { + use sentry_types::protocol::v7::LogAttribute; + use serde_json::{json, Value}; + + #[test] + fn test_log_attribute_serialization() { + let attributes: Vec<(LogAttribute, &str)> = vec![ + // Supported types + (42.into(), r#"{"value":42,"type":"integer"}"#), + (3.1.into(), r#"{"value":3.1,"type":"double"}"#), + ("lol".into(), r#"{"value":"lol","type":"string"}"#), + (false.into(), r#"{"value":false,"type":"boolean"}"#), + // Special case + (Value::Null.into(), r#"{"value":"null","type":"string"}"#), + // Unsupported types (for now) + ( + json!(r#"[1,2,3,4]"#).into(), + r#"{"value":"[1,2,3,4]","type":"string"}"#, + ), + ( + json!(r#"["a","b","c"]"#).into(), + r#"{"value":"[\"a\",\"b\",\"c\"]","type":"string"}"#, + ), + ]; + for (attribute, expected) in attributes { + let actual = serde_json::to_string(&attribute).unwrap(); + assert_eq!(expected, actual); + } + } + + #[test] + fn test_log_attribute_roundtrip() { + let attributes: Vec = vec![42.into(), 3.1.into(), "lol".into(), false.into()]; + for expected in attributes { + let serialized = serde_json::to_string(&expected).unwrap(); + let actual: LogAttribute = serde_json::from_str(&serialized).unwrap(); + assert_eq!(expected, actual); + } + } +} From d668e7d2f9adad2662e4c9ea4a5bb53c71d146e1 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Fri, 6 Jun 2025 10:04:49 +0200 Subject: [PATCH 095/148] feat(logs): add ability to capture and send logs (#823) Co-authored-by: Arpad Borsos --- CHANGELOG.md | 7 ++- sentry-core/Cargo.toml | 1 + sentry-core/src/client.rs | 85 ++++++++++++++++++++++++++- sentry-core/src/clientoptions.rs | 28 ++++++++- sentry-core/src/hub.rs | 12 +++- sentry-core/src/scope/noop.rs | 9 +++ sentry-core/src/scope/real.rs | 61 ++++++++++++++++++- sentry-types/src/protocol/envelope.rs | 4 +- sentry-types/src/protocol/v7.rs | 3 +- sentry/Cargo.toml | 1 + sentry/tests/test_basic.rs | 49 +++++++++++++++ 11 files changed, 247 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74b3b97bd..d2f8f5f85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,8 +18,11 @@ - feat(logs): add log protocol types (#821) by @lcian - Basic types for [Sentry structured logs](https://docs.sentry.io/product/explore/logs/) have been added. - - It's possible (but not recommended) to use them to send logs to Sentry by directly constructing an `Envelope` containing an `ItemContainer::Logs` envelope item and sending it through `Client::send_envelope`. - - A high-level API and integrations will come soon. +- feat(logs): add ability to capture and send logs (#823) by @lcian + - A method `capture_log` has been added to the `Hub` to enable sending logs. + - This is gated behind the `UNSTABLE_logs` feature flag (disabled by default). + - Additionally, the new client option `enable_logs` needs to be enabled for logs to be sent to Sentry. + - Please note that breaking changes could occur until the API is finalized. ## 0.38.1 diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index 572a3e040..784571a2d 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -24,6 +24,7 @@ default = [] client = ["rand"] test = ["client", "release-health"] release-health = [] +UNSTABLE_logs = [] [dependencies] log = { version = "0.4.8", optional = true, features = ["std"] } diff --git a/sentry-core/src/client.rs b/sentry-core/src/client.rs index 684f7f2a8..10fafa970 100644 --- a/sentry-core/src/client.rs +++ b/sentry-core/src/client.rs @@ -5,9 +5,11 @@ use std::panic::RefUnwindSafe; use std::sync::{Arc, RwLock}; use std::time::Duration; -use rand::random; +#[cfg(feature = "UNSTABLE_logs")] +use crate::protocol::EnvelopeItem; #[cfg(feature = "release-health")] -use sentry_types::protocol::v7::SessionUpdate; +use crate::protocol::SessionUpdate; +use rand::random; use sentry_types::random_uuid; use crate::constants::SDK_INFO; @@ -18,6 +20,8 @@ use crate::types::{Dsn, Uuid}; #[cfg(feature = "release-health")] use crate::SessionMode; use crate::{ClientOptions, Envelope, Hub, Integration, Scope, Transport}; +#[cfg(feature = "UNSTABLE_logs")] +use sentry_types::protocol::v7::{Log, LogAttribute}; impl> From for Client { fn from(o: T) -> Client { @@ -363,6 +367,83 @@ impl Client { random::() < rate } } + + /// Captures a log and sends it to Sentry. + #[cfg(feature = "UNSTABLE_logs")] + pub fn capture_log(&self, log: Log, scope: &Scope) { + if !self.options().enable_logs { + return; + } + if let Some(ref transport) = *self.transport.read().unwrap() { + if let Some(log) = self.prepare_log(log, scope) { + let mut envelope = Envelope::new(); + let logs: EnvelopeItem = vec![log].into(); + envelope.add_item(logs); + transport.send_envelope(envelope); + } + } + } + + /// Prepares a log to be sent, setting the `trace_id` and other default attributes, and + /// processing it through `before_send_log`. + #[cfg(feature = "UNSTABLE_logs")] + fn prepare_log(&self, mut log: Log, scope: &Scope) -> Option { + scope.apply_to_log(&mut log, self.options.send_default_pii); + + self.set_log_default_attributes(&mut log); + + if let Some(ref func) = self.options.before_send_log { + log = func(log)?; + } + + Some(log) + } + + #[cfg(feature = "UNSTABLE_logs")] + fn set_log_default_attributes(&self, log: &mut Log) { + if !log.attributes.contains_key("sentry.environment") { + if let Some(environment) = self.options.environment.as_ref() { + log.attributes.insert( + "sentry.sdk.version".to_owned(), + LogAttribute(environment.clone().into()), + ); + } + } + + if !log.attributes.contains_key("sentry.release") { + if let Some(release) = self.options.release.as_ref() { + log.attributes.insert( + "sentry.release".to_owned(), + LogAttribute(release.clone().into()), + ); + } + } + + if !log.attributes.contains_key("sentry.sdk.name") { + log.attributes.insert( + "sentry.sdk.name".to_owned(), + LogAttribute(self.sdk_info.name.to_owned().into()), + ); + } + + if !log.attributes.contains_key("sentry.sdk.version") { + log.attributes.insert( + "sentry.sdk.version".to_owned(), + LogAttribute(self.sdk_info.version.to_owned().into()), + ); + } + + // TODO: set OS (and Rust?) context + + if !log.attributes.contains_key("server.address") { + if let Some(server) = &self.options.server_name { + log.attributes.insert( + "server.address".to_owned(), + LogAttribute(server.clone().into()), + ); + } + } + } } // Make this unwind safe. It's not out of the box because of the diff --git a/sentry-core/src/clientoptions.rs b/sentry-core/src/clientoptions.rs index 70b0fcaac..a741cf434 100644 --- a/sentry-core/src/clientoptions.rs +++ b/sentry-core/src/clientoptions.rs @@ -5,6 +5,8 @@ use std::time::Duration; use crate::constants::USER_AGENT; use crate::performance::TracesSampler; +#[cfg(feature = "UNSTABLE_logs")] +use crate::protocol::Log; use crate::protocol::{Breadcrumb, Event}; use crate::types::Dsn; use crate::{Integration, IntoDsn, TransportFactory}; @@ -144,6 +146,9 @@ pub struct ClientOptions { pub before_send: Option>>, /// Callback that is executed for each Breadcrumb being added. pub before_breadcrumb: Option>, + /// Callback that is executed for each Log being added. + #[cfg(feature = "UNSTABLE_logs")] + pub before_send_log: Option>, // Transport options /// The transport to use. /// @@ -162,6 +167,12 @@ pub struct ClientOptions { pub https_proxy: Option>, /// The timeout on client drop for draining events on shutdown. pub shutdown_timeout: Duration, + /// Controls the maximum size of an HTTP request body that can be captured when using HTTP + /// server integrations. Needs `send_default_pii` to be enabled to have any effect. + pub max_request_body_size: MaxRequestBodySize, + /// Determines whether captured structured logs should be sent to Sentry (defaults to false). + #[cfg(feature = "UNSTABLE_logs")] + pub enable_logs: bool, // Other options not documented in Unified API /// Disable SSL verification. /// @@ -186,8 +197,6 @@ pub struct ClientOptions { pub trim_backtraces: bool, /// The user agent that should be reported. pub user_agent: Cow<'static, str>, - /// Controls how much of request bodies are captured - pub max_request_body_size: MaxRequestBodySize, } impl ClientOptions { @@ -223,6 +232,12 @@ impl fmt::Debug for ClientOptions { #[derive(Debug)] struct BeforeBreadcrumb; let before_breadcrumb = self.before_breadcrumb.as_ref().map(|_| BeforeBreadcrumb); + #[cfg(feature = "UNSTABLE_logs")] + let before_send_log = { + #[derive(Debug)] + struct BeforeSendLog; + self.before_send_log.as_ref().map(|_| BeforeSendLog) + }; #[derive(Debug)] struct TransportFactory; @@ -264,6 +279,11 @@ impl fmt::Debug for ClientOptions { .field("auto_session_tracking", &self.auto_session_tracking) .field("session_mode", &self.session_mode); + #[cfg(feature = "UNSTABLE_logs")] + debug_struct + .field("enable_logs", &self.enable_logs) + .field("before_send_log", &before_send_log); + debug_struct .field("extra_border_frames", &self.extra_border_frames) .field("trim_backtraces", &self.trim_backtraces) @@ -305,6 +325,10 @@ impl Default for ClientOptions { trim_backtraces: true, user_agent: Cow::Borrowed(USER_AGENT), max_request_body_size: MaxRequestBodySize::Medium, + #[cfg(feature = "UNSTABLE_logs")] + enable_logs: false, + #[cfg(feature = "UNSTABLE_logs")] + before_send_log: None, } } } diff --git a/sentry-core/src/hub.rs b/sentry-core/src/hub.rs index 6bab5263d..fe246078b 100644 --- a/sentry-core/src/hub.rs +++ b/sentry-core/src/hub.rs @@ -4,7 +4,7 @@ use std::sync::{Arc, RwLock}; -use crate::protocol::{Event, Level, SessionStatus}; +use crate::protocol::{Event, Level, Log, LogAttribute, LogLevel, Map, SessionStatus}; use crate::types::Uuid; use crate::{Integration, IntoBreadcrumbs, Scope, ScopeGuard}; @@ -245,4 +245,14 @@ impl Hub { }) }} } + + /// Captures a structured log. + #[cfg(feature = "UNSTABLE_logs")] + pub fn capture_log(&self, log: Log) { + with_client_impl! {{ + let top = self.inner.with(|stack| stack.top().clone()); + let Some(ref client) = top.client else { return }; + client.capture_log(log, &top.scope); + }} + } } diff --git a/sentry-core/src/scope/noop.rs b/sentry-core/src/scope/noop.rs index f4d47a37e..578c1f9b0 100644 --- a/sentry-core/src/scope/noop.rs +++ b/sentry-core/src/scope/noop.rs @@ -1,5 +1,7 @@ use std::fmt; +#[cfg(feature = "UNSTABLE_logs")] +use crate::protocol::Log; use crate::protocol::{Context, Event, Level, User, Value}; use crate::TransactionOrSpan; @@ -110,6 +112,13 @@ impl Scope { minimal_unreachable!(); } + /// Applies the contained scoped data to fill a log. + #[cfg(feature = "UNSTABLE_logs")] + pub fn apply_to_log(&self, log: &mut Log) { + let _log = log; + minimal_unreachable!(); + } + /// Set the given [`TransactionOrSpan`] as the active span for this scope. pub fn set_span(&mut self, span: Option) { let _ = span; diff --git a/sentry-core/src/scope/real.rs b/sentry-core/src/scope/real.rs index 47b1e9da0..c8147ce03 100644 --- a/sentry-core/src/scope/real.rs +++ b/sentry-core/src/scope/real.rs @@ -5,10 +5,12 @@ use std::fmt; use std::sync::Mutex; use std::sync::{Arc, PoisonError, RwLock}; -use sentry_types::protocol::v7::TraceContext; - use crate::performance::TransactionOrSpan; -use crate::protocol::{Attachment, Breadcrumb, Context, Event, Level, Transaction, User, Value}; +use crate::protocol::{ + Attachment, Breadcrumb, Context, Event, Level, TraceContext, Transaction, User, Value, +}; +#[cfg(feature = "UNSTABLE_logs")] +use crate::protocol::{Log, LogAttribute}; #[cfg(feature = "release-health")] use crate::session::Session; use crate::{Client, SentryTrace, TraceHeader, TraceHeadersIter}; @@ -346,6 +348,59 @@ impl Scope { ); } + /// Applies the contained scoped data to a log, setting the `trace_id` and certain default + /// attributes. + #[cfg(feature = "UNSTABLE_logs")] + pub fn apply_to_log(&self, log: &mut Log, send_default_pii: bool) { + if let Some(span) = self.span.as_ref() { + log.trace_id = Some(span.get_trace_context().trace_id); + } else { + log.trace_id = Some(self.propagation_context.trace_id); + } + + if !log.attributes.contains_key("sentry.trace.parent_span_id") { + if let Some(span) = self.get_span() { + let span_id = match span { + crate::TransactionOrSpan::Transaction(transaction) => { + transaction.get_trace_context().span_id + } + crate::TransactionOrSpan::Span(span) => span.get_span_id(), + }; + log.attributes.insert( + "parent_span_id".to_owned(), + LogAttribute(span_id.to_string().into()), + ); + } + } + + if send_default_pii { + if let Some(user) = self.user.as_ref() { + if !log.attributes.contains_key("user.id") { + if let Some(id) = user.id.as_ref() { + log.attributes + .insert("user.id".to_owned(), LogAttribute(id.to_owned().into())); + } + } + + if !log.attributes.contains_key("user.name") { + if let Some(name) = user.username.as_ref() { + log.attributes + .insert("user.name".to_owned(), LogAttribute(name.to_owned().into())); + } + } + + if !log.attributes.contains_key("user.email") { + if let Some(email) = user.email.as_ref() { + log.attributes.insert( + "user.email".to_owned(), + LogAttribute(email.to_owned().into()), + ); + } + } + } + } + } + /// Set the given [`TransactionOrSpan`] as the active span for this scope. pub fn set_span(&mut self, span: Option) { self.span = Arc::new(span); diff --git a/sentry-types/src/protocol/envelope.rs b/sentry-types/src/protocol/envelope.rs index 006c59caf..43a9c35ff 100644 --- a/sentry-types/src/protocol/envelope.rs +++ b/sentry-types/src/protocol/envelope.rs @@ -1071,7 +1071,7 @@ some content Log { level: protocol::LogLevel::Warn, body: "test".to_owned(), - trace_id: "335e53d614474acc9f89e632b776cc28".parse().unwrap(), + trace_id: Some("335e53d614474acc9f89e632b776cc28".parse().unwrap()), timestamp: timestamp("2022-07-25T14:51:14.296Z"), severity_number: Some(1.try_into().unwrap()), attributes, @@ -1079,7 +1079,7 @@ some content Log { level: protocol::LogLevel::Error, body: "a body".to_owned(), - trace_id: "332253d614472a2c9f89e232b7762c28".parse().unwrap(), + trace_id: Some("332253d614472a2c9f89e232b7762c28".parse().unwrap()), timestamp: timestamp("2021-07-21T14:51:14.296Z"), severity_number: Some(1.try_into().unwrap()), attributes: attributes_2, diff --git a/sentry-types/src/protocol/v7.rs b/sentry-types/src/protocol/v7.rs index d984035a1..827094bc3 100644 --- a/sentry-types/src/protocol/v7.rs +++ b/sentry-types/src/protocol/v7.rs @@ -2127,7 +2127,8 @@ pub struct Log { /// The log body/message (required). pub body: String, /// The ID of the Trace in which this log happened (required). - pub trace_id: TraceId, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub trace_id: Option, /// The timestamp of the log (required). #[serde(with = "ts_seconds_float")] pub timestamp: SystemTime, diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index 8e798195a..9ab7e3159 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -48,6 +48,7 @@ opentelemetry = ["sentry-opentelemetry"] # other features test = ["sentry-core/test"] release-health = ["sentry-core/release-health", "sentry-actix?/release-health"] +UNSTABLE_logs = ["sentry-core/UNSTABLE_logs"] # transports transport = ["reqwest", "native-tls"] reqwest = ["dep:reqwest", "httpdate", "tokio"] diff --git a/sentry/tests/test_basic.rs b/sentry/tests/test_basic.rs index dac87e373..c3b2afd7d 100644 --- a/sentry/tests/test_basic.rs +++ b/sentry/tests/test_basic.rs @@ -264,3 +264,52 @@ fn test_panic_scope_pop() { Some("Popped scope guard out of order".into()) ); } + +#[cfg(feature = "UNSTABLE_logs")] +#[test] +fn test_basic_capture_log() { + use std::time::SystemTime; + + use sentry::{protocol::Log, protocol::LogAttribute, protocol::Map, Hub}; + + let options = sentry::ClientOptions { + enable_logs: true, + ..Default::default() + }; + let envelopes = sentry::test::with_captured_envelopes_options( + || { + let mut attributes: Map = Map::new(); + attributes.insert("test".into(), "a string".into()); + let log = Log { + level: sentry::protocol::LogLevel::Warn, + body: "this is a test".into(), + trace_id: None, + timestamp: SystemTime::now(), + severity_number: None, + attributes, + }; + + Hub::current().capture_log(log); + }, + options, + ); + assert_eq!(envelopes.len(), 1); + let envelope = envelopes.first().expect("expected envelope"); + let item = envelope.items().next().expect("expected envelope item"); + match item { + EnvelopeItem::ItemContainer(container) => match container { + sentry::protocol::ItemContainer::Logs(logs) => { + let log = logs.iter().next().expect("expected log"); + assert_eq!(sentry::protocol::LogLevel::Warn, log.level); + assert_eq!("this is a test", log.body); + assert!(log.trace_id.is_some()); + assert!(log.severity_number.is_none()); + assert!(log.attributes.contains_key("sentry.sdk.name")); + assert!(log.attributes.contains_key("sentry.sdk.version")); + assert!(log.attributes.contains_key("test")); + } + _ => panic!("expected logs"), + }, + _ => panic!("expected item container"), + } +} From be2e04e9992cdd1d9e05335ff2e2468b51cddc00 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Fri, 6 Jun 2025 10:44:04 +0200 Subject: [PATCH 096/148] feat(logs): add macro-based API (#827) Co-authored-by: Daniel Szoke <7881302+szokeasaurusrex@users.noreply.github.com> --- CHANGELOG.md | 10 +- sentry-core/src/lib.rs | 2 + sentry-core/src/logger.rs | 333 +++++++++++++++++++++++++++++++++++++ sentry/tests/test_basic.rs | 265 +++++++++++++++++++++++++++++ 4 files changed, 605 insertions(+), 5 deletions(-) create mode 100644 sentry-core/src/logger.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index d2f8f5f85..110d7d512 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,11 +17,11 @@ ### Features - feat(logs): add log protocol types (#821) by @lcian - - Basic types for [Sentry structured logs](https://docs.sentry.io/product/explore/logs/) have been added. -- feat(logs): add ability to capture and send logs (#823) by @lcian - - A method `capture_log` has been added to the `Hub` to enable sending logs. - - This is gated behind the `UNSTABLE_logs` feature flag (disabled by default). - - Additionally, the new client option `enable_logs` needs to be enabled for logs to be sent to Sentry. +- feat(logs): add ability to capture and send logs (#823) by @lcian & @Swatinem +- feat(logs): add macro-based API (#827) by @lcian & @szokeasaurusrex + - Support for [Sentry structured logs](https://docs.sentry.io/product/explore/logs/) has been added. + - To enable logs, enable the `UNSTABLE_logs` feature of the `sentry` crate and set `enable_logs` to `true` in your client options. + - Then, use the `logger_trace!`, `logger_debug!`, `logger_info!`, `logger_warn!`, `logger_error!` and `logger_fatal!` macros to capture logs. - Please note that breaking changes could occur until the API is finalized. ## 0.38.1 diff --git a/sentry-core/src/lib.rs b/sentry-core/src/lib.rs index 5b674db95..d21cc6baa 100644 --- a/sentry-core/src/lib.rs +++ b/sentry-core/src/lib.rs @@ -132,6 +132,8 @@ pub use crate::intodsn::IntoDsn; pub use crate::performance::*; pub use crate::scope::{Scope, ScopeGuard}; pub use crate::transport::{Transport, TransportFactory}; +#[cfg(feature = "UNSTABLE_logs")] +mod logger; // structured logging macros exported with `#[macro_export]` // client feature #[cfg(feature = "client")] diff --git a/sentry-core/src/logger.rs b/sentry-core/src/logger.rs new file mode 100644 index 000000000..293bf3740 --- /dev/null +++ b/sentry-core/src/logger.rs @@ -0,0 +1,333 @@ +//! Macros for Sentry [structured logging](https://docs.sentry.io/product/explore/logs/). + +// Helper macro to capture a log at the given level. Should not be used directly. +#[doc(hidden)] +#[macro_export] +macro_rules! logger_log { + // Simple message + ($level:expr, $msg:literal) => {{ + let log = $crate::protocol::Log { + level: $level, + body: $msg.to_owned(), + trace_id: None, + timestamp: ::std::time::SystemTime::now(), + severity_number: None, + attributes: $crate::protocol::Map::new(), + }; + $crate::Hub::current().capture_log(log) + }}; + + // Message with format string and args + ($level:expr, $fmt:literal, $($arg:expr),+) => {{ + let mut attributes = $crate::protocol::Map::new(); + + attributes.insert( + "sentry.message.template".to_owned(), + $crate::protocol::LogAttribute($crate::protocol::Value::from($fmt)) + ); + let mut i = 0; + $( + attributes.insert( + format!("sentry.message.parameter.{}", i), + $crate::protocol::LogAttribute($crate::protocol::Value::from($arg)) + ); + i += 1; + )* + let _ = i; // avoid triggering the `unused_assignments` lint + + let log = $crate::protocol::Log { + level: $level, + body: format!($fmt, $($arg),*), + trace_id: None, + timestamp: ::std::time::SystemTime::now(), + severity_number: None, + attributes, + }; + $crate::Hub::current().capture_log(log) + }}; + + // Attributes entrypoint + ($level:expr, $($rest:tt)+) => {{ + let mut attributes = $crate::protocol::Map::new(); + $crate::logger_log!(@internal attributes, $level, $($rest)+) + }}; + + // Attributes base case: no more attributes, simple message + (@internal $attrs:ident, $level:expr, $msg:literal) => {{ + let log = $crate::protocol::Log { + level: $level, + body: $msg.to_owned(), + trace_id: None, + timestamp: ::std::time::SystemTime::now(), + severity_number: None, + #[allow(clippy::redundant_field_names)] + attributes: $attrs, + }; + $crate::Hub::current().capture_log(log) + }}; + + // Attributes base case: no more attributes, message with format string and args + (@internal $attrs:ident, $level:expr, $fmt:literal, $($arg:expr),+) => {{ + $attrs.insert( + "sentry.message.template".to_owned(), + $crate::protocol::LogAttribute($crate::protocol::Value::from($fmt)) + ); + let mut i = 0; + $( + $attrs.insert( + format!("sentry.message.parameter.{}", i), + $crate::protocol::LogAttribute($crate::protocol::Value::from($arg)) + ); + i += 1; + )* + let _ = i; // avoid triggering the `unused_assignments` lint + + let log = $crate::protocol::Log { + level: $level, + body: format!($fmt, $($arg),*), + trace_id: None, + timestamp: ::std::time::SystemTime::now(), + severity_number: None, + #[allow(clippy::redundant_field_names)] + attributes: $attrs, + }; + $crate::Hub::current().capture_log(log) + }}; + + // Attributes recursive case + (@internal $attrs:ident, $level:expr, $($key:ident).+ = $value:expr, $($rest:tt)+) => {{ + $attrs.insert( + stringify!($($key).+).to_owned(), + $crate::protocol::LogAttribute($crate::protocol::Value::from($value)) + ); + $crate::logger_log!(@internal $attrs, $level, $($rest)+) + }}; +} + +/// Captures a log at the trace level, with the given message and attributes. +/// +/// To attach attributes to a log, pass them with the `key = value` syntax before the message. +/// The message can be a simple string or a format string with its arguments. +/// +/// The supported attribute keys are all valid Rust identifiers with up to 8 dots. +/// Using dots will nest multiple attributes under their common prefix in the UI. +/// +/// The supported attribute values are simple types, such as string, numbers, and boolean. +/// +/// # Examples +/// +/// ``` +/// use sentry::logger_trace; +/// +/// // Simple message +/// logger_trace!("Hello world"); +/// +/// // Message with format args +/// logger_trace!("Value is {}", 42); +/// +/// // Message with format args and attributes +/// logger_trace!( +/// error_code = 500, +/// user.id = "12345", +/// user.email = "test@test.com", +/// success = false, +/// "Error occurred: {}", +/// "bad input" +/// ); +/// ``` +#[macro_export] +macro_rules! logger_trace { + ($($arg:tt)+) => { + $crate::logger_log!($crate::protocol::LogLevel::Trace, $($arg)+) + }; +} + +/// Captures a log at the debug level, with the given message and attributes. +/// +/// To attach attributes to a log, pass them with the `key = value` syntax before the message. +/// The message can be a simple string or a format string with its arguments. +/// +/// The supported attribute keys are all valid Rust identifiers with up to 8 dots. +/// Using dots will nest multiple attributes under their common prefix in the UI. +/// +/// The supported attribute values are simple types, such as string, numbers, and boolean. +/// +/// # Examples +/// +/// ``` +/// use sentry::logger_debug; +/// +/// // Simple message +/// logger_debug!("Hello world"); +/// +/// // Message with format args +/// logger_debug!("Value is {}", 42); +/// +/// // Message with format args and attributes +/// logger_debug!( +/// error_code = 500, +/// user.id = "12345", +/// user.email = "test@test.com", +/// success = false, +/// "Error occurred: {}", +/// "bad input" +/// ); +/// ``` +#[macro_export] +macro_rules! logger_debug { + ($($arg:tt)+) => { + $crate::logger_log!($crate::protocol::LogLevel::Debug, $($arg)+) + }; +} + +/// Captures a log at the info level, with the given message and attributes. +/// +/// To attach attributes to a log, pass them with the `key = value` syntax before the message. +/// The message can be a simple string or a format string with its arguments. +/// +/// The supported attribute keys are all valid Rust identifiers with up to 8 dots. +/// Using dots will nest multiple attributes under their common prefix in the UI. +/// +/// The supported attribute values are simple types, such as string, numbers, and boolean. +/// +/// # Examples +/// +/// ``` +/// use sentry::logger_info; +/// +/// // Simple message +/// logger_info!("Hello world"); +/// +/// // Message with format args +/// logger_info!("Value is {}", 42); +/// +/// // Message with format args and attributes +/// logger_info!( +/// error_code = 500, +/// user.id = "12345", +/// user.email = "test@test.com", +/// success = false, +/// "Error occurred: {}", +/// "bad input" +/// ); +/// ``` +#[macro_export] +macro_rules! logger_info { + ($($arg:tt)+) => { + $crate::logger_log!($crate::protocol::LogLevel::Info, $($arg)+) + }; +} + +/// Captures a log at the warn level, with the given message and attributes. +/// +/// To attach attributes to a log, pass them with the `key = value` syntax before the message. +/// The message can be a simple string or a format string with its arguments. +/// +/// The supported attribute keys are all valid Rust identifiers with up to 8 dots. +/// Using dots will nest multiple attributes under their common prefix in the UI. +/// +/// The supported attribute values are simple types, such as string, numbers, and boolean. +/// +/// # Examples +/// +/// ``` +/// use sentry::logger_warn; +/// +/// // Simple message +/// logger_warn!("Hello world"); +/// +/// // Message with format args +/// logger_warn!("Value is {}", 42); +/// +/// // Message with format args and attributes +/// logger_warn!( +/// error_code = 500, +/// user.id = "12345", +/// user.email = "test@test.com", +/// success = false, +/// "Error occurred: {}", +/// "bad input" +/// ); +/// ``` +#[macro_export] +macro_rules! logger_warn { + ($($arg:tt)+) => { + $crate::logger_log!($crate::protocol::LogLevel::Warn, $($arg)+) + }; +} + +/// Captures a log at the error level, with the given message and attributes. +/// +/// To attach attributes to a log, pass them with the `key = value` syntax before the message. +/// The message can be a simple string or a format string with its arguments. +/// +/// The supported attribute keys are all valid Rust identifiers with up to 8 dots. +/// Using dots will nest multiple attributes under their common prefix in the UI. +/// +/// The supported attribute values are simple types, such as string, numbers, and boolean. +/// +/// # Examples +/// +/// ``` +/// use sentry::logger_error; +/// +/// // Simple message +/// logger_error!("Hello world"); +/// +/// // Message with format args +/// logger_error!("Value is {}", 42); +/// +/// // Message with format args and attributes +/// logger_error!( +/// error_code = 500, +/// user.id = "12345", +/// user.email = "test@test.com", +/// success = false, +/// "Error occurred: {}", +/// "bad input" +/// ); +/// ``` +#[macro_export] +macro_rules! logger_error { + ($($arg:tt)+) => { + $crate::logger_log!($crate::protocol::LogLevel::Error, $($arg)+) + }; +} + +/// Captures a log at the fatal level, with the given message and attributes. +/// +/// To attach attributes to a log, pass them with the `key = value` syntax before the message. +/// The message can be a simple string or a format string with its arguments. +/// +/// The supported attribute keys are all valid Rust identifiers with up to 8 dots. +/// Using dots will nest multiple attributes under their common prefix in the UI. +/// +/// The supported attribute values are simple types, such as string, numbers, and boolean. +/// +/// # Examples +/// +/// ``` +/// use sentry::logger_fatal; +/// +/// // Simple message +/// logger_fatal!("Hello world"); +/// +/// // Message with format args +/// logger_fatal!("Value is {}", 42); +/// +/// // Message with format args and attributes +/// logger_fatal!( +/// error_code = 500, +/// user.id = "12345", +/// user.email = "test@test.com", +/// success = false, +/// "Error occurred: {}", +/// "bad input" +/// ); +/// ``` +#[macro_export] +macro_rules! logger_fatal { + ($($arg:tt)+) => { + $crate::logger_log!($crate::protocol::LogLevel::Fatal, $($arg)+) + }; +} diff --git a/sentry/tests/test_basic.rs b/sentry/tests/test_basic.rs index c3b2afd7d..fb80c90db 100644 --- a/sentry/tests/test_basic.rs +++ b/sentry/tests/test_basic.rs @@ -313,3 +313,268 @@ fn test_basic_capture_log() { _ => panic!("expected item container"), } } + +#[cfg(feature = "UNSTABLE_logs")] +#[test] +fn test_basic_capture_log_macro_message() { + use sentry_core::logger_info; + + let options = sentry::ClientOptions { + enable_logs: true, + ..Default::default() + }; + let envelopes = sentry::test::with_captured_envelopes_options( + || { + logger_info!("Hello, world!"); + }, + options, + ); + assert_eq!(envelopes.len(), 1); + let envelope = envelopes.first().expect("expected envelope"); + let item = envelope.items().next().expect("expected envelope item"); + match item { + EnvelopeItem::ItemContainer(container) => match container { + sentry::protocol::ItemContainer::Logs(logs) => { + let log = logs.iter().next().expect("expected log"); + assert_eq!(sentry_core::protocol::LogLevel::Info, log.level); + assert_eq!("Hello, world!", log.body); + assert!(log.trace_id.is_some()); + assert!(log.severity_number.is_none()); + assert!(log.attributes.contains_key("sentry.sdk.name")); + assert!(log.attributes.contains_key("sentry.sdk.version")); + } + _ => panic!("expected logs"), + }, + _ => panic!("expected item container"), + } +} + +#[cfg(feature = "UNSTABLE_logs")] +#[test] +fn test_basic_capture_log_macro_message_formatted() { + use sentry::protocol::LogAttribute; + use sentry_core::logger_warn; + + let options = sentry::ClientOptions { + enable_logs: true, + ..Default::default() + }; + let envelopes = sentry::test::with_captured_envelopes_options( + || { + let failed_requests = ["request1", "request2", "request3"]; + logger_warn!( + "Critical system errors detected for user {}, total failures: {}", + "test_user", + failed_requests.len() + ); + }, + options, + ); + assert_eq!(envelopes.len(), 1); + let envelope = envelopes.first().expect("expected envelope"); + let item = envelope.items().next().expect("expected envelope item"); + match item { + EnvelopeItem::ItemContainer(container) => match container { + sentry::protocol::ItemContainer::Logs(logs) => { + let log = logs.iter().next().expect("expected log"); + assert_eq!(sentry_core::protocol::LogLevel::Warn, log.level); + assert_eq!( + "Critical system errors detected for user test_user, total failures: 3", + log.body + ); + assert_eq!( + LogAttribute::from( + "Critical system errors detected for user {}, total failures: {}" + ), + log.attributes + .get("sentry.message.template") + .unwrap() + .clone() + ); + assert_eq!( + LogAttribute::from("test_user"), + log.attributes + .get("sentry.message.parameter.0") + .unwrap() + .clone() + ); + assert_eq!( + LogAttribute::from(3), + log.attributes + .get("sentry.message.parameter.1") + .unwrap() + .clone() + ); + assert!(log.trace_id.is_some()); + assert!(log.severity_number.is_none()); + assert!(log.attributes.contains_key("sentry.sdk.name")); + assert!(log.attributes.contains_key("sentry.sdk.version")); + } + _ => panic!("expected logs"), + }, + _ => panic!("expected item container"), + } +} + +#[cfg(feature = "UNSTABLE_logs")] +#[test] +fn test_basic_capture_log_macro_message_with_attributes() { + use sentry::protocol::LogAttribute; + use sentry_core::logger_error; + + let options = sentry::ClientOptions { + enable_logs: true, + ..Default::default() + }; + let envelopes = sentry::test::with_captured_envelopes_options( + || { + logger_error!( + user.id = "12345", + user.active = true, + request.duration = 150, + success = false, + "Failed to process request" + ); + }, + options, + ); + assert_eq!(envelopes.len(), 1); + let envelope = envelopes.first().expect("expected envelope"); + let item = envelope.items().next().expect("expected envelope item"); + match item { + EnvelopeItem::ItemContainer(container) => match container { + sentry::protocol::ItemContainer::Logs(logs) => { + let log = logs.iter().next().expect("expected log"); + assert_eq!(sentry_core::protocol::LogLevel::Error, log.level); + assert_eq!("Failed to process request", log.body); + assert_eq!(None, log.attributes.get("sentry.message.template")); + assert!(log.trace_id.is_some()); + assert!(log.severity_number.is_none()); + assert!(log.attributes.contains_key("sentry.sdk.name")); + assert!(log.attributes.contains_key("sentry.sdk.version")); + assert_eq!( + LogAttribute::from("12345"), + log.attributes.get("user.id").unwrap().clone() + ); + assert_eq!( + LogAttribute::from(true), + log.attributes.get("user.active").unwrap().clone() + ); + assert_eq!( + LogAttribute::from(150u64), + log.attributes.get("request.duration").unwrap().clone() + ); + assert_eq!( + LogAttribute::from(false), + log.attributes.get("success").unwrap().clone() + ); + } + _ => panic!("expected logs"), + }, + _ => panic!("expected item container"), + } +} + +#[cfg(feature = "UNSTABLE_logs")] +#[test] +fn test_basic_capture_log_macro_message_formatted_with_attributes() { + use sentry::protocol::LogAttribute; + use sentry_core::logger_debug; + + let options = sentry::ClientOptions { + enable_logs: true, + ..Default::default() + }; + let envelopes = sentry::test::with_captured_envelopes_options( + || { + logger_debug!( + hello = "test", + operation.name = "database_query", + operation.success = true, + operation.time_ms = 42, + world = 10, + "Database query {} completed in {} ms with {} results", + "users_by_region", + 42, + 15 + ); + }, + options, + ); + assert_eq!(envelopes.len(), 1); + let envelope = envelopes.first().expect("expected envelope"); + let item = envelope.items().next().expect("expected envelope item"); + match item { + EnvelopeItem::ItemContainer(container) => match container { + sentry::protocol::ItemContainer::Logs(logs) => { + let log = logs.iter().next().expect("expected log"); + assert_eq!(sentry_core::protocol::LogLevel::Debug, log.level); + assert_eq!( + "Database query users_by_region completed in 42 ms with 15 results", + log.body + ); + assert!(log.trace_id.is_some()); + assert!(log.severity_number.is_none()); + assert_eq!( + LogAttribute::from("Database query {} completed in {} ms with {} results",), + log.attributes + .get("sentry.message.template") + .unwrap() + .clone() + ); + assert!(log.attributes.contains_key("sentry.sdk.name")); + assert!(log.attributes.contains_key("sentry.sdk.version")); + assert_eq!( + LogAttribute::from("test"), + log.attributes.get("hello").unwrap().clone() + ); + assert_eq!( + LogAttribute::from("database_query"), + log.attributes.get("operation.name").unwrap().clone() + ); + assert_eq!( + LogAttribute::from(true), + log.attributes.get("operation.success").unwrap().clone() + ); + assert_eq!( + LogAttribute::from(42u64), + log.attributes.get("operation.time_ms").unwrap().clone() + ); + assert_eq!( + LogAttribute::from(10), + log.attributes.get("world").unwrap().clone() + ); + assert_eq!( + LogAttribute::from("Database query {} completed in {} ms with {} results"), + log.attributes + .get("sentry.message.template") + .unwrap() + .clone() + ); + assert_eq!( + LogAttribute::from("users_by_region"), + log.attributes + .get("sentry.message.parameter.0") + .unwrap() + .clone() + ); + assert_eq!( + LogAttribute::from(42), + log.attributes + .get("sentry.message.parameter.1") + .unwrap() + .clone() + ); + assert_eq!( + LogAttribute::from(15), + log.attributes + .get("sentry.message.parameter.2") + .unwrap() + .clone() + ); + } + _ => panic!("expected logs"), + }, + _ => panic!("expected item container"), + } +} From 5912203921639df70b6d36336071a893cc6a0135 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Tue, 10 Jun 2025 10:30:55 +0200 Subject: [PATCH 097/148] chore: cargo +nightly clippy --fix (#833) --- sentry-core/src/performance.rs | 2 +- sentry-opentelemetry/src/converters.rs | 2 +- sentry-opentelemetry/tests/captures_transaction.rs | 2 +- .../tests/captures_transaction_with_nested_spans.rs | 2 +- sentry-opentelemetry/tests/creates_distributed_trace.rs | 4 ++-- sentry-tracing/src/converters.rs | 4 ++-- sentry-tracing/tests/breadcrumbs.rs | 2 +- sentry-tracing/tests/smoke.rs | 6 +++--- sentry-types/src/protocol/v7.rs | 7 +++---- 9 files changed, 15 insertions(+), 16 deletions(-) diff --git a/sentry-core/src/performance.rs b/sentry-core/src/performance.rs index 39ee2363e..10c98ac1d 100644 --- a/sentry-core/src/performance.rs +++ b/sentry-core/src/performance.rs @@ -313,7 +313,7 @@ impl TransactionContext { // And set our key let existing_value = custom.insert(key, value); - std::mem::swap(&mut self.custom, &mut Some(custom)); + self.custom = Some(custom); existing_value } diff --git a/sentry-opentelemetry/src/converters.rs b/sentry-opentelemetry/src/converters.rs index 0f6645142..b0c8c326e 100644 --- a/sentry-opentelemetry/src/converters.rs +++ b/sentry-opentelemetry/src/converters.rs @@ -18,7 +18,7 @@ pub(crate) fn convert_span_status(status: &opentelemetry::trace::Status) -> Span } pub(crate) fn convert_span_kind(kind: opentelemetry::trace::SpanKind) -> Value { - format!("{:?}", kind).to_lowercase().into() + format!("{kind:?}").to_lowercase().into() } pub(crate) fn convert_value(value: opentelemetry::Value) -> Value { diff --git a/sentry-opentelemetry/tests/captures_transaction.rs b/sentry-opentelemetry/tests/captures_transaction.rs index c8ca55d0d..3c30ec555 100644 --- a/sentry-opentelemetry/tests/captures_transaction.rs +++ b/sentry-opentelemetry/tests/captures_transaction.rs @@ -37,6 +37,6 @@ fn test_captures_transaction() { sentry::protocol::EnvelopeItem::Transaction(tx) => { assert_eq!(tx.name.as_deref(), Some("root_span")); } - unexpected => panic!("Expected transaction, but got {:#?}", unexpected), + unexpected => panic!("Expected transaction, but got {unexpected:#?}"), } } diff --git a/sentry-opentelemetry/tests/captures_transaction_with_nested_spans.rs b/sentry-opentelemetry/tests/captures_transaction_with_nested_spans.rs index 4b47efa63..551cd3a0a 100644 --- a/sentry-opentelemetry/tests/captures_transaction_with_nested_spans.rs +++ b/sentry-opentelemetry/tests/captures_transaction_with_nested_spans.rs @@ -67,6 +67,6 @@ fn test_captures_transaction_with_nested_spans() { assert_eq!(grandchild_span.parent_span_id, Some(child_span.span_id)); assert_eq!(child_span.parent_span_id, Some(tx_span_id)); } - unexpected => panic!("Expected transaction, but got {:#?}", unexpected), + unexpected => panic!("Expected transaction, but got {unexpected:#?}"), } } diff --git a/sentry-opentelemetry/tests/creates_distributed_trace.rs b/sentry-opentelemetry/tests/creates_distributed_trace.rs index 7ae4297c9..369e9ceb3 100644 --- a/sentry-opentelemetry/tests/creates_distributed_trace.rs +++ b/sentry-opentelemetry/tests/creates_distributed_trace.rs @@ -63,14 +63,14 @@ fn test_creates_distributed_trace() { for envelope in &envelopes { let tx = match envelope.items().next().unwrap() { sentry::protocol::EnvelopeItem::Transaction(tx) => tx.clone(), - unexpected => panic!("Expected transaction, but got {:#?}", unexpected), + unexpected => panic!("Expected transaction, but got {unexpected:#?}"), }; // Determine which service this transaction belongs to based on name match tx.name.as_deref() { Some("first_service") => first_tx = Some(tx), Some("second_service") => second_tx = Some(tx), - name => panic!("Unexpected transaction name: {:?}", name), + name => panic!("Unexpected transaction name: {name:?}"), } } diff --git a/sentry-tracing/src/converters.rs b/sentry-tracing/src/converters.rs index 5822e96b3..30e831311 100644 --- a/sentry-tracing/src/converters.rs +++ b/sentry-tracing/src/converters.rs @@ -77,7 +77,7 @@ where TransactionOrSpan::Span(span) => { for (key, value) in span.data().iter() { if key != "message" { - let key = format!("{}:{}", name, key); + let key = format!("{name}:{key}"); visitor.json_values.insert(key, value.clone()); } } @@ -85,7 +85,7 @@ where TransactionOrSpan::Transaction(transaction) => { for (key, value) in transaction.data().iter() { if key != "message" { - let key = format!("{}:{}", name, key); + let key = format!("{name}:{key}"); visitor.json_values.insert(key, value.clone()); } } diff --git a/sentry-tracing/tests/breadcrumbs.rs b/sentry-tracing/tests/breadcrumbs.rs index f1eab18d1..e163112db 100644 --- a/sentry-tracing/tests/breadcrumbs.rs +++ b/sentry-tracing/tests/breadcrumbs.rs @@ -12,7 +12,7 @@ fn breadcrumbs_should_capture_span_fields() { let event = data.first().expect("should have 1 event"); let event = match event.items().next().unwrap() { sentry::protocol::EnvelopeItem::Event(event) => event, - unexpected => panic!("Expected event, but got {:#?}", unexpected), + unexpected => panic!("Expected event, but got {unexpected:#?}"), }; assert_eq!(event.breadcrumbs.len(), 1); diff --git a/sentry-tracing/tests/smoke.rs b/sentry-tracing/tests/smoke.rs index 22b3ad26e..5bc0322ae 100644 --- a/sentry-tracing/tests/smoke.rs +++ b/sentry-tracing/tests/smoke.rs @@ -16,13 +16,13 @@ fn should_instrument_function_with_event() { let event = data.first().expect("should have 1 event"); let event = match event.items().next().unwrap() { sentry::protocol::EnvelopeItem::Event(event) => event, - unexpected => panic!("Expected event, but got {:#?}", unexpected), + unexpected => panic!("Expected event, but got {unexpected:#?}"), }; //Validate transaction is created let trace = match event.contexts.get("trace").expect("to get 'trace' context") { sentry::protocol::Context::Trace(trace) => trace, - unexpected => panic!("Expected trace context but got {:?}", unexpected), + unexpected => panic!("Expected trace context but got {unexpected:?}"), }; assert_eq!(trace.op.as_deref().unwrap(), "function_with_tags"); @@ -30,7 +30,7 @@ fn should_instrument_function_with_event() { let transaction = data.get(1).expect("should have 1 transaction"); let transaction = match transaction.items().next().unwrap() { sentry::protocol::EnvelopeItem::Transaction(transaction) => transaction, - unexpected => panic!("Expected transaction, but got {:#?}", unexpected), + unexpected => panic!("Expected transaction, but got {unexpected:#?}"), }; assert_eq!(transaction.tags.len(), 1); assert_eq!(trace.data.len(), 2); diff --git a/sentry-types/src/protocol/v7.rs b/sentry-types/src/protocol/v7.rs index 827094bc3..f7c76aee2 100644 --- a/sentry-types/src/protocol/v7.rs +++ b/sentry-types/src/protocol/v7.rs @@ -1370,7 +1370,7 @@ impl fmt::Display for SpanId { impl fmt::Debug for SpanId { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "SpanId({})", self) + write!(fmt, "SpanId({self})") } } @@ -1423,7 +1423,7 @@ impl fmt::Display for TraceId { impl fmt::Debug for TraceId { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "TraceId({})", self) + write!(fmt, "TraceId({self})") } } @@ -2320,8 +2320,7 @@ impl<'de> Deserialize<'de> for LogAttribute { } _ => { return Err(de::Error::custom(format!( - "expected type to be 'string' | 'integer' | 'double' | 'boolean', found {}", - type_str + "expected type to be 'string' | 'integer' | 'double' | 'boolean', found {type_str}" ))) } } From cb7fc818b8b9a5c75cccd9482add634aa4083267 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Tue, 10 Jun 2025 11:55:58 +0200 Subject: [PATCH 098/148] feat(logs): send logs in batches (#831) --- CHANGELOG.md | 25 ++-- sentry-core/Cargo.toml | 2 +- sentry-core/src/client.rs | 47 ++++-- sentry-core/src/clientoptions.rs | 14 +- sentry-core/src/hub.rs | 2 +- sentry-core/src/lib.rs | 4 +- sentry-core/src/logs.rs | 197 ++++++++++++++++++++++++++ sentry-core/src/scope/noop.rs | 4 +- sentry-core/src/scope/real.rs | 4 +- sentry-types/src/protocol/envelope.rs | 2 +- sentry/Cargo.toml | 2 +- sentry/tests/test_basic.rs | 10 +- 12 files changed, 269 insertions(+), 44 deletions(-) create mode 100644 sentry-core/src/logs.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 110d7d512..1b15c5469 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,18 @@ ## Unreleased -### Breaking changes +### Features -- refactor: remove `debug-logs` feature (#820) by @lcian - - The deprecated `debug-logs` feature of the `sentry` crate, used for the SDK's own internal logging, has been removed. +Support for [Sentry structured logs](https://docs.sentry.io/product/explore/logs/) has been added to the SDK. +- To set up logs, enable the `logs` feature of the `sentry` crate and set `enable_logs` to `true` in your client options. +- Then, use the `logger_trace!`, `logger_debug!`, `logger_info!`, `logger_warn!`, `logger_error!` and `logger_fatal!` macros to capture logs. +- To filter or update logs before they are sent, you can use the `before_send_log` client option. +- Please note that breaking changes could occur until the API is finalized. + +- feat(logs): add log protocol types (#821) by @lcian +- feat(logs): add ability to capture and send logs (#823) by @lcian & @Swatinem +- feat(logs): add macro-based API (#827) by @lcian & @szokeasaurusrex +- feat(logs): send logs in batches (#831) by @lcian ### Behavioral changes @@ -14,15 +22,10 @@ - This information is used as a fallback when capturing an event with tracing disabled or otherwise no ongoing span, to still allow related events to be linked by a trace. - A new API `Scope::iter_trace_propagation_headers` has been provided that will use the fallback tracing information if there is no current `Span` on the `Scope`. -### Features +### Breaking changes -- feat(logs): add log protocol types (#821) by @lcian -- feat(logs): add ability to capture and send logs (#823) by @lcian & @Swatinem -- feat(logs): add macro-based API (#827) by @lcian & @szokeasaurusrex - - Support for [Sentry structured logs](https://docs.sentry.io/product/explore/logs/) has been added. - - To enable logs, enable the `UNSTABLE_logs` feature of the `sentry` crate and set `enable_logs` to `true` in your client options. - - Then, use the `logger_trace!`, `logger_debug!`, `logger_info!`, `logger_warn!`, `logger_error!` and `logger_fatal!` macros to capture logs. - - Please note that breaking changes could occur until the API is finalized. +- refactor: remove `debug-logs` feature (#820) by @lcian + - The deprecated `debug-logs` feature of the `sentry` crate, used for the SDK's own internal logging, has been removed. ## 0.38.1 diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index 784571a2d..f3a143cb6 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -24,7 +24,7 @@ default = [] client = ["rand"] test = ["client", "release-health"] release-health = [] -UNSTABLE_logs = [] +logs = [] [dependencies] log = { version = "0.4.8", optional = true, features = ["std"] } diff --git a/sentry-core/src/client.rs b/sentry-core/src/client.rs index 10fafa970..c9abf6b22 100644 --- a/sentry-core/src/client.rs +++ b/sentry-core/src/client.rs @@ -5,14 +5,14 @@ use std::panic::RefUnwindSafe; use std::sync::{Arc, RwLock}; use std::time::Duration; -#[cfg(feature = "UNSTABLE_logs")] -use crate::protocol::EnvelopeItem; #[cfg(feature = "release-health")] use crate::protocol::SessionUpdate; use rand::random; use sentry_types::random_uuid; use crate::constants::SDK_INFO; +#[cfg(feature = "logs")] +use crate::logs::LogsBatcher; use crate::protocol::{ClientSdkInfo, Event}; #[cfg(feature = "release-health")] use crate::session::SessionFlusher; @@ -20,7 +20,7 @@ use crate::types::{Dsn, Uuid}; #[cfg(feature = "release-health")] use crate::SessionMode; use crate::{ClientOptions, Envelope, Hub, Integration, Scope, Transport}; -#[cfg(feature = "UNSTABLE_logs")] +#[cfg(feature = "logs")] use sentry_types::protocol::v7::{Log, LogAttribute}; impl> From for Client { @@ -53,6 +53,8 @@ pub struct Client { transport: TransportArc, #[cfg(feature = "release-health")] session_flusher: RwLock>, + #[cfg(feature = "logs")] + logs_batcher: RwLock>, integrations: Vec<(TypeId, Arc)>, pub(crate) sdk_info: ClientSdkInfo, } @@ -76,11 +78,20 @@ impl Clone for Client { self.options.session_mode, ))); + #[cfg(feature = "logs")] + let logs_batcher = RwLock::new(if self.options.enable_logs { + Some(LogsBatcher::new(transport.clone())) + } else { + None + }); + Client { options: self.options.clone(), transport, #[cfg(feature = "release-health")] session_flusher, + #[cfg(feature = "logs")] + logs_batcher, integrations: self.integrations.clone(), sdk_info: self.sdk_info.clone(), } @@ -150,11 +161,20 @@ impl Client { options.session_mode, ))); + #[cfg(feature = "logs")] + let logs_batcher = RwLock::new(if options.enable_logs { + Some(LogsBatcher::new(transport.clone())) + } else { + None + }); + Client { options, transport, #[cfg(feature = "release-health")] session_flusher, + #[cfg(feature = "logs")] + logs_batcher, integrations, sdk_info, } @@ -329,6 +349,10 @@ impl Client { if let Some(ref flusher) = *self.session_flusher.read().unwrap() { flusher.flush(); } + #[cfg(feature = "logs")] + if let Some(ref batcher) = *self.logs_batcher.read().unwrap() { + batcher.flush(); + } if let Some(ref transport) = *self.transport.read().unwrap() { transport.flush(timeout.unwrap_or(self.options.shutdown_timeout)) } else { @@ -346,6 +370,8 @@ impl Client { pub fn close(&self, timeout: Option) -> bool { #[cfg(feature = "release-health")] drop(self.session_flusher.write().unwrap().take()); + #[cfg(feature = "logs")] + drop(self.logs_batcher.write().unwrap().take()); let transport_opt = self.transport.write().unwrap().take(); if let Some(transport) = transport_opt { sentry_debug!("client close; request transport to shut down"); @@ -369,24 +395,21 @@ impl Client { } /// Captures a log and sends it to Sentry. - #[cfg(feature = "UNSTABLE_logs")] + #[cfg(feature = "logs")] pub fn capture_log(&self, log: Log, scope: &Scope) { if !self.options().enable_logs { return; } - if let Some(ref transport) = *self.transport.read().unwrap() { - if let Some(log) = self.prepare_log(log, scope) { - let mut envelope = Envelope::new(); - let logs: EnvelopeItem = vec![log].into(); - envelope.add_item(logs); - transport.send_envelope(envelope); + if let Some(log) = self.prepare_log(log, scope) { + if let Some(ref batcher) = *self.logs_batcher.read().unwrap() { + batcher.enqueue(log); } } } /// Prepares a log to be sent, setting the `trace_id` and other default attributes, and /// processing it through `before_send_log`. - #[cfg(feature = "UNSTABLE_logs")] + #[cfg(feature = "logs")] fn prepare_log(&self, mut log: Log, scope: &Scope) -> Option { scope.apply_to_log(&mut log, self.options.send_default_pii); @@ -399,7 +422,7 @@ impl Client { Some(log) } - #[cfg(feature = "UNSTABLE_logs")] + #[cfg(feature = "logs")] fn set_log_default_attributes(&self, log: &mut Log) { if !log.attributes.contains_key("sentry.environment") { if let Some(environment) = self.options.environment.as_ref() { diff --git a/sentry-core/src/clientoptions.rs b/sentry-core/src/clientoptions.rs index a741cf434..a34077880 100644 --- a/sentry-core/src/clientoptions.rs +++ b/sentry-core/src/clientoptions.rs @@ -5,7 +5,7 @@ use std::time::Duration; use crate::constants::USER_AGENT; use crate::performance::TracesSampler; -#[cfg(feature = "UNSTABLE_logs")] +#[cfg(feature = "logs")] use crate::protocol::Log; use crate::protocol::{Breadcrumb, Event}; use crate::types::Dsn; @@ -147,7 +147,7 @@ pub struct ClientOptions { /// Callback that is executed for each Breadcrumb being added. pub before_breadcrumb: Option>, /// Callback that is executed for each Log being added. - #[cfg(feature = "UNSTABLE_logs")] + #[cfg(feature = "logs")] pub before_send_log: Option>, // Transport options /// The transport to use. @@ -171,7 +171,7 @@ pub struct ClientOptions { /// server integrations. Needs `send_default_pii` to be enabled to have any effect. pub max_request_body_size: MaxRequestBodySize, /// Determines whether captured structured logs should be sent to Sentry (defaults to false). - #[cfg(feature = "UNSTABLE_logs")] + #[cfg(feature = "logs")] pub enable_logs: bool, // Other options not documented in Unified API /// Disable SSL verification. @@ -232,7 +232,7 @@ impl fmt::Debug for ClientOptions { #[derive(Debug)] struct BeforeBreadcrumb; let before_breadcrumb = self.before_breadcrumb.as_ref().map(|_| BeforeBreadcrumb); - #[cfg(feature = "UNSTABLE_logs")] + #[cfg(feature = "logs")] let before_send_log = { #[derive(Debug)] struct BeforeSendLog; @@ -279,7 +279,7 @@ impl fmt::Debug for ClientOptions { .field("auto_session_tracking", &self.auto_session_tracking) .field("session_mode", &self.session_mode); - #[cfg(feature = "UNSTABLE_logs")] + #[cfg(feature = "logs")] debug_struct .field("enable_logs", &self.enable_logs) .field("before_send_log", &before_send_log); @@ -325,9 +325,9 @@ impl Default for ClientOptions { trim_backtraces: true, user_agent: Cow::Borrowed(USER_AGENT), max_request_body_size: MaxRequestBodySize::Medium, - #[cfg(feature = "UNSTABLE_logs")] + #[cfg(feature = "logs")] enable_logs: false, - #[cfg(feature = "UNSTABLE_logs")] + #[cfg(feature = "logs")] before_send_log: None, } } diff --git a/sentry-core/src/hub.rs b/sentry-core/src/hub.rs index fe246078b..ebd70b0ca 100644 --- a/sentry-core/src/hub.rs +++ b/sentry-core/src/hub.rs @@ -247,7 +247,7 @@ impl Hub { } /// Captures a structured log. - #[cfg(feature = "UNSTABLE_logs")] + #[cfg(feature = "logs")] pub fn capture_log(&self, log: Log) { with_client_impl! {{ let top = self.inner.with(|stack| stack.top().clone()); diff --git a/sentry-core/src/lib.rs b/sentry-core/src/lib.rs index d21cc6baa..a39e63ca5 100644 --- a/sentry-core/src/lib.rs +++ b/sentry-core/src/lib.rs @@ -132,7 +132,7 @@ pub use crate::intodsn::IntoDsn; pub use crate::performance::*; pub use crate::scope::{Scope, ScopeGuard}; pub use crate::transport::{Transport, TransportFactory}; -#[cfg(feature = "UNSTABLE_logs")] +#[cfg(feature = "logs")] mod logger; // structured logging macros exported with `#[macro_export]` // client feature @@ -140,6 +140,8 @@ mod logger; // structured logging macros exported with `#[macro_export]` mod client; #[cfg(feature = "client")] mod hub_impl; +#[cfg(all(feature = "client", feature = "logs"))] +mod logs; #[cfg(feature = "client")] mod session; diff --git a/sentry-core/src/logs.rs b/sentry-core/src/logs.rs new file mode 100644 index 000000000..9be3ee335 --- /dev/null +++ b/sentry-core/src/logs.rs @@ -0,0 +1,197 @@ +//! Batching for Sentry [structured logs](https://docs.sentry.io/product/explore/logs/). + +use std::sync::{Arc, Condvar, Mutex, MutexGuard}; +use std::thread::JoinHandle; +use std::time::{Duration, Instant}; + +use crate::client::TransportArc; +use crate::protocol::EnvelopeItem; +use crate::Envelope; +use sentry_types::protocol::v7::Log; + +// Flush when there's 100 logs in the buffer +const MAX_LOG_ITEMS: usize = 100; +// Or when 5 seconds have passed from the last flush +const FLUSH_INTERVAL: Duration = Duration::from_secs(5); + +#[derive(Debug, Default)] +struct LogQueue { + logs: Vec, +} + +/// Accumulates logs in the queue and submits them through the transport when one of the flushing +/// conditions is met. +pub(crate) struct LogsBatcher { + transport: TransportArc, + queue: Arc>, + shutdown: Arc<(Mutex, Condvar)>, + worker: Option>, +} + +impl LogsBatcher { + /// Creates a new LogsBatcher that will submit envelopes to the given `transport`. + pub(crate) fn new(transport: TransportArc) -> Self { + let queue = Arc::new(Mutex::new(Default::default())); + #[allow(clippy::mutex_atomic)] + let shutdown = Arc::new((Mutex::new(false), Condvar::new())); + + let worker_transport = transport.clone(); + let worker_queue = queue.clone(); + let worker_shutdown = shutdown.clone(); + let worker = std::thread::Builder::new() + .name("sentry-logs-batcher".into()) + .spawn(move || { + let (lock, cvar) = worker_shutdown.as_ref(); + let mut shutdown = lock.lock().unwrap(); + // check this immediately, in case the main thread is already shutting down + if *shutdown { + return; + } + let mut last_flush = Instant::now(); + loop { + let timeout = FLUSH_INTERVAL + .checked_sub(last_flush.elapsed()) + .unwrap_or_else(|| Duration::from_secs(0)); + shutdown = cvar.wait_timeout(shutdown, timeout).unwrap().0; + if *shutdown { + return; + } + if last_flush.elapsed() >= FLUSH_INTERVAL { + LogsBatcher::flush_queue_internal( + worker_queue.lock().unwrap(), + &worker_transport, + ); + last_flush = Instant::now(); + } + } + }) + .unwrap(); + + Self { + transport, + queue, + shutdown, + worker: Some(worker), + } + } + + /// Enqueues a log for delayed sending. + /// + /// This will automatically flush the queue if it reaches a size of `BATCH_SIZE`. + pub(crate) fn enqueue(&self, log: Log) { + let mut queue = self.queue.lock().unwrap(); + queue.logs.push(log); + if queue.logs.len() >= MAX_LOG_ITEMS { + LogsBatcher::flush_queue_internal(queue, &self.transport); + } + } + + /// Flushes the queue to the transport. + pub(crate) fn flush(&self) { + let queue = self.queue.lock().unwrap(); + LogsBatcher::flush_queue_internal(queue, &self.transport); + } + + /// Flushes the queue to the transport. + /// + /// This is a static method as it will be called from both the background + /// thread and the main thread on drop. + fn flush_queue_internal(mut queue_lock: MutexGuard, transport: &TransportArc) { + let logs = std::mem::take(&mut queue_lock.logs); + drop(queue_lock); + + if logs.is_empty() { + return; + } + + sentry_debug!("[LogsBatcher] Flushing {} logs", logs.len()); + + if let Some(ref transport) = *transport.read().unwrap() { + let mut envelope = Envelope::new(); + let logs_item: EnvelopeItem = logs.into(); + envelope.add_item(logs_item); + transport.send_envelope(envelope); + } + } +} + +impl Drop for LogsBatcher { + fn drop(&mut self) { + let (lock, cvar) = self.shutdown.as_ref(); + *lock.lock().unwrap() = true; + cvar.notify_one(); + + if let Some(worker) = self.worker.take() { + worker.join().ok(); + } + LogsBatcher::flush_queue_internal(self.queue.lock().unwrap(), &self.transport); + } +} + +#[cfg(all(test, feature = "test"))] +mod tests { + use crate::logger_info; + use crate::test; + + // Test that logs are sent in batches + #[test] + fn test_logs_batching() { + let envelopes = test::with_captured_envelopes_options( + || { + for i in 0..150 { + logger_info!("test log {}", i); + } + }, + crate::ClientOptions { + enable_logs: true, + ..Default::default() + }, + ); + + assert_eq!(2, envelopes.len()); + + let mut total_logs = 0; + for envelope in &envelopes { + for item in envelope.items() { + if let crate::protocol::EnvelopeItem::ItemContainer( + crate::protocol::ItemContainer::Logs(logs), + ) = item + { + total_logs += logs.len(); + } + } + } + + assert_eq!(150, total_logs); + } + + // Test that the batcher is flushed on client close + #[test] + fn test_logs_batcher_flush() { + let envelopes = test::with_captured_envelopes_options( + || { + for i in 0..12 { + logger_info!("test log {}", i); + } + }, + crate::ClientOptions { + enable_logs: true, + ..Default::default() + }, + ); + + assert_eq!(1, envelopes.len()); + + for envelope in &envelopes { + for item in envelope.items() { + if let crate::protocol::EnvelopeItem::ItemContainer( + crate::protocol::ItemContainer::Logs(logs), + ) = item + { + assert_eq!(12, logs.len()); + break; + } + } + } + } +} diff --git a/sentry-core/src/scope/noop.rs b/sentry-core/src/scope/noop.rs index 578c1f9b0..fc62120b9 100644 --- a/sentry-core/src/scope/noop.rs +++ b/sentry-core/src/scope/noop.rs @@ -1,6 +1,6 @@ use std::fmt; -#[cfg(feature = "UNSTABLE_logs")] +#[cfg(feature = "logs")] use crate::protocol::Log; use crate::protocol::{Context, Event, Level, User, Value}; use crate::TransactionOrSpan; @@ -113,7 +113,7 @@ impl Scope { } /// Applies the contained scoped data to fill a log. - #[cfg(feature = "UNSTABLE_logs")] + #[cfg(feature = "logs")] pub fn apply_to_log(&self, log: &mut Log) { let _log = log; minimal_unreachable!(); diff --git a/sentry-core/src/scope/real.rs b/sentry-core/src/scope/real.rs index c8147ce03..f4972cf19 100644 --- a/sentry-core/src/scope/real.rs +++ b/sentry-core/src/scope/real.rs @@ -9,7 +9,7 @@ use crate::performance::TransactionOrSpan; use crate::protocol::{ Attachment, Breadcrumb, Context, Event, Level, TraceContext, Transaction, User, Value, }; -#[cfg(feature = "UNSTABLE_logs")] +#[cfg(feature = "logs")] use crate::protocol::{Log, LogAttribute}; #[cfg(feature = "release-health")] use crate::session::Session; @@ -350,7 +350,7 @@ impl Scope { /// Applies the contained scoped data to a log, setting the `trace_id` and certain default /// attributes. - #[cfg(feature = "UNSTABLE_logs")] + #[cfg(feature = "logs")] pub fn apply_to_log(&self, log: &mut Log, send_default_pii: bool) { if let Some(span) = self.span.as_ref() { log.trace_id = Some(span.get_trace_context().trace_id); diff --git a/sentry-types/src/protocol/envelope.rs b/sentry-types/src/protocol/envelope.rs index 43a9c35ff..190c439b2 100644 --- a/sentry-types/src/protocol/envelope.rs +++ b/sentry-types/src/protocol/envelope.rs @@ -308,7 +308,7 @@ impl Envelope { } /// Create an [`Iterator`] over all the [`EnvelopeItem`]s. - pub fn items(&self) -> EnvelopeItemIter { + pub fn items(&self) -> EnvelopeItemIter<'_> { let inner = match &self.items { Items::EnvelopeItems(items) => items.iter(), Items::Raw(_) => [].iter(), diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index 9ab7e3159..7737c31a5 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -48,7 +48,7 @@ opentelemetry = ["sentry-opentelemetry"] # other features test = ["sentry-core/test"] release-health = ["sentry-core/release-health", "sentry-actix?/release-health"] -UNSTABLE_logs = ["sentry-core/UNSTABLE_logs"] +logs = ["sentry-core/logs"] # transports transport = ["reqwest", "native-tls"] reqwest = ["dep:reqwest", "httpdate", "tokio"] diff --git a/sentry/tests/test_basic.rs b/sentry/tests/test_basic.rs index fb80c90db..8f5f4d0bc 100644 --- a/sentry/tests/test_basic.rs +++ b/sentry/tests/test_basic.rs @@ -265,7 +265,7 @@ fn test_panic_scope_pop() { ); } -#[cfg(feature = "UNSTABLE_logs")] +#[cfg(feature = "logs")] #[test] fn test_basic_capture_log() { use std::time::SystemTime; @@ -314,7 +314,7 @@ fn test_basic_capture_log() { } } -#[cfg(feature = "UNSTABLE_logs")] +#[cfg(feature = "logs")] #[test] fn test_basic_capture_log_macro_message() { use sentry_core::logger_info; @@ -349,7 +349,7 @@ fn test_basic_capture_log_macro_message() { } } -#[cfg(feature = "UNSTABLE_logs")] +#[cfg(feature = "logs")] #[test] fn test_basic_capture_log_macro_message_formatted() { use sentry::protocol::LogAttribute; @@ -416,7 +416,7 @@ fn test_basic_capture_log_macro_message_formatted() { } } -#[cfg(feature = "UNSTABLE_logs")] +#[cfg(feature = "logs")] #[test] fn test_basic_capture_log_macro_message_with_attributes() { use sentry::protocol::LogAttribute; @@ -475,7 +475,7 @@ fn test_basic_capture_log_macro_message_with_attributes() { } } -#[cfg(feature = "UNSTABLE_logs")] +#[cfg(feature = "logs")] #[test] fn test_basic_capture_log_macro_message_formatted_with_attributes() { use sentry::protocol::LogAttribute; From 37dda6bd1d1da62bc888c8267ed6c1b005aba3cf Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Tue, 10 Jun 2025 11:50:38 +0000 Subject: [PATCH 099/148] release: 0.39.0 --- CHANGELOG.md | 2 +- sentry-actix/Cargo.toml | 4 ++-- sentry-anyhow/Cargo.toml | 6 +++--- sentry-backtrace/Cargo.toml | 4 ++-- sentry-contexts/Cargo.toml | 4 ++-- sentry-core/Cargo.toml | 4 ++-- sentry-core/README.md | 2 +- sentry-debug-images/Cargo.toml | 4 ++-- sentry-debug-images/README.md | 2 +- sentry-log/Cargo.toml | 4 ++-- sentry-opentelemetry/Cargo.toml | 4 ++-- sentry-panic/Cargo.toml | 6 +++--- sentry-slog/Cargo.toml | 4 ++-- sentry-tower/Cargo.toml | 4 ++-- sentry-tower/README.md | 2 +- sentry-tracing/Cargo.toml | 6 +++--- sentry-tracing/README.md | 2 +- sentry-types/Cargo.toml | 2 +- sentry/Cargo.toml | 26 +++++++++++++------------- sentry/README.md | 12 ++++++------ 20 files changed, 52 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b15c5469..2d2492e58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 0.39.0 ### Features diff --git a/sentry-actix/Cargo.toml b/sentry-actix/Cargo.toml index 1adbe2a48..132f4be64 100644 --- a/sentry-actix/Cargo.toml +++ b/sentry-actix/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-actix" -version = "0.38.1" +version = "0.39.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -20,7 +20,7 @@ release-health = ["sentry-core/release-health"] actix-web = { version = "4", default-features = false } bytes = "1.2" futures-util = { version = "0.3.5", default-features = false } -sentry-core = { version = "0.38.1", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.39.0", path = "../sentry-core", default-features = false, features = [ "client", ] } actix-http = "3.10" diff --git a/sentry-anyhow/Cargo.toml b/sentry-anyhow/Cargo.toml index 1d0abab81..902d37d49 100644 --- a/sentry-anyhow/Cargo.toml +++ b/sentry-anyhow/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-anyhow" -version = "0.38.1" +version = "0.39.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -17,8 +17,8 @@ default = ["backtrace"] backtrace = ["anyhow/backtrace"] [dependencies] -sentry-backtrace = { version = "0.38.1", path = "../sentry-backtrace" } -sentry-core = { version = "0.38.1", path = "../sentry-core" } +sentry-backtrace = { version = "0.39.0", path = "../sentry-backtrace" } +sentry-core = { version = "0.39.0", path = "../sentry-core" } anyhow = "1.0.39" [dev-dependencies] diff --git a/sentry-backtrace/Cargo.toml b/sentry-backtrace/Cargo.toml index a5d7a6931..2813a8141 100644 --- a/sentry-backtrace/Cargo.toml +++ b/sentry-backtrace/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-backtrace" -version = "0.38.1" +version = "0.39.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -18,4 +18,4 @@ regex = { version = "1.5.5", default-features = false, features = [ "std", "unicode-perl", ] } -sentry-core = { version = "0.38.1", path = "../sentry-core" } +sentry-core = { version = "0.39.0", path = "../sentry-core" } diff --git a/sentry-contexts/Cargo.toml b/sentry-contexts/Cargo.toml index 8cceacb26..9a965b51a 100644 --- a/sentry-contexts/Cargo.toml +++ b/sentry-contexts/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-contexts" -version = "0.38.1" +version = "0.39.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -14,7 +14,7 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.38.1", path = "../sentry-core" } +sentry-core = { version = "0.39.0", path = "../sentry-core" } libc = "0.2.66" hostname = "0.4" diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index f3a143cb6..1aa95fb42 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-core" -version = "0.38.1" +version = "0.39.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -29,7 +29,7 @@ logs = [] [dependencies] log = { version = "0.4.8", optional = true, features = ["std"] } rand = { version = "0.9.0", optional = true } -sentry-types = { version = "0.38.1", path = "../sentry-types" } +sentry-types = { version = "0.39.0", path = "../sentry-types" } serde = { version = "1.0.104", features = ["derive"] } serde_json = { version = "1.0.46" } uuid = { version = "1.0.0", features = ["v4", "serde"], optional = true } diff --git a/sentry-core/README.md b/sentry-core/README.md index d6118d384..844b9e92b 100644 --- a/sentry-core/README.md +++ b/sentry-core/README.md @@ -99,7 +99,7 @@ functionality. [Sentry]: https://sentry.io/ [`sentry`]: https://crates.io/crates/sentry [Unified API]: https://develop.sentry.dev/sdk/unified-api/ -[`test`]: https://docs.rs/sentry-core/0.38.1/sentry_core/test/index.html +[`test`]: https://docs.rs/sentry-core/0.39.0/sentry_core/test/index.html ## Resources diff --git a/sentry-debug-images/Cargo.toml b/sentry-debug-images/Cargo.toml index cce22992f..b5ece5011 100644 --- a/sentry-debug-images/Cargo.toml +++ b/sentry-debug-images/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-debug-images" -version = "0.38.1" +version = "0.39.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -14,4 +14,4 @@ rust-version = "1.81" [dependencies] findshlibs = "=0.10.2" -sentry-core = { version = "0.38.1", path = "../sentry-core" } +sentry-core = { version = "0.39.0", path = "../sentry-core" } diff --git a/sentry-debug-images/README.md b/sentry-debug-images/README.md index 1065e0bf4..0fc832aec 100644 --- a/sentry-debug-images/README.md +++ b/sentry-debug-images/README.md @@ -22,7 +22,7 @@ let integration = sentry_debug_images::DebugImagesIntegration::new() .filter(|event| event.level >= Level::Warning); ``` -[`Event`]: https://docs.rs/sentry-debug-images/0.38.1/sentry_debug_images/sentry_core::protocol::Event +[`Event`]: https://docs.rs/sentry-debug-images/0.39.0/sentry_debug_images/sentry_core::protocol::Event ## Resources diff --git a/sentry-log/Cargo.toml b/sentry-log/Cargo.toml index ff92bafd1..10de5a4ee 100644 --- a/sentry-log/Cargo.toml +++ b/sentry-log/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-log" -version = "0.38.1" +version = "0.39.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.38.1", path = "../sentry-core" } +sentry-core = { version = "0.39.0", path = "../sentry-core" } log = { version = "0.4.8", features = ["std"] } [dev-dependencies] diff --git a/sentry-opentelemetry/Cargo.toml b/sentry-opentelemetry/Cargo.toml index 1bced8e73..f70370cd0 100644 --- a/sentry-opentelemetry/Cargo.toml +++ b/sentry-opentelemetry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-opentelemetry" -version = "0.38.1" +version = "0.39.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -16,7 +16,7 @@ rust-version = "1.81" all-features = true [dependencies] -sentry-core = { version = "0.38.1", path = "../sentry-core", features = [ +sentry-core = { version = "0.39.0", path = "../sentry-core", features = [ "client", ] } opentelemetry = { version = "0.29.0", default-features = false } diff --git a/sentry-panic/Cargo.toml b/sentry-panic/Cargo.toml index 000ecfa6d..ca6e28b45 100644 --- a/sentry-panic/Cargo.toml +++ b/sentry-panic/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-panic" -version = "0.38.1" +version = "0.39.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -13,8 +13,8 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.38.1", path = "../sentry-core" } -sentry-backtrace = { version = "0.38.1", path = "../sentry-backtrace" } +sentry-core = { version = "0.39.0", path = "../sentry-core" } +sentry-backtrace = { version = "0.39.0", path = "../sentry-backtrace" } [dev-dependencies] sentry = { path = "../sentry", default-features = false, features = ["test"] } diff --git a/sentry-slog/Cargo.toml b/sentry-slog/Cargo.toml index 964882882..65e8fe94e 100644 --- a/sentry-slog/Cargo.toml +++ b/sentry-slog/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-slog" -version = "0.38.1" +version = "0.39.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.38.1", path = "../sentry-core" } +sentry-core = { version = "0.39.0", path = "../sentry-core" } slog = { version = "2.5.2", features = ["nested-values"] } serde_json = "1.0.46" diff --git a/sentry-tower/Cargo.toml b/sentry-tower/Cargo.toml index b72f53a14..61a6fc8a1 100644 --- a/sentry-tower/Cargo.toml +++ b/sentry-tower/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tower" -version = "0.38.1" +version = "0.39.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -26,7 +26,7 @@ tower-layer = "0.3" tower-service = "0.3" http = { version = "1.0.0", optional = true } pin-project = { version = "1.0.10", optional = true } -sentry-core = { version = "0.38.1", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.39.0", path = "../sentry-core", default-features = false, features = [ "client", ] } url = { version = "2.2.2", optional = true } diff --git a/sentry-tower/README.md b/sentry-tower/README.md index 944dea7eb..f169b6ef5 100644 --- a/sentry-tower/README.md +++ b/sentry-tower/README.md @@ -103,7 +103,7 @@ feature of the `sentry` crate instead of the `tower` feature. The created transaction will automatically use the request URI as its name. This is sometimes not desirable in case the request URI contains unique IDs or similar. In this case, users should manually override the transaction name -in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.38.1/sentry_tower/sentry_core::Scope::set_transaction) +in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.39.0/sentry_tower/sentry_core::Scope::set_transaction) method. When combining both layers, take care of the ordering of both. For example diff --git a/sentry-tracing/Cargo.toml b/sentry-tracing/Cargo.toml index ec8d927fd..e9c9b348e 100644 --- a/sentry-tracing/Cargo.toml +++ b/sentry-tracing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tracing" -version = "0.38.1" +version = "0.39.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -20,14 +20,14 @@ default = [] backtrace = ["dep:sentry-backtrace"] [dependencies] -sentry-core = { version = "0.38.1", path = "../sentry-core", features = [ +sentry-core = { version = "0.39.0", path = "../sentry-core", features = [ "client", ] } tracing-core = "0.1" tracing-subscriber = { version = "0.3.1", default-features = false, features = [ "std", ] } -sentry-backtrace = { version = "0.38.1", path = "../sentry-backtrace", optional = true } +sentry-backtrace = { version = "0.39.0", path = "../sentry-backtrace", optional = true } [dev-dependencies] log = "0.4" diff --git a/sentry-tracing/README.md b/sentry-tracing/README.md index 755b0323c..1fb79e80a 100644 --- a/sentry-tracing/README.md +++ b/sentry-tracing/README.md @@ -83,7 +83,7 @@ tracing::error!( ); ``` -To track [error structs](https://docs.rs/sentry-tracing/0.38.1/sentry_tracing/std::error::Error), assign a reference to error trait object as field +To track [error structs](https://docs.rs/sentry-tracing/0.39.0/sentry_tracing/std::error::Error), assign a reference to error trait object as field in one of the logging macros. By convention, it is recommended to use the `ERROR` level and assign it to a field called `error`, although the integration will also work with all other levels and field names. diff --git a/sentry-types/Cargo.toml b/sentry-types/Cargo.toml index f5bec5620..d78c18cfe 100644 --- a/sentry-types/Cargo.toml +++ b/sentry-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-types" -version = "0.38.1" +version = "0.39.0" authors = ["Sentry "] license = "MIT" readme = "README.md" diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index 7737c31a5..7f88dbd31 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry" -version = "0.38.1" +version = "0.39.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -60,20 +60,20 @@ rustls = ["dep:rustls", "reqwest?/rustls-tls", "ureq?/tls", "webpki-roots"] embedded-svc-http = ["dep:embedded-svc", "dep:esp-idf-svc"] [dependencies] -sentry-core = { version = "0.38.1", path = "../sentry-core", features = [ +sentry-core = { version = "0.39.0", path = "../sentry-core", features = [ "client", ] } -sentry-anyhow = { version = "0.38.1", path = "../sentry-anyhow", optional = true } -sentry-actix = { version = "0.38.1", path = "../sentry-actix", optional = true, default-features = false } -sentry-backtrace = { version = "0.38.1", path = "../sentry-backtrace", optional = true } -sentry-contexts = { version = "0.38.1", path = "../sentry-contexts", optional = true } -sentry-debug-images = { version = "0.38.1", path = "../sentry-debug-images", optional = true } -sentry-log = { version = "0.38.1", path = "../sentry-log", optional = true } -sentry-panic = { version = "0.38.1", path = "../sentry-panic", optional = true } -sentry-slog = { version = "0.38.1", path = "../sentry-slog", optional = true } -sentry-tower = { version = "0.38.1", path = "../sentry-tower", optional = true } -sentry-tracing = { version = "0.38.1", path = "../sentry-tracing", optional = true } -sentry-opentelemetry = { version = "0.38.1", path = "../sentry-opentelemetry", optional = true } +sentry-anyhow = { version = "0.39.0", path = "../sentry-anyhow", optional = true } +sentry-actix = { version = "0.39.0", path = "../sentry-actix", optional = true, default-features = false } +sentry-backtrace = { version = "0.39.0", path = "../sentry-backtrace", optional = true } +sentry-contexts = { version = "0.39.0", path = "../sentry-contexts", optional = true } +sentry-debug-images = { version = "0.39.0", path = "../sentry-debug-images", optional = true } +sentry-log = { version = "0.39.0", path = "../sentry-log", optional = true } +sentry-panic = { version = "0.39.0", path = "../sentry-panic", optional = true } +sentry-slog = { version = "0.39.0", path = "../sentry-slog", optional = true } +sentry-tower = { version = "0.39.0", path = "../sentry-tower", optional = true } +sentry-tracing = { version = "0.39.0", path = "../sentry-tracing", optional = true } +sentry-opentelemetry = { version = "0.39.0", path = "../sentry-opentelemetry", optional = true } reqwest = { version = "0.12", optional = true, features = [ "blocking", "json", diff --git a/sentry/README.md b/sentry/README.md index c28116cca..7034146a5 100644 --- a/sentry/README.md +++ b/sentry/README.md @@ -34,8 +34,8 @@ sentry::capture_message("Hello World!", sentry::Level::Info); More complex examples on how to use sentry can also be found in [examples]. Extended instructions may also be found on [Sentry itself]. -[`sentry::init`]: https://docs.rs/sentry/0.38.1/sentry/fn.init.html -[`Hub`]: https://docs.rs/sentry/0.38.1/sentry/struct.Hub.html +[`sentry::init`]: https://docs.rs/sentry/0.39.0/sentry/fn.init.html +[`Hub`]: https://docs.rs/sentry/0.39.0/sentry/struct.Hub.html [examples]: https://github.com/getsentry/sentry-rust/tree/master/sentry/examples [Sentry itself]: https://docs.sentry.io/platforms/rust @@ -47,8 +47,8 @@ the ecosystem require a feature flag. For available integrations and how to use [integrations] and [apply_defaults]. [Features]: #features -[integrations]: https://docs.rs/sentry/0.38.1/sentry/integrations/index.html -[apply_defaults]: https://docs.rs/sentry/0.38.1/sentry/fn.apply_defaults.html +[integrations]: https://docs.rs/sentry/0.39.0/sentry/integrations/index.html +[apply_defaults]: https://docs.rs/sentry/0.39.0/sentry/fn.apply_defaults.html ## Minimal API @@ -56,8 +56,8 @@ This crate comes fully-featured. If the goal is to instrument libraries for usag with sentry, or to extend sentry with a custom [`Integration`] or a [`Transport`], one should use the [`sentry-core`] crate instead. -[`Integration`]: https://docs.rs/sentry/0.38.1/sentry/trait.Integration.html -[`Transport`]: https://docs.rs/sentry/0.38.1/sentry/trait.Transport.html +[`Integration`]: https://docs.rs/sentry/0.39.0/sentry/trait.Integration.html +[`Transport`]: https://docs.rs/sentry/0.39.0/sentry/trait.Transport.html [`sentry-core`]: https://crates.io/crates/sentry-core From 644ee85c522d16c0acdc0900242ffbe615a5971d Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Tue, 10 Jun 2025 15:49:08 +0200 Subject: [PATCH 100/148] fix(logs): send environment in `sentry.environment` default attribute (#837) --- CHANGELOG.md | 6 ++++++ Cargo.lock | 28 ++++++++++++++-------------- sentry-core/src/client.rs | 2 +- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d2492e58..dfe010822 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Fixes + +- fix(logs): send environment in `sentry.environment` default attribute (#837) by @lcian + ## 0.39.0 ### Features diff --git a/Cargo.lock b/Cargo.lock index 0bd5fa94b..da67f55b3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3137,7 +3137,7 @@ dependencies = [ [[package]] name = "sentry" -version = "0.38.1" +version = "0.39.0" dependencies = [ "actix-web", "anyhow", @@ -3174,7 +3174,7 @@ dependencies = [ [[package]] name = "sentry-actix" -version = "0.38.1" +version = "0.39.0" dependencies = [ "actix-http", "actix-web", @@ -3188,7 +3188,7 @@ dependencies = [ [[package]] name = "sentry-anyhow" -version = "0.38.1" +version = "0.39.0" dependencies = [ "anyhow", "sentry", @@ -3198,7 +3198,7 @@ dependencies = [ [[package]] name = "sentry-backtrace" -version = "0.38.1" +version = "0.39.0" dependencies = [ "backtrace", "regex", @@ -3207,7 +3207,7 @@ dependencies = [ [[package]] name = "sentry-contexts" -version = "0.38.1" +version = "0.39.0" dependencies = [ "hostname", "libc", @@ -3220,7 +3220,7 @@ dependencies = [ [[package]] name = "sentry-core" -version = "0.38.1" +version = "0.39.0" dependencies = [ "anyhow", "criterion", @@ -3239,7 +3239,7 @@ dependencies = [ [[package]] name = "sentry-debug-images" -version = "0.38.1" +version = "0.39.0" dependencies = [ "findshlibs", "sentry-core", @@ -3247,7 +3247,7 @@ dependencies = [ [[package]] name = "sentry-log" -version = "0.38.1" +version = "0.39.0" dependencies = [ "log", "pretty_env_logger", @@ -3257,7 +3257,7 @@ dependencies = [ [[package]] name = "sentry-opentelemetry" -version = "0.38.1" +version = "0.39.0" dependencies = [ "opentelemetry", "opentelemetry_sdk", @@ -3267,7 +3267,7 @@ dependencies = [ [[package]] name = "sentry-panic" -version = "0.38.1" +version = "0.39.0" dependencies = [ "sentry", "sentry-backtrace", @@ -3276,7 +3276,7 @@ dependencies = [ [[package]] name = "sentry-slog" -version = "0.38.1" +version = "0.39.0" dependencies = [ "erased-serde", "sentry", @@ -3288,7 +3288,7 @@ dependencies = [ [[package]] name = "sentry-tower" -version = "0.38.1" +version = "0.39.0" dependencies = [ "anyhow", "axum 0.8.3", @@ -3308,7 +3308,7 @@ dependencies = [ [[package]] name = "sentry-tracing" -version = "0.38.1" +version = "0.39.0" dependencies = [ "log", "sentry", @@ -3323,7 +3323,7 @@ dependencies = [ [[package]] name = "sentry-types" -version = "0.38.1" +version = "0.39.0" dependencies = [ "debugid", "hex", diff --git a/sentry-core/src/client.rs b/sentry-core/src/client.rs index c9abf6b22..487f87cd0 100644 --- a/sentry-core/src/client.rs +++ b/sentry-core/src/client.rs @@ -427,7 +427,7 @@ impl Client { if !log.attributes.contains_key("sentry.environment") { if let Some(environment) = self.options.environment.as_ref() { log.attributes.insert( - "sentry.sdk.version".to_owned(), + "sentry.environment".to_owned(), LogAttribute(environment.clone().into()), ); } From c92d8d82664393576556777a2aac0517b40b0d23 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Tue, 10 Jun 2025 16:07:01 +0200 Subject: [PATCH 101/148] feat(scripts): add command to update `Cargo.lock` (#838) --- scripts/bump-version.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/bump-version.sh b/scripts/bump-version.sh index 490ab6b6d..131a80fbd 100755 --- a/scripts/bump-version.sh +++ b/scripts/bump-version.sh @@ -14,3 +14,4 @@ perl -pi -e "s/^version = \".*?\"/version = \"$NEW_VERSION\"/" sentry*/Cargo.tom perl -pi -e "s/^(sentry.*)?version = \".*?\"/\$1version = \"$NEW_VERSION\"/" sentry*/Cargo.toml "$SCRIPT_DIR"/update-readme.sh "$NEW_VERSION" +cargo metadata --format-version 1 > /dev/null # update `Cargo.lock` From 2b1455b3f130646947d03d68d844bd3973507519 Mon Sep 17 00:00:00 2001 From: Martin Algesten Date: Wed, 11 Jun 2025 19:28:30 +0200 Subject: [PATCH 102/148] chore(deps): upgrade `ureq` to 3.x (#835) Co-authored-by: Lorenzo Cian --- CHANGELOG.md | 4 + Cargo.lock | 100 ++++++++++++++++++++----- sentry/Cargo.toml | 5 +- sentry/src/transports/ureq.rs | 136 +++++++++------------------------- 4 files changed, 123 insertions(+), 122 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dfe010822..2efa89a02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ - fix(logs): send environment in `sentry.environment` default attribute (#837) by @lcian +### Dependencies + +- chore(deps): upgrade `ureq` to 3.x (#835) by @algesten + ## 0.39.0 ### Features diff --git a/Cargo.lock b/Cargo.lock index da67f55b3..d011b9442 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -436,6 +436,12 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + [[package]] name = "bindgen" version = "0.71.1" @@ -974,6 +980,16 @@ dependencies = [ "thiserror 2.0.12", ] +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "pem-rfc7468", + "zeroize", +] + [[package]] name = "deranged" version = "0.4.0" @@ -1228,7 +1244,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -2046,7 +2062,7 @@ checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -2167,9 +2183,9 @@ checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" [[package]] name = "litemap" -version = "0.7.5" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" [[package]] name = "local-channel" @@ -2257,9 +2273,9 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.14" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" dependencies = [ "libc", "log", @@ -2502,6 +2518,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.1" @@ -2723,7 +2748,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -3007,7 +3032,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -3020,7 +3045,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.9.4", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -3169,7 +3194,6 @@ dependencies = [ "tracing", "tracing-subscriber", "ureq", - "webpki-roots", ] [[package]] @@ -3558,7 +3582,7 @@ dependencies = [ "getrandom 0.3.2", "once_cell", "rustix 1.0.5", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -3961,20 +3985,36 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "2.12.1" +version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d" +checksum = "b7a3e9af6113ecd57b8c63d3cd76a385b2e3881365f1f489e54f49801d0c83ea" dependencies = [ "base64", + "der", "log", "native-tls", - "once_cell", + "percent-encoding", "rustls", + "rustls-pemfile", "rustls-pki-types", - "url", + "ureq-proto", + "utf-8", + "webpki-root-certs 0.26.11", "webpki-roots", ] +[[package]] +name = "ureq-proto" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fadf18427d33828c311234884b7ba2afb57143e6e7e69fda7ee883b624661e36" +dependencies = [ + "base64", + "http 1.3.1", + "httparse", + "log", +] + [[package]] name = "url" version = "2.5.4" @@ -3987,6 +4027,12 @@ dependencies = [ "serde", ] +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "utf16_iter" version = "1.0.5" @@ -4158,6 +4204,24 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-root-certs" +version = "0.26.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75c7f0ef91146ebfb530314f5f1d24528d7f0767efbfd31dce919275413e393e" +dependencies = [ + "webpki-root-certs 1.0.0", +] + +[[package]] +name = "webpki-root-certs" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01a83f7e1a9f8712695c03eabe9ed3fbca0feff0152f33f12593e5a6303cb1a4" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "webpki-roots" version = "0.26.8" @@ -4201,7 +4265,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -4511,9 +4575,9 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.6" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" dependencies = [ "zerofrom-derive", ] diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index 7f88dbd31..72e234d62 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -56,7 +56,7 @@ curl = ["dep:curl", "httpdate"] ureq = ["dep:ureq", "httpdate"] # transport settings native-tls = ["dep:native-tls", "reqwest?/default-tls", "ureq?/native-tls"] -rustls = ["dep:rustls", "reqwest?/rustls-tls", "ureq?/tls", "webpki-roots"] +rustls = ["dep:rustls", "reqwest?/rustls-tls", "ureq?/rustls"] embedded-svc-http = ["dep:embedded-svc", "dep:esp-idf-svc"] [dependencies] @@ -82,10 +82,9 @@ curl = { version = "0.4.25", optional = true } httpdate = { version = "1.0.0", optional = true } serde_json = { version = "1.0.48", optional = true } tokio = { version = "1.44", features = ["rt"], optional = true } -ureq = { version = "2.10.1", optional = true, default-features = false } +ureq = { version = "3.0.11", optional = true, default-features = false } native-tls = { version = "0.2.8", optional = true } rustls = { version = "0.23.18", optional = true, default-features = false } -webpki-roots = { version = "0.26.1", optional = true } embedded-svc = { version = "0.28.1", optional = true } [target.'cfg(target_os = "espidf")'.dependencies] esp-idf-svc = { version = "0.51.0", optional = true } diff --git a/sentry/src/transports/ureq.rs b/sentry/src/transports/ureq.rs index ee59cd283..9fa20fe4b 100644 --- a/sentry/src/transports/ureq.rs +++ b/sentry/src/transports/ureq.rs @@ -1,19 +1,9 @@ -use std::sync::Arc; use std::time::Duration; -#[cfg(feature = "native-tls")] -use native_tls::TlsConnector; -#[cfg(feature = "rustls")] -use rustls::client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier}; -#[cfg(feature = "rustls")] -use rustls::crypto::{verify_tls12_signature, verify_tls13_signature}; -#[cfg(feature = "rustls")] -use rustls::pki_types::{CertificateDer, ServerName, TrustAnchor, UnixTime}; -#[cfg(feature = "rustls")] -use rustls::{ClientConfig, DigitallySignedStruct, RootCertStore}; -use ureq::{Agent, AgentBuilder, Proxy}; -#[cfg(feature = "rustls")] -use webpki_roots::TLS_SERVER_ROOTS; +use ureq::http::Response; +#[cfg(any(feature = "rustls", feature = "native-tls"))] +use ureq::tls::{TlsConfig, TlsProvider}; +use ureq::{Agent, Proxy}; use super::thread::TransportThread; @@ -42,92 +32,33 @@ impl UreqHttpTransport { let dsn = options.dsn.as_ref().unwrap(); let scheme = dsn.scheme(); let agent = agent.unwrap_or_else(|| { - let mut builder = AgentBuilder::new(); + let mut builder = Agent::config_builder(); #[cfg(feature = "native-tls")] { - let mut tls_connector_builder = TlsConnector::builder(); - - if options.accept_invalid_certs { - tls_connector_builder.danger_accept_invalid_certs(true); - } - - builder = builder.tls_connector(Arc::new(tls_connector_builder.build().unwrap())); + builder = builder.tls_config( + TlsConfig::builder() + .provider(TlsProvider::NativeTls) + .disable_verification(options.accept_invalid_certs) + .build(), + ); } - - if options.accept_invalid_certs { - #[cfg(feature = "rustls")] - { - #[derive(Debug)] - struct NoVerifier; - - impl ServerCertVerifier for NoVerifier { - fn verify_server_cert( - &self, - _end_entity: &CertificateDer<'_>, - _intermediates: &[CertificateDer<'_>], - _server_name: &ServerName<'_>, - _ocsp: &[u8], - _now: UnixTime, - ) -> Result { - Ok(ServerCertVerified::assertion()) - } - - fn verify_tls12_signature( - &self, - message: &[u8], - cert: &CertificateDer<'_>, - dss: &DigitallySignedStruct, - ) -> Result - { - verify_tls12_signature( - message, - cert, - dss, - &rustls::crypto::ring::default_provider() - .signature_verification_algorithms, - ) - } - - fn verify_tls13_signature( - &self, - message: &[u8], - cert: &CertificateDer<'_>, - dss: &DigitallySignedStruct, - ) -> Result - { - verify_tls13_signature( - message, - cert, - dss, - &rustls::crypto::ring::default_provider() - .signature_verification_algorithms, - ) - } - - fn supported_verify_schemes(&self) -> Vec { - rustls::crypto::ring::default_provider() - .signature_verification_algorithms - .supported_schemes() - } - } - - let mut root_store = RootCertStore::empty(); - root_store.extend(TLS_SERVER_ROOTS.iter().map(TrustAnchor::to_owned)); - let mut config = ClientConfig::builder() - .with_root_certificates(root_store) - .with_no_client_auth(); - config - .dangerous() - .set_certificate_verifier(Arc::new(NoVerifier)); - builder = builder.tls_config(Arc::new(config)); - } + #[cfg(feature = "rustls")] + { + builder = builder.tls_config( + TlsConfig::builder() + .provider(TlsProvider::Rustls) + .disable_verification(options.accept_invalid_certs) + .build(), + ); } + let mut maybe_proxy = None; + match (scheme, &options.http_proxy, &options.https_proxy) { (Scheme::Https, _, Some(proxy)) => match Proxy::new(proxy) { Ok(proxy) => { - builder = builder.proxy(proxy); + maybe_proxy = Some(proxy); } Err(err) => { sentry_debug!("invalid proxy: {:?}", err); @@ -135,7 +66,7 @@ impl UreqHttpTransport { }, (_, Some(proxy), _) => match Proxy::new(proxy) { Ok(proxy) => { - builder = builder.proxy(proxy); + maybe_proxy = Some(proxy); } Err(err) => { sentry_debug!("invalid proxy: {:?}", err); @@ -144,7 +75,9 @@ impl UreqHttpTransport { _ => {} } - builder.build() + builder = builder.proxy(maybe_proxy); + + builder.build().new_agent() }); let user_agent = options.user_agent.clone(); let auth = dsn.to_auth(Some(&user_agent)).to_string(); @@ -153,22 +86,23 @@ impl UreqHttpTransport { let thread = TransportThread::new(move |envelope, rl| { let mut body = Vec::new(); envelope.to_writer(&mut body).unwrap(); - let request = agent - .post(&url) - .set("X-Sentry-Auth", &auth) - .send_bytes(&body); + let request = agent.post(&url).header("X-Sentry-Auth", &auth).send(&body); match request { - Ok(response) => { - if let Some(sentry_header) = response.header("x-sentry-rate-limits") { + Ok(mut response) => { + fn header_str<'a, B>(response: &'a Response, key: &str) -> Option<&'a str> { + response.headers().get(key)?.to_str().ok() + } + + if let Some(sentry_header) = header_str(&response, "x-sentry-rate-limits") { rl.update_from_sentry_header(sentry_header); - } else if let Some(retry_after) = response.header("retry-after") { + } else if let Some(retry_after) = header_str(&response, "retry-after") { rl.update_from_retry_after(retry_after); } else if response.status() == 429 { rl.update_from_429(); } - match response.into_string() { + match response.body_mut().read_to_string() { Err(err) => { sentry_debug!("Failed to read sentry response: {}", err); } From c42ed3fe340b68803b1e62bd49036558b36abe48 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Mon, 16 Jun 2025 15:20:17 +0200 Subject: [PATCH 103/148] refactor(tracing): refactor internal code and improve docs (#839) --- CHANGELOG.md | 6 +++ sentry-tracing/Cargo.toml | 2 +- sentry-tracing/src/converters.rs | 93 ++++++++++++++++++-------------- sentry-tracing/src/layer.rs | 2 +- sentry-tracing/src/lib.rs | 50 +++++++++++------ sentry/tests/test_tracing.rs | 13 +++++ 6 files changed, 107 insertions(+), 59 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2efa89a02..bf58d23ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ - fix(logs): send environment in `sentry.environment` default attribute (#837) by @lcian +### Behavioral changes + +- refactor(tracing): refactor internal code and improve docs (#839) by @lcian + - Errors carried by breadcrumbs will now be stored in the breadcrumb `data` under their original field name. + - Before, they were all stored under a single key called `errors`. + ### Dependencies - chore(deps): upgrade `ureq` to 3.x (#835) by @algesten diff --git a/sentry-tracing/Cargo.toml b/sentry-tracing/Cargo.toml index e9c9b348e..7327c27c1 100644 --- a/sentry-tracing/Cargo.toml +++ b/sentry-tracing/Cargo.toml @@ -31,7 +31,7 @@ sentry-backtrace = { version = "0.39.0", path = "../sentry-backtrace", optional [dev-dependencies] log = "0.4" -sentry = { path = "../sentry", default-features = false, features = ["test"] } +sentry = { path = "../sentry", default-features = false, features = ["test", "tracing"] } serde_json = "1" tracing = "0.1" tracing-subscriber = { version = "0.3.1", features = ["fmt", "registry"] } diff --git a/sentry-tracing/src/converters.rs b/sentry-tracing/src/converters.rs index 30e831311..e7b96125d 100644 --- a/sentry-tracing/src/converters.rs +++ b/sentry-tracing/src/converters.rs @@ -11,16 +11,17 @@ use tracing_subscriber::registry::LookupSpan; use super::layer::SentrySpanData; use crate::TAGS_PREFIX; -/// Converts a [`tracing_core::Level`] to a Sentry [`Level`] -fn convert_tracing_level(level: &tracing_core::Level) -> Level { - match level { - &tracing_core::Level::TRACE | &tracing_core::Level::DEBUG => Level::Debug, - &tracing_core::Level::INFO => Level::Info, - &tracing_core::Level::WARN => Level::Warning, - &tracing_core::Level::ERROR => Level::Error, +/// Converts a [`tracing_core::Level`] to a Sentry [`Level`]. +fn level_to_sentry_level(level: &tracing_core::Level) -> Level { + match *level { + tracing_core::Level::TRACE | tracing_core::Level::DEBUG => Level::Debug, + tracing_core::Level::INFO => Level::Info, + tracing_core::Level::WARN => Level::Warning, + tracing_core::Level::ERROR => Level::Error, } } +/// Converts a [`tracing_core::Level`] to the corresponding Sentry [`Exception::ty`] entry. #[allow(unused)] fn level_to_exception_type(level: &tracing_core::Level) -> &'static str { match *level { @@ -32,11 +33,16 @@ fn level_to_exception_type(level: &tracing_core::Level) -> &'static str { } } -/// Extracts the message and metadata from an event -/// and also optionally from its spans chain. -fn extract_event_data(event: &tracing_core::Event) -> (Option, FieldVisitor) { +/// Extracts the message and metadata from an event. +fn extract_event_data( + event: &tracing_core::Event, + store_errors_in_values: bool, +) -> (Option, FieldVisitor) { // Find message of the event, if any - let mut visitor = FieldVisitor::default(); + let mut visitor = FieldVisitor { + store_errors_in_values, + ..Default::default() + }; event.record(&mut visitor); let message = visitor .json_values @@ -52,14 +58,16 @@ fn extract_event_data(event: &tracing_core::Event) -> (Option, FieldVisi (message, visitor) } +/// Extracts the message and metadata from an event, including the data in the current span. fn extract_event_data_with_context( event: &tracing_core::Event, ctx: Option>, + store_errors_in_values: bool, ) -> (Option, FieldVisitor) where S: Subscriber + for<'a> LookupSpan<'a>, { - let (message, mut visitor) = extract_event_data(event); + let (message, mut visitor) = extract_event_data(event, store_errors_in_values); // Add the context fields of every parent span. let current_span = ctx.as_ref().and_then(|ctx| { @@ -72,6 +80,7 @@ where for span in span.scope() { let name = span.name(); let ext = span.extensions(); + if let Some(span_data) = ext.get::() { match &span_data.sentry_span { TransactionOrSpan::Span(span) => { @@ -98,11 +107,14 @@ where (message, visitor) } -/// Records all fields of [`tracing_core::Event`] for easy access +/// Records the fields of a [`tracing_core::Event`]. #[derive(Default)] pub(crate) struct FieldVisitor { - pub json_values: BTreeMap, - pub exceptions: Vec, + pub(crate) json_values: BTreeMap, + pub(crate) exceptions: Vec, + /// If `true`, stringify and store errors in `self.json_values` under the original field name + /// else (default), convert to `Exception`s and store in `self.exceptions`. + store_errors_in_values: bool, } impl FieldVisitor { @@ -129,10 +141,20 @@ impl Visit for FieldVisitor { self.record(field, value); } - fn record_error(&mut self, _field: &Field, value: &(dyn Error + 'static)) { + fn record_error(&mut self, field: &Field, value: &(dyn Error + 'static)) { let event = event_from_error(value); - for exception in event.exception { - self.exceptions.push(exception); + if self.store_errors_in_values { + let error_chain = event + .exception + .iter() + .rev() + .filter_map(|x| x.value.as_ref().map(|v| format!("{}: {}", x.ty, *v))) + .collect::>(); + self.record(field, error_chain); + } else { + for exception in event.exception { + self.exceptions.push(exception); + } } } @@ -141,7 +163,7 @@ impl Visit for FieldVisitor { } } -/// Creates a [`Breadcrumb`] from a given [`tracing_core::Event`] +/// Creates a [`Breadcrumb`] from a given [`tracing_core::Event`]. pub fn breadcrumb_from_event<'context, S>( event: &tracing_core::Event, ctx: impl Into>>, @@ -149,33 +171,20 @@ pub fn breadcrumb_from_event<'context, S>( where S: Subscriber + for<'a> LookupSpan<'a>, { - let (message, visitor) = extract_event_data_with_context(event, ctx.into()); - - let FieldVisitor { - exceptions, - mut json_values, - } = visitor; - - let errors = exceptions - .iter() - .rev() - .filter_map(|x| x.value.as_ref().map(|v| format!("{}: {}", x.ty, *v))) - .collect::>(); - if !errors.is_empty() { - json_values.insert("errors".to_owned(), errors.into()); - } + let (message, visitor) = extract_event_data_with_context(event, ctx.into(), true); Breadcrumb { category: Some(event.metadata().target().to_owned()), ty: "log".into(), - level: convert_tracing_level(event.metadata().level()), + level: level_to_sentry_level(event.metadata().level()), message, - data: json_values, + data: visitor.json_values, ..Default::default() } } -fn tags_from_event(fields: &mut BTreeMap) -> BTreeMap { +/// Convert `tracing` fields to the corresponding Sentry tags, removing them from `fields`. +fn extract_and_remove_tags(fields: &mut BTreeMap) -> BTreeMap { let mut tags = BTreeMap::new(); fields.retain(|key, value| { @@ -200,6 +209,7 @@ fn tags_from_event(fields: &mut BTreeMap) -> BTreeMap, @@ -232,7 +242,7 @@ fn contexts_from_event( context } -/// Creates an [`Event`] (possibly carrying an exception) from a given [`tracing_core::Event`] +/// Creates an [`Event`] (possibly carrying exceptions) from a given [`tracing_core::Event`]. pub fn event_from_event<'context, S>( event: &tracing_core::Event, ctx: impl Into>>, @@ -245,10 +255,11 @@ where // information for this. However, it may contain a serialized error which we can parse to emit // an exception record. #[allow(unused_mut)] - let (mut message, visitor) = extract_event_data_with_context(event, ctx.into()); + let (mut message, visitor) = extract_event_data_with_context(event, ctx.into(), false); let FieldVisitor { mut exceptions, mut json_values, + store_errors_in_values: _, } = visitor; // If there are a message, an exception, and we are capturing stack traces, then add the message @@ -289,10 +300,10 @@ where Event { logger: Some(event.metadata().target().to_owned()), - level: convert_tracing_level(event.metadata().level()), + level: level_to_sentry_level(event.metadata().level()), message, exception: exceptions.into(), - tags: tags_from_event(&mut json_values), + tags: extract_and_remove_tags(&mut json_values), contexts: contexts_from_event(event, json_values), ..Default::default() } diff --git a/sentry-tracing/src/layer.rs b/sentry-tracing/src/layer.rs index 0ae51dfab..a6aa6f3e0 100644 --- a/sentry-tracing/src/layer.rs +++ b/sentry-tracing/src/layer.rs @@ -13,7 +13,7 @@ use tracing_subscriber::registry::LookupSpan; use crate::converters::*; use crate::TAGS_PREFIX; -/// The action that Sentry should perform for a [`Metadata`] +/// The action that Sentry should perform for a given [`Event`] #[derive(Debug, Clone, Copy)] pub enum EventFilter { /// Ignore the [`Event`] diff --git a/sentry-tracing/src/lib.rs b/sentry-tracing/src/lib.rs index 4defd941d..c4ae5fe99 100644 --- a/sentry-tracing/src/lib.rs +++ b/sentry-tracing/src/lib.rs @@ -1,10 +1,20 @@ -//! Support for automatic breadcrumb, event, and trace capturing from `tracing` events. -//! -//! The `tracing` crate is supported in three ways. First, events can be captured as breadcrumbs for -//! later. Secondly, error events can be captured as events to Sentry. Finally, spans can be -//! recorded as structured transaction events. By default, events above `Info` are recorded as -//! breadcrumbs, events above `Error` are captured as error events, and spans above `Info` are -//! recorded as transactions. +//! Support for automatic breadcrumb, event, and trace capturing from `tracing` events and spans. +//! +//! The `tracing` crate is supported in three ways: +//! - `tracing` events can be captured as Sentry events. These are grouped and show up in the Sentry +//! [issues](https://docs.sentry.io/product/issues/) page, representing high severity issues to be +//! acted upon. +//! - `tracing` events can be captured as [breadcrumbs](https://docs.sentry.io/product/issues/issue-details/breadcrumbs/). +//! Breadcrumbs create a trail of what happened prior to an event, and are therefore sent only when +//! an event is captured, either manually through e.g. `sentry::capture_message` or through integrations +//! (e.g. the panic integration is enabled (default) and a panic happens). +//! - `tracing` spans can be captured as Sentry spans. These can be used to provide more contextual +//! information for errors, diagnose [performance +//! issues](https://docs.sentry.io/product/insights/overview/), and capture additional attributes to +//! aggregate and compute [metrics](https://docs.sentry.io/product/explore/trace-explorer/). +//! +//! By default, events above `Info` are recorded as breadcrumbs, events above `Error` are captured +//! as error events, and spans above `Info` are recorded as spans. //! //! # Configuration //! @@ -23,21 +33,24 @@ //! // Register the Sentry tracing layer to capture breadcrumbs, events, and spans: //! tracing_subscriber::registry() //! .with(tracing_subscriber::fmt::layer()) -//! .with(sentry_tracing::layer()) +//! .with(sentry::integrations::tracing::layer()) //! .init(); //! ``` //! -//! It is also possible to set an explicit filter, to customize which log events are captured by -//! Sentry: +//! You can customize the behavior of the layer by providing an explicit event filter, to customize which events +//! are captured by Sentry and the data type they are mapped to. +//! Similarly, you can provide a span filter to customize which spans are captured by Sentry. //! //! ``` -//! use sentry_tracing::EventFilter; +//! use sentry::integrations::tracing::EventFilter; //! use tracing_subscriber::prelude::*; //! -//! let sentry_layer = sentry_tracing::layer().event_filter(|md| match md.level() { -//! &tracing::Level::ERROR => EventFilter::Event, -//! _ => EventFilter::Ignore, -//! }); +//! let sentry_layer = sentry::integrations::tracing::layer() +//! .event_filter(|md| match *md.level() { +//! tracing::Level::ERROR => EventFilter::Event, +//! _ => EventFilter::Ignore, +//! }) +//! .span_filter(|md| matches!(*md.level(), tracing::Level::ERROR | tracing::Level::WARN)); //! //! tracing_subscriber::registry() //! .with(tracing_subscriber::fmt::layer()) @@ -45,7 +58,12 @@ //! .init(); //! ``` //! -//! # Logging Messages +//! In addition, a custom event mapper can be provided, to fully customize if and how `tracing` events are converted to Sentry data. +//! +//! Note that if both an event mapper and event filter are set, the mapper takes precedence, thus the +//! filter has no effect. +//! +//! # Capturing breadcrumbs //! //! Tracing events automatically create breadcrumbs that are attached to the current scope in //! Sentry. They show up on errors and transactions captured within this scope as shown in the diff --git a/sentry/tests/test_tracing.rs b/sentry/tests/test_tracing.rs index 49e2dd305..4eef937f2 100644 --- a/sentry/tests/test_tracing.rs +++ b/sentry/tests/test_tracing.rs @@ -28,6 +28,7 @@ fn test_tracing() { let err = "NaN".parse::().unwrap_err(); let err: &dyn std::error::Error = &err; + tracing::warn!(something = err, "Breadcrumb with error"); tracing::error!(err, tagname = "tagvalue"); let _ = fn_errors(); }); @@ -78,6 +79,7 @@ fn test_tracing() { ); let event = events.next().unwrap(); + assert_eq!(event.breadcrumbs.len(), 3); assert!(!event.exception.is_empty()); assert_eq!(event.exception[0].ty, "ParseIntError"); assert_eq!( @@ -100,6 +102,17 @@ fn test_tracing() { _ => panic!("Wrong context type"), } + assert_eq!(event.breadcrumbs[2].level, sentry::Level::Warning); + assert_eq!( + event.breadcrumbs[2].message, + Some("Breadcrumb with error".into()) + ); + assert!(event.breadcrumbs[2].data.contains_key("something")); + assert_eq!( + event.breadcrumbs[2].data.get("something").unwrap(), + &Value::from(vec!("ParseIntError: invalid digit found in string")) + ); + let event = events.next().unwrap(); assert_eq!(event.message, Some("I'm broken!".to_string())); } From 0b251dc3fa5ab477d9b97e8da26321e2067ab9a9 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Mon, 16 Jun 2025 15:28:33 +0200 Subject: [PATCH 104/148] feat(tracing): add support for logs (#840) --- CHANGELOG.md | 15 ++++++ sentry-tracing/Cargo.toml | 1 + sentry-tracing/src/converters.rs | 58 +++++++++++++++++++++- sentry-tracing/src/layer.rs | 10 ++++ sentry-tracing/src/lib.rs | 22 ++++++++- sentry/Cargo.toml | 2 +- sentry/tests/test_tracing.rs | 84 ++++++++++++++++++++++++++++++++ 7 files changed, 189 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf58d23ba..bc204a050 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,21 @@ ## Unreleased +### Features + +- feat(tracing): add support for logs (#840) by @lcian + - To capture `tracing` events as Sentry structured logs, enable the `logs` feature of the `sentry` crate. + - Then, initialize the SDK with `enable_logs: true` in your client options. + - Finally, set up a custom event filter to map events to logs based on criteria such as severity. For example: + ```rust + let sentry_layer = sentry_tracing::layer().event_filter(|md| match *md.level() { + tracing::Level::ERROR => EventFilter::Event, + tracing::Level::TRACE => EventFilter::Ignore, + _ => EventFilter::Log, + }); + ``` + + ### Fixes - fix(logs): send environment in `sentry.environment` default attribute (#837) by @lcian diff --git a/sentry-tracing/Cargo.toml b/sentry-tracing/Cargo.toml index 7327c27c1..b7d9acf12 100644 --- a/sentry-tracing/Cargo.toml +++ b/sentry-tracing/Cargo.toml @@ -18,6 +18,7 @@ all-features = true [features] default = [] backtrace = ["dep:sentry-backtrace"] +logs = ["sentry-core/logs"] [dependencies] sentry-core = { version = "0.39.0", path = "../sentry-core", features = [ diff --git a/sentry-tracing/src/converters.rs b/sentry-tracing/src/converters.rs index e7b96125d..65735f54b 100644 --- a/sentry-tracing/src/converters.rs +++ b/sentry-tracing/src/converters.rs @@ -2,7 +2,11 @@ use std::collections::BTreeMap; use std::error::Error; use sentry_core::protocol::{Event, Exception, Mechanism, Value}; +#[cfg(feature = "logs")] +use sentry_core::protocol::{Log, LogAttribute, LogLevel}; use sentry_core::{event_from_error, Breadcrumb, Level, TransactionOrSpan}; +#[cfg(feature = "logs")] +use std::time::SystemTime; use tracing_core::field::{Field, Visit}; use tracing_core::Subscriber; use tracing_subscriber::layer::Context; @@ -11,7 +15,7 @@ use tracing_subscriber::registry::LookupSpan; use super::layer::SentrySpanData; use crate::TAGS_PREFIX; -/// Converts a [`tracing_core::Level`] to a Sentry [`Level`]. +/// Converts a [`tracing_core::Level`] to a Sentry [`Level`], used for events and breadcrumbs. fn level_to_sentry_level(level: &tracing_core::Level) -> Level { match *level { tracing_core::Level::TRACE | tracing_core::Level::DEBUG => Level::Debug, @@ -21,6 +25,18 @@ fn level_to_sentry_level(level: &tracing_core::Level) -> Level { } } +/// Converts a [`tracing_core::Level`] to a Sentry [`LogLevel`], used for logs. +#[cfg(feature = "logs")] +fn level_to_log_level(level: &tracing_core::Level) -> LogLevel { + match *level { + tracing_core::Level::TRACE => LogLevel::Trace, + tracing_core::Level::DEBUG => LogLevel::Debug, + tracing_core::Level::INFO => LogLevel::Info, + tracing_core::Level::WARN => LogLevel::Warn, + tracing_core::Level::ERROR => LogLevel::Error, + } +} + /// Converts a [`tracing_core::Level`] to the corresponding Sentry [`Exception::ty`] entry. #[allow(unused)] fn level_to_exception_type(level: &tracing_core::Level) -> &'static str { @@ -308,3 +324,43 @@ where ..Default::default() } } + +/// Creates a [`Log`] from a given [`tracing_core::Event`] +#[cfg(feature = "logs")] +pub fn log_from_event<'context, S>( + event: &tracing_core::Event, + ctx: impl Into>>, +) -> Log +where + S: Subscriber + for<'a> LookupSpan<'a>, +{ + let (message, visitor) = extract_event_data_with_context(event, ctx.into(), true); + + let mut attributes: BTreeMap = visitor + .json_values + .into_iter() + .map(|(key, val)| (key, val.into())) + .collect(); + + let event_meta = event.metadata(); + if let Some(module_path) = event_meta.module_path() { + attributes.insert("tracing.module_path".to_owned(), module_path.into()); + } + if let Some(file) = event_meta.file() { + attributes.insert("tracing.file".to_owned(), file.into()); + } + if let Some(line) = event_meta.line() { + attributes.insert("tracing.line".to_owned(), line.into()); + } + + attributes.insert("sentry.origin".to_owned(), "auto.tracing".into()); + + Log { + level: level_to_log_level(event.metadata().level()), + body: message.unwrap_or_default(), + trace_id: None, + timestamp: SystemTime::now(), + severity_number: None, + attributes, + } +} diff --git a/sentry-tracing/src/layer.rs b/sentry-tracing/src/layer.rs index a6aa6f3e0..f9cbf3aa2 100644 --- a/sentry-tracing/src/layer.rs +++ b/sentry-tracing/src/layer.rs @@ -22,6 +22,9 @@ pub enum EventFilter { Breadcrumb, /// Create a [`sentry_core::protocol::Event`] from this [`Event`] Event, + /// Create a [`sentry_core::protocol::Log`] from this [`Event`] + #[cfg(feature = "logs")] + Log, } /// The type of data Sentry should ingest for a [`Event`] @@ -34,6 +37,9 @@ pub enum EventMapping { Breadcrumb(Breadcrumb), /// Captures the [`sentry_core::protocol::Event`] to Sentry. Event(sentry_core::protocol::Event<'static>), + /// Captures the [`sentry_core::protocol::Log`] to Sentry. + #[cfg(feature = "logs")] + Log(sentry_core::protocol::Log), } /// The default event filter. @@ -215,6 +221,8 @@ where EventMapping::Breadcrumb(breadcrumb_from_event(event, span_ctx)) } EventFilter::Event => EventMapping::Event(event_from_event(event, span_ctx)), + #[cfg(feature = "logs")] + EventFilter::Log => EventMapping::Log(log_from_event(event, span_ctx)), } } }; @@ -224,6 +232,8 @@ where sentry_core::capture_event(event); } EventMapping::Breadcrumb(breadcrumb) => sentry_core::add_breadcrumb(breadcrumb), + #[cfg(feature = "logs")] + EventMapping::Log(log) => sentry_core::Hub::with_active(|hub| hub.capture_log(log)), _ => (), } } diff --git a/sentry-tracing/src/lib.rs b/sentry-tracing/src/lib.rs index c4ae5fe99..97115ba0a 100644 --- a/sentry-tracing/src/lib.rs +++ b/sentry-tracing/src/lib.rs @@ -1,6 +1,6 @@ //! Support for automatic breadcrumb, event, and trace capturing from `tracing` events and spans. //! -//! The `tracing` crate is supported in three ways: +//! The `tracing` crate is supported in four ways: //! - `tracing` events can be captured as Sentry events. These are grouped and show up in the Sentry //! [issues](https://docs.sentry.io/product/issues/) page, representing high severity issues to be //! acted upon. @@ -8,6 +8,9 @@ //! Breadcrumbs create a trail of what happened prior to an event, and are therefore sent only when //! an event is captured, either manually through e.g. `sentry::capture_message` or through integrations //! (e.g. the panic integration is enabled (default) and a panic happens). +//! - `tracing` events can be captured as traditional [structured logs](https://docs.sentry.io/product/explore/logs/). +//! The `tracing` fields are captured as attributes on the logs, which can be queried in the Logs +//! explorer. (Available on crate feature `logs`) //! - `tracing` spans can be captured as Sentry spans. These can be used to provide more contextual //! information for errors, diagnose [performance //! issues](https://docs.sentry.io/product/insights/overview/), and capture additional attributes to @@ -79,6 +82,23 @@ //! } //! ``` //! +//! # Capturing logs +//! +//! Tracing events can be captured as traditional structured logs in Sentry. +//! This is gated by the `logs` feature flag and requires setting up a custom Event filter/mapper +//! to capture logs. +//! +//! ``` +//! // assuming `tracing::Level::INFO => EventFilter::Log` in your `event_filter` +//! for i in 0..10 { +//! tracing::info!(number = i, my.key = "val", my.num = 42, "This is a log"); +//! } +//! ``` +//! +//! The fields of a `tracing` event are captured as attributes of the log. +//! Logs can be viewed and queried in the Logs explorer based on message and attributes. +//! Fields containing dots will be displayed as nested under their common prefix in the UI. +//! //! # Tracking Errors //! //! The easiest way to emit errors is by logging an event with `ERROR` level. This will create a diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index 72e234d62..d6aa7663b 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -48,7 +48,7 @@ opentelemetry = ["sentry-opentelemetry"] # other features test = ["sentry-core/test"] release-health = ["sentry-core/release-health", "sentry-actix?/release-health"] -logs = ["sentry-core/logs"] +logs = ["sentry-core/logs", "sentry-tracing?/logs"] # transports transport = ["reqwest", "native-tls"] reqwest = ["dep:reqwest", "httpdate", "tokio"] diff --git a/sentry/tests/test_tracing.rs b/sentry/tests/test_tracing.rs index 4eef937f2..6ec51317d 100644 --- a/sentry/tests/test_tracing.rs +++ b/sentry/tests/test_tracing.rs @@ -193,3 +193,87 @@ fn test_set_transaction() { assert_eq!(transaction.name.as_deref().unwrap(), "new name"); assert!(transaction.request.is_some()); } + +#[cfg(feature = "logs")] +#[test] +fn test_tracing_logs() { + let sentry_layer = sentry_tracing::layer().event_filter(|_| sentry_tracing::EventFilter::Log); + + let _dispatcher = tracing_subscriber::registry() + .with(sentry_layer) + .set_default(); + + let options = sentry::ClientOptions { + enable_logs: true, + ..Default::default() + }; + + let envelopes = sentry::test::with_captured_envelopes_options( + || { + #[derive(Debug)] + struct ConnectionError { + message: String, + source: Option, + } + + impl std::fmt::Display for ConnectionError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.message) + } + } + + impl std::error::Error for ConnectionError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + self.source + .as_ref() + .map(|e| e as &(dyn std::error::Error + 'static)) + } + } + + let io_error = + std::io::Error::new(std::io::ErrorKind::ConnectionRefused, "Connection refused"); + let connection_error = ConnectionError { + message: "Failed to connect to database server".to_string(), + source: Some(io_error), + }; + + tracing::error!( + my.key = "hello", + an.error = &connection_error as &dyn std::error::Error, + "This is an error log: {}", + "hello" + ); + }, + options, + ); + + assert_eq!(envelopes.len(), 1); + let envelope = envelopes.first().expect("expected envelope"); + let item = envelope.items().next().expect("expected envelope item"); + + match item { + sentry::protocol::EnvelopeItem::ItemContainer(container) => match container { + sentry::protocol::ItemContainer::Logs(logs) => { + assert_eq!(logs.len(), 1); + + let log = &logs[0]; + assert_eq!(log.level, sentry::protocol::LogLevel::Error); + assert_eq!(log.body, "This is an error log: hello"); + assert!(log.trace_id.is_some()); + assert_eq!( + log.attributes.get("my.key").unwrap().clone(), + sentry::protocol::LogAttribute::from("hello") + ); + assert_eq!( + log.attributes.get("an.error").unwrap().clone(), + sentry::protocol::LogAttribute::from(vec![ + "ConnectionError: Failed to connect to database server", + "Custom: Connection refused" + ]) + ); + } + _ => panic!("expected logs container"), + }, + _ => panic!("expected item container"), + } +} From 88b00f35d527b5ff88dfab3d525e4e5a9e1a2cfd Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Mon, 16 Jun 2025 15:37:46 +0200 Subject: [PATCH 105/148] refactor(logs): apply user attributes to log regardless of `send_default_pii` (#843) --- CHANGELOG.md | 6 +++++- sentry-core/src/client.rs | 2 +- sentry-core/src/scope/real.rs | 38 +++++++++++++++++------------------ 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc204a050..c5ae2e96c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +### Breaking changes + +- refactor(logs): apply user attributes to log regardless of `send_default_pii` (#843) by @lcian + - User attributes should be applied to logs regardless of `send_default_pii`. Therefore, that parameter was removed from `sentry_core::Scope::apply_to_log`. + ### Features - feat(tracing): add support for logs (#840) by @lcian @@ -16,7 +21,6 @@ }); ``` - ### Fixes - fix(logs): send environment in `sentry.environment` default attribute (#837) by @lcian diff --git a/sentry-core/src/client.rs b/sentry-core/src/client.rs index 487f87cd0..5b0195be9 100644 --- a/sentry-core/src/client.rs +++ b/sentry-core/src/client.rs @@ -411,7 +411,7 @@ impl Client { /// processing it through `before_send_log`. #[cfg(feature = "logs")] fn prepare_log(&self, mut log: Log, scope: &Scope) -> Option { - scope.apply_to_log(&mut log, self.options.send_default_pii); + scope.apply_to_log(&mut log); self.set_log_default_attributes(&mut log); diff --git a/sentry-core/src/scope/real.rs b/sentry-core/src/scope/real.rs index f4972cf19..6bb2662f9 100644 --- a/sentry-core/src/scope/real.rs +++ b/sentry-core/src/scope/real.rs @@ -351,7 +351,7 @@ impl Scope { /// Applies the contained scoped data to a log, setting the `trace_id` and certain default /// attributes. #[cfg(feature = "logs")] - pub fn apply_to_log(&self, log: &mut Log, send_default_pii: bool) { + pub fn apply_to_log(&self, log: &mut Log) { if let Some(span) = self.span.as_ref() { log.trace_id = Some(span.get_trace_context().trace_id); } else { @@ -373,29 +373,27 @@ impl Scope { } } - if send_default_pii { - if let Some(user) = self.user.as_ref() { - if !log.attributes.contains_key("user.id") { - if let Some(id) = user.id.as_ref() { - log.attributes - .insert("user.id".to_owned(), LogAttribute(id.to_owned().into())); - } + if let Some(user) = self.user.as_ref() { + if !log.attributes.contains_key("user.id") { + if let Some(id) = user.id.as_ref() { + log.attributes + .insert("user.id".to_owned(), LogAttribute(id.to_owned().into())); } + } - if !log.attributes.contains_key("user.name") { - if let Some(name) = user.username.as_ref() { - log.attributes - .insert("user.name".to_owned(), LogAttribute(name.to_owned().into())); - } + if !log.attributes.contains_key("user.name") { + if let Some(name) = user.username.as_ref() { + log.attributes + .insert("user.name".to_owned(), LogAttribute(name.to_owned().into())); } + } - if !log.attributes.contains_key("user.email") { - if let Some(email) = user.email.as_ref() { - log.attributes.insert( - "user.email".to_owned(), - LogAttribute(email.to_owned().into()), - ); - } + if !log.attributes.contains_key("user.email") { + if let Some(email) = user.email.as_ref() { + log.attributes.insert( + "user.email".to_owned(), + LogAttribute(email.to_owned().into()), + ); } } } From 34db51db4bd7290a392334a605fdebbe4a8c834b Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Mon, 16 Jun 2025 15:52:15 +0200 Subject: [PATCH 106/148] feat(log): add support for logs (#841) --- CHANGELOG.md | 11 ++++++++ Cargo.lock | 14 ++++----- sentry-log/Cargo.toml | 4 +++ sentry-log/src/converters.rs | 48 ++++++++++++++++++++++++++++++- sentry-log/src/lib.rs | 24 ++++++++++++---- sentry-log/src/logger.rs | 12 ++++++++ sentry/Cargo.toml | 2 +- sentry/tests/test_log_logs.rs | 53 +++++++++++++++++++++++++++++++++++ 8 files changed, 154 insertions(+), 14 deletions(-) create mode 100644 sentry/tests/test_log_logs.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index c5ae2e96c..f4924ca6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,17 @@ _ => EventFilter::Log, }); ``` +- feat(log): add support for logs (#841) by @lcian + - To capture `log` records as Sentry structured logs, enable the `logs` feature of the `sentry` crate. + - Then, initialize the SDK with `enable_logs: true` in your client options. + - Finally, set up a custom event filter to map records to Sentry logs based on criteria such as severity. For example: + ```rust + let logger = sentry::integrations::log::SentryLogger::new().filter(|md| match md.level() { + log::Level::Error => LogFilter::Event, + log::Level::Trace => LogFilter::Ignore, + _ => LogFilter::Log, + }); + ``` ### Fixes diff --git a/Cargo.lock b/Cargo.lock index d011b9442..7417360e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1244,7 +1244,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2062,7 +2062,7 @@ checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2748,7 +2748,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3032,7 +3032,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3045,7 +3045,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.9.4", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3582,7 +3582,7 @@ dependencies = [ "getrandom 0.3.2", "once_cell", "rustix 1.0.5", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4265,7 +4265,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] diff --git a/sentry-log/Cargo.toml b/sentry-log/Cargo.toml index 10de5a4ee..cb36c59e8 100644 --- a/sentry-log/Cargo.toml +++ b/sentry-log/Cargo.toml @@ -12,6 +12,10 @@ Sentry integration for log and env_logger crates. edition = "2021" rust-version = "1.81" +[features] +default = [] +logs = ["sentry-core/logs"] + [dependencies] sentry-core = { version = "0.39.0", path = "../sentry-core" } log = { version = "0.4.8", features = ["std"] } diff --git a/sentry-log/src/converters.rs b/sentry-log/src/converters.rs index df4d13a1f..baf7d4640 100644 --- a/sentry-log/src/converters.rs +++ b/sentry-log/src/converters.rs @@ -1,7 +1,11 @@ use sentry_core::protocol::Event; +#[cfg(feature = "logs")] +use sentry_core::protocol::{Log, LogAttribute, LogLevel}; use sentry_core::{Breadcrumb, Level}; +#[cfg(feature = "logs")] +use std::{collections::BTreeMap, time::SystemTime}; -/// Converts a [`log::Level`] to a Sentry [`Level`] +/// Converts a [`log::Level`] to a Sentry [`Level`], used for [`Event`] and [`Breadcrumb`]. pub fn convert_log_level(level: log::Level) -> Level { match level { log::Level::Error => Level::Error, @@ -11,6 +15,18 @@ pub fn convert_log_level(level: log::Level) -> Level { } } +/// Converts a [`log::Level`] to a Sentry [`LogLevel`], used for [`Log`]. +#[cfg(feature = "logs")] +pub fn convert_log_level_to_sentry_log_level(level: log::Level) -> LogLevel { + match level { + log::Level::Error => LogLevel::Error, + log::Level::Warn => LogLevel::Warn, + log::Level::Info => LogLevel::Info, + log::Level::Debug => LogLevel::Debug, + log::Level::Trace => LogLevel::Trace, + } +} + /// Creates a [`Breadcrumb`] from a given [`log::Record`]. pub fn breadcrumb_from_record(record: &log::Record<'_>) -> Breadcrumb { Breadcrumb { @@ -40,3 +56,33 @@ pub fn exception_from_record(record: &log::Record<'_>) -> Event<'static> { // an exception record. event_from_record(record) } + +/// Creates a [`Log`] from a given [`log::Record`]. +#[cfg(feature = "logs")] +pub fn log_from_record(record: &log::Record<'_>) -> Log { + let mut attributes: BTreeMap = BTreeMap::new(); + + attributes.insert("logger.target".into(), record.target().into()); + if let Some(module_path) = record.module_path() { + attributes.insert("logger.module_path".into(), module_path.into()); + } + if let Some(file) = record.file() { + attributes.insert("logger.file".into(), file.into()); + } + if let Some(line) = record.line() { + attributes.insert("logger.line".into(), line.into()); + } + + attributes.insert("sentry.origin".into(), "auto.logger.log".into()); + + // TODO: support the `kv` feature and store key value pairs as attributes + + Log { + level: convert_log_level_to_sentry_log_level(record.level()), + body: format!("{}", record.args()), + trace_id: None, + timestamp: SystemTime::now(), + severity_number: None, + attributes, + } +} diff --git a/sentry-log/src/lib.rs b/sentry-log/src/lib.rs index bbf667767..56d986539 100644 --- a/sentry-log/src/lib.rs +++ b/sentry-log/src/lib.rs @@ -1,10 +1,24 @@ -//! Adds support for automatic Breadcrumb and Event capturing from logs. -//! -//! The `log` crate is supported in two ways. First, logs can be captured as -//! breadcrumbs for later. Secondly, error logs can be captured as events to -//! Sentry. By default anything above `Info` is recorded as a breadcrumb and +//! Adds support for automatic Breadcrumb, Event, and Log capturing from `log` records. +//! +//! The `log` crate is supported in three ways: +//! - Records can be captured as Sentry events. These are grouped and show up in the Sentry +//! [issues](https://docs.sentry.io/product/issues/) page, representing high severity issues to be +//! acted upon. +//! - Records can be captured as [breadcrumbs](https://docs.sentry.io/product/issues/issue-details/breadcrumbs/). +//! Breadcrumbs create a trail of what happened prior to an event, and are therefore sent only when +//! an event is captured, either manually through e.g. `sentry::capture_message` or through integrations +//! (e.g. the panic integration is enabled (default) and a panic happens). +//! - Records can be captured as traditional [logs](https://docs.sentry.io/product/explore/logs/) +//! Logs can be viewed and queried in the Logs explorer. +//! +//! By default anything above `Info` is recorded as a breadcrumb and //! anything above `Error` is captured as error event. //! +//! To capture records as Sentry logs: +//! 1. Enable the `logs` feature of the `sentry` crate. +//! 2. Initialize the SDK with `enable_logs: true` in your client options. +//! 3. Set up a custom filter (see below) to map records to logs (`LogFilter::Log`) based on criteria such as severity. +//! //! # Examples //! //! ``` diff --git a/sentry-log/src/logger.rs b/sentry-log/src/logger.rs index f0f1e9ab9..7308afa95 100644 --- a/sentry-log/src/logger.rs +++ b/sentry-log/src/logger.rs @@ -1,6 +1,8 @@ use log::Record; use sentry_core::protocol::{Breadcrumb, Event}; +#[cfg(feature = "logs")] +use crate::converters::log_from_record; use crate::converters::{breadcrumb_from_record, event_from_record, exception_from_record}; /// The action that Sentry should perform for a [`log::Metadata`]. @@ -14,6 +16,9 @@ pub enum LogFilter { Event, /// Create an exception [`Event`] from this [`Record`]. Exception, + /// Create a [`sentry_core::protocol::Log`] from this [`Record`]. + #[cfg(feature = "logs")] + Log, } /// The type of Data Sentry should ingest for a [`log::Record`]. @@ -26,6 +31,9 @@ pub enum RecordMapping { Breadcrumb(Breadcrumb), /// Captures the [`Event`] to Sentry. Event(Event<'static>), + /// Captures the [`sentry_core::protocol::Log`] to Sentry. + #[cfg(feature = "logs")] + Log(sentry_core::protocol::Log), } /// The default log filter. @@ -135,6 +143,8 @@ impl log::Log for SentryLogger { LogFilter::Breadcrumb => RecordMapping::Breadcrumb(breadcrumb_from_record(record)), LogFilter::Event => RecordMapping::Event(event_from_record(record)), LogFilter::Exception => RecordMapping::Event(exception_from_record(record)), + #[cfg(feature = "logs")] + LogFilter::Log => RecordMapping::Log(log_from_record(record)), }, }; @@ -144,6 +154,8 @@ impl log::Log for SentryLogger { RecordMapping::Event(e) => { sentry_core::capture_event(e); } + #[cfg(feature = "logs")] + RecordMapping::Log(log) => sentry_core::Hub::with_active(|hub| hub.capture_log(log)), } self.dest.log(record) diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index d6aa7663b..011e312e5 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -48,7 +48,7 @@ opentelemetry = ["sentry-opentelemetry"] # other features test = ["sentry-core/test"] release-health = ["sentry-core/release-health", "sentry-actix?/release-health"] -logs = ["sentry-core/logs", "sentry-tracing?/logs"] +logs = ["sentry-core/logs", "sentry-tracing?/logs", "sentry-log?/logs"] # transports transport = ["reqwest", "native-tls"] reqwest = ["dep:reqwest", "httpdate", "tokio"] diff --git a/sentry/tests/test_log_logs.rs b/sentry/tests/test_log_logs.rs new file mode 100644 index 000000000..adaa2993a --- /dev/null +++ b/sentry/tests/test_log_logs.rs @@ -0,0 +1,53 @@ +#![cfg(feature = "test")] + +// Test `log` integration <> Sentry structured logging. +// This must be a in a separate file because `log::set_boxed_logger` can only be called once. +#[cfg(feature = "logs")] +#[test] +fn test_log_logs() { + let logger = sentry_log::SentryLogger::new().filter(|_| sentry_log::LogFilter::Log); + + log::set_boxed_logger(Box::new(logger)) + .map(|()| log::set_max_level(log::LevelFilter::Trace)) + .unwrap(); + + let options = sentry::ClientOptions { + enable_logs: true, + ..Default::default() + }; + + let envelopes = sentry::test::with_captured_envelopes_options( + || { + log::info!("This is a log"); + }, + options, + ); + + assert_eq!(envelopes.len(), 1); + let envelope = envelopes.first().expect("expected envelope"); + let item = envelope.items().next().expect("expected envelope item"); + + match item { + sentry::protocol::EnvelopeItem::ItemContainer(container) => match container { + sentry::protocol::ItemContainer::Logs(logs) => { + assert_eq!(logs.len(), 1); + + let info_log = logs + .iter() + .find(|log| log.level == sentry::protocol::LogLevel::Info) + .expect("expected info log"); + assert_eq!(info_log.body, "This is a log"); + assert_eq!( + info_log.attributes.get("logger.target").unwrap().clone(), + "test_log_logs".into() + ); + assert_eq!( + info_log.attributes.get("sentry.origin").unwrap().clone(), + "auto.logger.log".into() + ); + } + _ => panic!("expected logs"), + }, + _ => panic!("expected item container"), + } +} From 4553e2eea77f32e4d88328e312b56be563648248 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Mon, 16 Jun 2025 16:06:47 +0200 Subject: [PATCH 107/148] refactor(logs): cache default attributes and add OS attributes (#842) --- CHANGELOG.md | 2 + sentry-core/src/client.rs | 121 +++++++++++++++++++++++--------------- 2 files changed, 75 insertions(+), 48 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f4924ca6e..31eb6b551 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,8 @@ _ => LogFilter::Log, }); ``` +- refactor(logs): cache default attributes and add OS attributes (#842) by @lcian + - `os.name` and `os.version` are now being attached to logs as default attributes. ### Fixes diff --git a/sentry-core/src/client.rs b/sentry-core/src/client.rs index 5b0195be9..92262ba5e 100644 --- a/sentry-core/src/client.rs +++ b/sentry-core/src/client.rs @@ -1,5 +1,7 @@ use std::any::TypeId; use std::borrow::Cow; +#[cfg(feature = "logs")] +use std::collections::BTreeMap; use std::fmt; use std::panic::RefUnwindSafe; use std::sync::{Arc, RwLock}; @@ -21,6 +23,8 @@ use crate::types::{Dsn, Uuid}; use crate::SessionMode; use crate::{ClientOptions, Envelope, Hub, Integration, Scope, Transport}; #[cfg(feature = "logs")] +use sentry_types::protocol::v7::Context; +#[cfg(feature = "logs")] use sentry_types::protocol::v7::{Log, LogAttribute}; impl> From for Client { @@ -55,6 +59,8 @@ pub struct Client { session_flusher: RwLock>, #[cfg(feature = "logs")] logs_batcher: RwLock>, + #[cfg(feature = "logs")] + default_log_attributes: Option>, integrations: Vec<(TypeId, Arc)>, pub(crate) sdk_info: ClientSdkInfo, } @@ -92,6 +98,8 @@ impl Clone for Client { session_flusher, #[cfg(feature = "logs")] logs_batcher, + #[cfg(feature = "logs")] + default_log_attributes: self.default_log_attributes.clone(), integrations: self.integrations.clone(), sdk_info: self.sdk_info.clone(), } @@ -168,16 +176,75 @@ impl Client { None }); - Client { + #[allow(unused_mut)] + let mut client = Client { options, transport, #[cfg(feature = "release-health")] session_flusher, #[cfg(feature = "logs")] logs_batcher, + #[cfg(feature = "logs")] + default_log_attributes: None, integrations, sdk_info, + }; + + #[cfg(feature = "logs")] + client.cache_default_log_attributes(); + + client + } + + #[cfg(feature = "logs")] + fn cache_default_log_attributes(&mut self) { + let mut attributes = BTreeMap::new(); + + if let Some(environment) = self.options.environment.as_ref() { + attributes.insert("sentry.environment".to_owned(), environment.clone().into()); + } + + if let Some(release) = self.options.release.as_ref() { + attributes.insert("sentry.release".to_owned(), release.clone().into()); } + + attributes.insert( + "sentry.sdk.name".to_owned(), + self.sdk_info.name.to_owned().into(), + ); + + attributes.insert( + "sentry.sdk.version".to_owned(), + self.sdk_info.version.to_owned().into(), + ); + + // Process a fake event through integrations, so that `ContextIntegration` (if available) + // provides the OS Context. + // This is needed as that integration adds the OS Context to events using an event + // processor, which logs don't go through. + // We cannot get the `ContextIntegration` directly, as its type lives in `sentry-contexts`, + // which `sentry-core` doesn't depend on. + let mut fake_event = Event::default(); + for (_, integration) in self.integrations.iter() { + if let Some(res) = integration.process_event(fake_event.clone(), &self.options) { + fake_event = res; + } + } + + if let Some(Context::Os(os)) = fake_event.contexts.get("os") { + if let Some(name) = os.name.as_ref() { + attributes.insert("os.name".to_owned(), name.to_owned().into()); + } + if let Some(version) = os.version.as_ref() { + attributes.insert("os.version".to_owned(), version.to_owned().into()); + } + } + + if let Some(server) = &self.options.server_name { + attributes.insert("server.address".to_owned(), server.clone().into()); + } + + self.default_log_attributes = Some(attributes); } pub(crate) fn get_integration(&self) -> Option<&I> @@ -413,7 +480,11 @@ impl Client { fn prepare_log(&self, mut log: Log, scope: &Scope) -> Option { scope.apply_to_log(&mut log); - self.set_log_default_attributes(&mut log); + if let Some(default_attributes) = self.default_log_attributes.as_ref() { + for (key, val) in default_attributes.iter() { + log.attributes.entry(key.to_owned()).or_insert(val.clone()); + } + } if let Some(ref func) = self.options.before_send_log { log = func(log)?; @@ -421,52 +492,6 @@ impl Client { Some(log) } - - #[cfg(feature = "logs")] - fn set_log_default_attributes(&self, log: &mut Log) { - if !log.attributes.contains_key("sentry.environment") { - if let Some(environment) = self.options.environment.as_ref() { - log.attributes.insert( - "sentry.environment".to_owned(), - LogAttribute(environment.clone().into()), - ); - } - } - - if !log.attributes.contains_key("sentry.release") { - if let Some(release) = self.options.release.as_ref() { - log.attributes.insert( - "sentry.release".to_owned(), - LogAttribute(release.clone().into()), - ); - } - } - - if !log.attributes.contains_key("sentry.sdk.name") { - log.attributes.insert( - "sentry.sdk.name".to_owned(), - LogAttribute(self.sdk_info.name.to_owned().into()), - ); - } - - if !log.attributes.contains_key("sentry.sdk.version") { - log.attributes.insert( - "sentry.sdk.version".to_owned(), - LogAttribute(self.sdk_info.version.to_owned().into()), - ); - } - - // TODO: set OS (and Rust?) context - - if !log.attributes.contains_key("server.address") { - if let Some(server) = &self.options.server_name { - log.attributes.insert( - "server.address".to_owned(), - LogAttribute(server.clone().into()), - ); - } - } - } } // Make this unwind safe. It's not out of the box because of the From 25be1a57b2a3b27db90305a8c0e7a1ee8d09c75f Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Tue, 17 Jun 2025 08:41:20 +0000 Subject: [PATCH 108/148] release: 0.40.0 --- CHANGELOG.md | 2 +- Cargo.lock | 28 ++++++------- sentry-actix/Cargo.toml | 4 +- sentry-anyhow/Cargo.toml | 6 +-- sentry-backtrace/Cargo.toml | 4 +- sentry-contexts/Cargo.toml | 4 +- sentry-core/Cargo.toml | 4 +- sentry-core/README.md | 2 +- sentry-debug-images/Cargo.toml | 4 +- sentry-debug-images/README.md | 2 +- sentry-log/Cargo.toml | 4 +- sentry-log/README.md | 24 ++++++++--- sentry-opentelemetry/Cargo.toml | 4 +- sentry-panic/Cargo.toml | 6 +-- sentry-slog/Cargo.toml | 4 +- sentry-tower/Cargo.toml | 4 +- sentry-tower/README.md | 2 +- sentry-tracing/Cargo.toml | 6 +-- sentry-tracing/README.md | 72 +++++++++++++++++++++++++-------- sentry-types/Cargo.toml | 2 +- sentry/Cargo.toml | 26 ++++++------ sentry/README.md | 12 +++--- 22 files changed, 139 insertions(+), 87 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 31eb6b551..fa5db80b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 0.40.0 ### Breaking changes diff --git a/Cargo.lock b/Cargo.lock index 7417360e2..322210583 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3162,7 +3162,7 @@ dependencies = [ [[package]] name = "sentry" -version = "0.39.0" +version = "0.40.0" dependencies = [ "actix-web", "anyhow", @@ -3198,7 +3198,7 @@ dependencies = [ [[package]] name = "sentry-actix" -version = "0.39.0" +version = "0.40.0" dependencies = [ "actix-http", "actix-web", @@ -3212,7 +3212,7 @@ dependencies = [ [[package]] name = "sentry-anyhow" -version = "0.39.0" +version = "0.40.0" dependencies = [ "anyhow", "sentry", @@ -3222,7 +3222,7 @@ dependencies = [ [[package]] name = "sentry-backtrace" -version = "0.39.0" +version = "0.40.0" dependencies = [ "backtrace", "regex", @@ -3231,7 +3231,7 @@ dependencies = [ [[package]] name = "sentry-contexts" -version = "0.39.0" +version = "0.40.0" dependencies = [ "hostname", "libc", @@ -3244,7 +3244,7 @@ dependencies = [ [[package]] name = "sentry-core" -version = "0.39.0" +version = "0.40.0" dependencies = [ "anyhow", "criterion", @@ -3263,7 +3263,7 @@ dependencies = [ [[package]] name = "sentry-debug-images" -version = "0.39.0" +version = "0.40.0" dependencies = [ "findshlibs", "sentry-core", @@ -3271,7 +3271,7 @@ dependencies = [ [[package]] name = "sentry-log" -version = "0.39.0" +version = "0.40.0" dependencies = [ "log", "pretty_env_logger", @@ -3281,7 +3281,7 @@ dependencies = [ [[package]] name = "sentry-opentelemetry" -version = "0.39.0" +version = "0.40.0" dependencies = [ "opentelemetry", "opentelemetry_sdk", @@ -3291,7 +3291,7 @@ dependencies = [ [[package]] name = "sentry-panic" -version = "0.39.0" +version = "0.40.0" dependencies = [ "sentry", "sentry-backtrace", @@ -3300,7 +3300,7 @@ dependencies = [ [[package]] name = "sentry-slog" -version = "0.39.0" +version = "0.40.0" dependencies = [ "erased-serde", "sentry", @@ -3312,7 +3312,7 @@ dependencies = [ [[package]] name = "sentry-tower" -version = "0.39.0" +version = "0.40.0" dependencies = [ "anyhow", "axum 0.8.3", @@ -3332,7 +3332,7 @@ dependencies = [ [[package]] name = "sentry-tracing" -version = "0.39.0" +version = "0.40.0" dependencies = [ "log", "sentry", @@ -3347,7 +3347,7 @@ dependencies = [ [[package]] name = "sentry-types" -version = "0.39.0" +version = "0.40.0" dependencies = [ "debugid", "hex", diff --git a/sentry-actix/Cargo.toml b/sentry-actix/Cargo.toml index 132f4be64..bd4700123 100644 --- a/sentry-actix/Cargo.toml +++ b/sentry-actix/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-actix" -version = "0.39.0" +version = "0.40.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -20,7 +20,7 @@ release-health = ["sentry-core/release-health"] actix-web = { version = "4", default-features = false } bytes = "1.2" futures-util = { version = "0.3.5", default-features = false } -sentry-core = { version = "0.39.0", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.40.0", path = "../sentry-core", default-features = false, features = [ "client", ] } actix-http = "3.10" diff --git a/sentry-anyhow/Cargo.toml b/sentry-anyhow/Cargo.toml index 902d37d49..a790a0655 100644 --- a/sentry-anyhow/Cargo.toml +++ b/sentry-anyhow/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-anyhow" -version = "0.39.0" +version = "0.40.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -17,8 +17,8 @@ default = ["backtrace"] backtrace = ["anyhow/backtrace"] [dependencies] -sentry-backtrace = { version = "0.39.0", path = "../sentry-backtrace" } -sentry-core = { version = "0.39.0", path = "../sentry-core" } +sentry-backtrace = { version = "0.40.0", path = "../sentry-backtrace" } +sentry-core = { version = "0.40.0", path = "../sentry-core" } anyhow = "1.0.39" [dev-dependencies] diff --git a/sentry-backtrace/Cargo.toml b/sentry-backtrace/Cargo.toml index 2813a8141..37c038a7b 100644 --- a/sentry-backtrace/Cargo.toml +++ b/sentry-backtrace/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-backtrace" -version = "0.39.0" +version = "0.40.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -18,4 +18,4 @@ regex = { version = "1.5.5", default-features = false, features = [ "std", "unicode-perl", ] } -sentry-core = { version = "0.39.0", path = "../sentry-core" } +sentry-core = { version = "0.40.0", path = "../sentry-core" } diff --git a/sentry-contexts/Cargo.toml b/sentry-contexts/Cargo.toml index 9a965b51a..16840b96c 100644 --- a/sentry-contexts/Cargo.toml +++ b/sentry-contexts/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-contexts" -version = "0.39.0" +version = "0.40.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -14,7 +14,7 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.39.0", path = "../sentry-core" } +sentry-core = { version = "0.40.0", path = "../sentry-core" } libc = "0.2.66" hostname = "0.4" diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index 1aa95fb42..773b58e77 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-core" -version = "0.39.0" +version = "0.40.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -29,7 +29,7 @@ logs = [] [dependencies] log = { version = "0.4.8", optional = true, features = ["std"] } rand = { version = "0.9.0", optional = true } -sentry-types = { version = "0.39.0", path = "../sentry-types" } +sentry-types = { version = "0.40.0", path = "../sentry-types" } serde = { version = "1.0.104", features = ["derive"] } serde_json = { version = "1.0.46" } uuid = { version = "1.0.0", features = ["v4", "serde"], optional = true } diff --git a/sentry-core/README.md b/sentry-core/README.md index 844b9e92b..8965eed0d 100644 --- a/sentry-core/README.md +++ b/sentry-core/README.md @@ -99,7 +99,7 @@ functionality. [Sentry]: https://sentry.io/ [`sentry`]: https://crates.io/crates/sentry [Unified API]: https://develop.sentry.dev/sdk/unified-api/ -[`test`]: https://docs.rs/sentry-core/0.39.0/sentry_core/test/index.html +[`test`]: https://docs.rs/sentry-core/0.40.0/sentry_core/test/index.html ## Resources diff --git a/sentry-debug-images/Cargo.toml b/sentry-debug-images/Cargo.toml index b5ece5011..582b8f6df 100644 --- a/sentry-debug-images/Cargo.toml +++ b/sentry-debug-images/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-debug-images" -version = "0.39.0" +version = "0.40.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -14,4 +14,4 @@ rust-version = "1.81" [dependencies] findshlibs = "=0.10.2" -sentry-core = { version = "0.39.0", path = "../sentry-core" } +sentry-core = { version = "0.40.0", path = "../sentry-core" } diff --git a/sentry-debug-images/README.md b/sentry-debug-images/README.md index 0fc832aec..ad2e3600c 100644 --- a/sentry-debug-images/README.md +++ b/sentry-debug-images/README.md @@ -22,7 +22,7 @@ let integration = sentry_debug_images::DebugImagesIntegration::new() .filter(|event| event.level >= Level::Warning); ``` -[`Event`]: https://docs.rs/sentry-debug-images/0.39.0/sentry_debug_images/sentry_core::protocol::Event +[`Event`]: https://docs.rs/sentry-debug-images/0.40.0/sentry_debug_images/sentry_core::protocol::Event ## Resources diff --git a/sentry-log/Cargo.toml b/sentry-log/Cargo.toml index cb36c59e8..51e07960e 100644 --- a/sentry-log/Cargo.toml +++ b/sentry-log/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-log" -version = "0.39.0" +version = "0.40.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -17,7 +17,7 @@ default = [] logs = ["sentry-core/logs"] [dependencies] -sentry-core = { version = "0.39.0", path = "../sentry-core" } +sentry-core = { version = "0.40.0", path = "../sentry-core" } log = { version = "0.4.8", features = ["std"] } [dev-dependencies] diff --git a/sentry-log/README.md b/sentry-log/README.md index 6466bd45f..0af6fd8f6 100644 --- a/sentry-log/README.md +++ b/sentry-log/README.md @@ -6,13 +6,27 @@ # Sentry Rust SDK: sentry-log -Adds support for automatic Breadcrumb and Event capturing from logs. - -The `log` crate is supported in two ways. First, logs can be captured as -breadcrumbs for later. Secondly, error logs can be captured as events to -Sentry. By default anything above `Info` is recorded as a breadcrumb and +Adds support for automatic Breadcrumb, Event, and Log capturing from `log` records. + +The `log` crate is supported in three ways: +- Records can be captured as Sentry events. These are grouped and show up in the Sentry + [issues](https://docs.sentry.io/product/issues/) page, representing high severity issues to be + acted upon. +- Records can be captured as [breadcrumbs](https://docs.sentry.io/product/issues/issue-details/breadcrumbs/). + Breadcrumbs create a trail of what happened prior to an event, and are therefore sent only when + an event is captured, either manually through e.g. `sentry::capture_message` or through integrations + (e.g. the panic integration is enabled (default) and a panic happens). +- Records can be captured as traditional [logs](https://docs.sentry.io/product/explore/logs/) + Logs can be viewed and queried in the Logs explorer. + +By default anything above `Info` is recorded as a breadcrumb and anything above `Error` is captured as error event. +To capture records as Sentry logs: +1. Enable the `logs` feature of the `sentry` crate. +2. Initialize the SDK with `enable_logs: true` in your client options. +3. Set up a custom filter (see below) to map records to logs (`LogFilter::Log`) based on criteria such as severity. + ## Examples ```rust diff --git a/sentry-opentelemetry/Cargo.toml b/sentry-opentelemetry/Cargo.toml index f70370cd0..17a2a70bf 100644 --- a/sentry-opentelemetry/Cargo.toml +++ b/sentry-opentelemetry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-opentelemetry" -version = "0.39.0" +version = "0.40.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -16,7 +16,7 @@ rust-version = "1.81" all-features = true [dependencies] -sentry-core = { version = "0.39.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.40.0", path = "../sentry-core", features = [ "client", ] } opentelemetry = { version = "0.29.0", default-features = false } diff --git a/sentry-panic/Cargo.toml b/sentry-panic/Cargo.toml index ca6e28b45..4f7df7212 100644 --- a/sentry-panic/Cargo.toml +++ b/sentry-panic/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-panic" -version = "0.39.0" +version = "0.40.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -13,8 +13,8 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.39.0", path = "../sentry-core" } -sentry-backtrace = { version = "0.39.0", path = "../sentry-backtrace" } +sentry-core = { version = "0.40.0", path = "../sentry-core" } +sentry-backtrace = { version = "0.40.0", path = "../sentry-backtrace" } [dev-dependencies] sentry = { path = "../sentry", default-features = false, features = ["test"] } diff --git a/sentry-slog/Cargo.toml b/sentry-slog/Cargo.toml index 65e8fe94e..f3c1e5f39 100644 --- a/sentry-slog/Cargo.toml +++ b/sentry-slog/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-slog" -version = "0.39.0" +version = "0.40.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.39.0", path = "../sentry-core" } +sentry-core = { version = "0.40.0", path = "../sentry-core" } slog = { version = "2.5.2", features = ["nested-values"] } serde_json = "1.0.46" diff --git a/sentry-tower/Cargo.toml b/sentry-tower/Cargo.toml index 61a6fc8a1..0a6018d46 100644 --- a/sentry-tower/Cargo.toml +++ b/sentry-tower/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tower" -version = "0.39.0" +version = "0.40.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -26,7 +26,7 @@ tower-layer = "0.3" tower-service = "0.3" http = { version = "1.0.0", optional = true } pin-project = { version = "1.0.10", optional = true } -sentry-core = { version = "0.39.0", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.40.0", path = "../sentry-core", default-features = false, features = [ "client", ] } url = { version = "2.2.2", optional = true } diff --git a/sentry-tower/README.md b/sentry-tower/README.md index f169b6ef5..5a05f140a 100644 --- a/sentry-tower/README.md +++ b/sentry-tower/README.md @@ -103,7 +103,7 @@ feature of the `sentry` crate instead of the `tower` feature. The created transaction will automatically use the request URI as its name. This is sometimes not desirable in case the request URI contains unique IDs or similar. In this case, users should manually override the transaction name -in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.39.0/sentry_tower/sentry_core::Scope::set_transaction) +in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.40.0/sentry_tower/sentry_core::Scope::set_transaction) method. When combining both layers, take care of the ordering of both. For example diff --git a/sentry-tracing/Cargo.toml b/sentry-tracing/Cargo.toml index b7d9acf12..b4ac56216 100644 --- a/sentry-tracing/Cargo.toml +++ b/sentry-tracing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tracing" -version = "0.39.0" +version = "0.40.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -21,14 +21,14 @@ backtrace = ["dep:sentry-backtrace"] logs = ["sentry-core/logs"] [dependencies] -sentry-core = { version = "0.39.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.40.0", path = "../sentry-core", features = [ "client", ] } tracing-core = "0.1" tracing-subscriber = { version = "0.3.1", default-features = false, features = [ "std", ] } -sentry-backtrace = { version = "0.39.0", path = "../sentry-backtrace", optional = true } +sentry-backtrace = { version = "0.40.0", path = "../sentry-backtrace", optional = true } [dev-dependencies] log = "0.4" diff --git a/sentry-tracing/README.md b/sentry-tracing/README.md index 1fb79e80a..a5db3b2f1 100644 --- a/sentry-tracing/README.md +++ b/sentry-tracing/README.md @@ -6,13 +6,26 @@ # Sentry Rust SDK: sentry-tracing -Support for automatic breadcrumb, event, and trace capturing from `tracing` events. - -The `tracing` crate is supported in three ways. First, events can be captured as breadcrumbs for -later. Secondly, error events can be captured as events to Sentry. Finally, spans can be -recorded as structured transaction events. By default, events above `Info` are recorded as -breadcrumbs, events above `Error` are captured as error events, and spans above `Info` are -recorded as transactions. +Support for automatic breadcrumb, event, and trace capturing from `tracing` events and spans. + +The `tracing` crate is supported in four ways: +- `tracing` events can be captured as Sentry events. These are grouped and show up in the Sentry + [issues](https://docs.sentry.io/product/issues/) page, representing high severity issues to be + acted upon. +- `tracing` events can be captured as [breadcrumbs](https://docs.sentry.io/product/issues/issue-details/breadcrumbs/). + Breadcrumbs create a trail of what happened prior to an event, and are therefore sent only when + an event is captured, either manually through e.g. `sentry::capture_message` or through integrations + (e.g. the panic integration is enabled (default) and a panic happens). +- `tracing` events can be captured as traditional [structured logs](https://docs.sentry.io/product/explore/logs/). + The `tracing` fields are captured as attributes on the logs, which can be queried in the Logs + explorer. (Available on crate feature `logs`) +- `tracing` spans can be captured as Sentry spans. These can be used to provide more contextual + information for errors, diagnose [performance + issues](https://docs.sentry.io/product/insights/overview/), and capture additional attributes to + aggregate and compute [metrics](https://docs.sentry.io/product/explore/trace-explorer/). + +By default, events above `Info` are recorded as breadcrumbs, events above `Error` are captured +as error events, and spans above `Info` are recorded as spans. ## Configuration @@ -31,21 +44,24 @@ let _guard = sentry::init(sentry::ClientOptions { // Register the Sentry tracing layer to capture breadcrumbs, events, and spans: tracing_subscriber::registry() .with(tracing_subscriber::fmt::layer()) - .with(sentry_tracing::layer()) + .with(sentry::integrations::tracing::layer()) .init(); ``` -It is also possible to set an explicit filter, to customize which log events are captured by -Sentry: +You can customize the behavior of the layer by providing an explicit event filter, to customize which events +are captured by Sentry and the data type they are mapped to. +Similarly, you can provide a span filter to customize which spans are captured by Sentry. ```rust -use sentry_tracing::EventFilter; +use sentry::integrations::tracing::EventFilter; use tracing_subscriber::prelude::*; -let sentry_layer = sentry_tracing::layer().event_filter(|md| match md.level() { - &tracing::Level::ERROR => EventFilter::Event, - _ => EventFilter::Ignore, -}); +let sentry_layer = sentry::integrations::tracing::layer() + .event_filter(|md| match *md.level() { + tracing::Level::ERROR => EventFilter::Event, + _ => EventFilter::Ignore, + }) + .span_filter(|md| matches!(*md.level(), tracing::Level::ERROR | tracing::Level::WARN)); tracing_subscriber::registry() .with(tracing_subscriber::fmt::layer()) @@ -53,7 +69,12 @@ tracing_subscriber::registry() .init(); ``` -## Logging Messages +In addition, a custom event mapper can be provided, to fully customize if and how `tracing` events are converted to Sentry data. + +Note that if both an event mapper and event filter are set, the mapper takes precedence, thus the +filter has no effect. + +## Capturing breadcrumbs Tracing events automatically create breadcrumbs that are attached to the current scope in Sentry. They show up on errors and transactions captured within this scope as shown in the @@ -69,6 +90,23 @@ for i in 0..10 { } ``` +## Capturing logs + +Tracing events can be captured as traditional structured logs in Sentry. +This is gated by the `logs` feature flag and requires setting up a custom Event filter/mapper +to capture logs. + +```rust +// assuming `tracing::Level::INFO => EventFilter::Log` in your `event_filter` +for i in 0..10 { + tracing::info!(number = i, my.key = "val", my.num = 42, "This is a log"); +} +``` + +The fields of a `tracing` event are captured as attributes of the log. +Logs can be viewed and queried in the Logs explorer based on message and attributes. +Fields containing dots will be displayed as nested under their common prefix in the UI. + ## Tracking Errors The easiest way to emit errors is by logging an event with `ERROR` level. This will create a @@ -83,7 +121,7 @@ tracing::error!( ); ``` -To track [error structs](https://docs.rs/sentry-tracing/0.39.0/sentry_tracing/std::error::Error), assign a reference to error trait object as field +To track [error structs](https://docs.rs/sentry-tracing/0.40.0/sentry_tracing/std::error::Error), assign a reference to error trait object as field in one of the logging macros. By convention, it is recommended to use the `ERROR` level and assign it to a field called `error`, although the integration will also work with all other levels and field names. diff --git a/sentry-types/Cargo.toml b/sentry-types/Cargo.toml index d78c18cfe..992a396f5 100644 --- a/sentry-types/Cargo.toml +++ b/sentry-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-types" -version = "0.39.0" +version = "0.40.0" authors = ["Sentry "] license = "MIT" readme = "README.md" diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index 011e312e5..216a4f55c 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry" -version = "0.39.0" +version = "0.40.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -60,20 +60,20 @@ rustls = ["dep:rustls", "reqwest?/rustls-tls", "ureq?/rustls"] embedded-svc-http = ["dep:embedded-svc", "dep:esp-idf-svc"] [dependencies] -sentry-core = { version = "0.39.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.40.0", path = "../sentry-core", features = [ "client", ] } -sentry-anyhow = { version = "0.39.0", path = "../sentry-anyhow", optional = true } -sentry-actix = { version = "0.39.0", path = "../sentry-actix", optional = true, default-features = false } -sentry-backtrace = { version = "0.39.0", path = "../sentry-backtrace", optional = true } -sentry-contexts = { version = "0.39.0", path = "../sentry-contexts", optional = true } -sentry-debug-images = { version = "0.39.0", path = "../sentry-debug-images", optional = true } -sentry-log = { version = "0.39.0", path = "../sentry-log", optional = true } -sentry-panic = { version = "0.39.0", path = "../sentry-panic", optional = true } -sentry-slog = { version = "0.39.0", path = "../sentry-slog", optional = true } -sentry-tower = { version = "0.39.0", path = "../sentry-tower", optional = true } -sentry-tracing = { version = "0.39.0", path = "../sentry-tracing", optional = true } -sentry-opentelemetry = { version = "0.39.0", path = "../sentry-opentelemetry", optional = true } +sentry-anyhow = { version = "0.40.0", path = "../sentry-anyhow", optional = true } +sentry-actix = { version = "0.40.0", path = "../sentry-actix", optional = true, default-features = false } +sentry-backtrace = { version = "0.40.0", path = "../sentry-backtrace", optional = true } +sentry-contexts = { version = "0.40.0", path = "../sentry-contexts", optional = true } +sentry-debug-images = { version = "0.40.0", path = "../sentry-debug-images", optional = true } +sentry-log = { version = "0.40.0", path = "../sentry-log", optional = true } +sentry-panic = { version = "0.40.0", path = "../sentry-panic", optional = true } +sentry-slog = { version = "0.40.0", path = "../sentry-slog", optional = true } +sentry-tower = { version = "0.40.0", path = "../sentry-tower", optional = true } +sentry-tracing = { version = "0.40.0", path = "../sentry-tracing", optional = true } +sentry-opentelemetry = { version = "0.40.0", path = "../sentry-opentelemetry", optional = true } reqwest = { version = "0.12", optional = true, features = [ "blocking", "json", diff --git a/sentry/README.md b/sentry/README.md index 7034146a5..27f0d8140 100644 --- a/sentry/README.md +++ b/sentry/README.md @@ -34,8 +34,8 @@ sentry::capture_message("Hello World!", sentry::Level::Info); More complex examples on how to use sentry can also be found in [examples]. Extended instructions may also be found on [Sentry itself]. -[`sentry::init`]: https://docs.rs/sentry/0.39.0/sentry/fn.init.html -[`Hub`]: https://docs.rs/sentry/0.39.0/sentry/struct.Hub.html +[`sentry::init`]: https://docs.rs/sentry/0.40.0/sentry/fn.init.html +[`Hub`]: https://docs.rs/sentry/0.40.0/sentry/struct.Hub.html [examples]: https://github.com/getsentry/sentry-rust/tree/master/sentry/examples [Sentry itself]: https://docs.sentry.io/platforms/rust @@ -47,8 +47,8 @@ the ecosystem require a feature flag. For available integrations and how to use [integrations] and [apply_defaults]. [Features]: #features -[integrations]: https://docs.rs/sentry/0.39.0/sentry/integrations/index.html -[apply_defaults]: https://docs.rs/sentry/0.39.0/sentry/fn.apply_defaults.html +[integrations]: https://docs.rs/sentry/0.40.0/sentry/integrations/index.html +[apply_defaults]: https://docs.rs/sentry/0.40.0/sentry/fn.apply_defaults.html ## Minimal API @@ -56,8 +56,8 @@ This crate comes fully-featured. If the goal is to instrument libraries for usag with sentry, or to extend sentry with a custom [`Integration`] or a [`Transport`], one should use the [`sentry-core`] crate instead. -[`Integration`]: https://docs.rs/sentry/0.39.0/sentry/trait.Integration.html -[`Transport`]: https://docs.rs/sentry/0.39.0/sentry/trait.Transport.html +[`Integration`]: https://docs.rs/sentry/0.40.0/sentry/trait.Integration.html +[`Transport`]: https://docs.rs/sentry/0.40.0/sentry/trait.Transport.html [`sentry-core`]: https://crates.io/crates/sentry-core From 333b14ee10f09aa569e8bd542d7f40885d146dd8 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Tue, 17 Jun 2025 12:07:13 +0200 Subject: [PATCH 109/148] fix(logs): stringify u64 attributes greater than `i64::MAX` (#846) --- CHANGELOG.md | 6 ++++++ sentry-types/src/protocol/v7.rs | 4 ++++ sentry-types/tests/test_protocol_v7.rs | 6 +++++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa5db80b0..ac98b5cc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Fixes + +- fix(logs): stringify u64 attributes greater than `i64::MAX` (#846) by @lcian + ## 0.40.0 ### Breaking changes diff --git a/sentry-types/src/protocol/v7.rs b/sentry-types/src/protocol/v7.rs index f7c76aee2..6871d7998 100644 --- a/sentry-types/src/protocol/v7.rs +++ b/sentry-types/src/protocol/v7.rs @@ -2217,6 +2217,10 @@ impl Serialize for LogAttribute { if let Some(i) = n.as_i64() { state.serialize_field("value", &i)?; state.serialize_field("type", "integer")?; + } else if let Some(u) = n.as_u64() { + // Converting to a f64 could lead to precision loss + state.serialize_field("value", &u.to_string())?; + state.serialize_field("type", "string")?; } else if let Some(f) = n.as_f64() { state.serialize_field("value", &f)?; state.serialize_field("type", "double")?; diff --git a/sentry-types/tests/test_protocol_v7.rs b/sentry-types/tests/test_protocol_v7.rs index 88a567cc2..5638d3141 100644 --- a/sentry-types/tests/test_protocol_v7.rs +++ b/sentry-types/tests/test_protocol_v7.rs @@ -1536,8 +1536,12 @@ mod test_logs { (3.1.into(), r#"{"value":3.1,"type":"double"}"#), ("lol".into(), r#"{"value":"lol","type":"string"}"#), (false.into(), r#"{"value":false,"type":"boolean"}"#), - // Special case + // Special cases (Value::Null.into(), r#"{"value":"null","type":"string"}"#), + ( + (u64::MAX - 1).into(), + r#"{"value":"18446744073709551614","type":"string"}"#, + ), // Unsupported types (for now) ( json!(r#"[1,2,3,4]"#).into(), From 20a5d48be380b7f7863d4561986a10c26342312b Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Mon, 23 Jun 2025 09:55:27 +0200 Subject: [PATCH 110/148] feat(tracing): support combined EventFilters and EventMappings (#847) --- CHANGELOG.md | 8 +++ Cargo.lock | 27 ++++---- sentry-tracing/Cargo.toml | 1 + sentry-tracing/src/converters.rs | 8 +-- sentry-tracing/src/layer.rs | 102 ++++++++++++++++++++++--------- sentry-tracing/src/lib.rs | 19 +++++- sentry/tests/test_tracing.rs | 81 ++++++++++++++++++++++++ 7 files changed, 198 insertions(+), 48 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac98b5cc5..40fde2671 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ ## Unreleased +### Breaking changes + +- feat(tracing): support combined EventFilters and EventMappings (#847) by @lcian + - `EventFilter` has been changed to a `bitflags` struct. + - It's now possible to map a `tracing` event to multiple items in Sentry by combining multiple event filters in the `event_filter`, e.g. `tracing::Level::ERROR => EventFilter::Event | EventFilter::Log`. + - It's also possible to use `EventMapping::Combined` to map a `tracing` event to multiple items in Sentry. + - `ctx` in the signatures of `event_from_event`, `breadcrumb_from_event` and `log_from_event` has been changed to take `impl Into>>` to avoid cloning the `Context` when mapping to multiple items. + ### Fixes - fix(logs): stringify u64 attributes greater than `i64::MAX` (#846) by @lcian diff --git a/Cargo.lock b/Cargo.lock index 322210583..feb8b9446 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,7 +8,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "bytes", "futures-core", "futures-sink", @@ -30,7 +30,7 @@ dependencies = [ "actix-service", "actix-utils", "base64", - "bitflags 2.9.0", + "bitflags 2.9.1", "brotli", "bytes", "bytestring", @@ -448,7 +448,7 @@ version = "0.71.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "cexpr", "clang-sys", "itertools 0.13.0", @@ -470,9 +470,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" [[package]] name = "block-buffer" @@ -2152,7 +2152,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "libc", "redox_syscall", ] @@ -2309,7 +2309,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "cfg-if", "cfg_aliases", "libc", @@ -2407,7 +2407,7 @@ version = "0.10.72" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "cfg-if", "foreign-types", "libc", @@ -2852,7 +2852,7 @@ version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", ] [[package]] @@ -3028,7 +3028,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "errno", "libc", "linux-raw-sys 0.4.15", @@ -3041,7 +3041,7 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "errno", "libc", "linux-raw-sys 0.9.4", @@ -3134,7 +3134,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "core-foundation", "core-foundation-sys", "libc", @@ -3334,6 +3334,7 @@ dependencies = [ name = "sentry-tracing" version = "0.40.0" dependencies = [ + "bitflags 2.9.1", "log", "sentry", "sentry-backtrace", @@ -4514,7 +4515,7 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", ] [[package]] diff --git a/sentry-tracing/Cargo.toml b/sentry-tracing/Cargo.toml index b4ac56216..73f94cbc8 100644 --- a/sentry-tracing/Cargo.toml +++ b/sentry-tracing/Cargo.toml @@ -29,6 +29,7 @@ tracing-subscriber = { version = "0.3.1", default-features = false, features = [ "std", ] } sentry-backtrace = { version = "0.40.0", path = "../sentry-backtrace", optional = true } +bitflags = "2.0.0" [dev-dependencies] log = "0.4" diff --git a/sentry-tracing/src/converters.rs b/sentry-tracing/src/converters.rs index 65735f54b..d09f5325a 100644 --- a/sentry-tracing/src/converters.rs +++ b/sentry-tracing/src/converters.rs @@ -77,7 +77,7 @@ fn extract_event_data( /// Extracts the message and metadata from an event, including the data in the current span. fn extract_event_data_with_context( event: &tracing_core::Event, - ctx: Option>, + ctx: Option<&Context>, store_errors_in_values: bool, ) -> (Option, FieldVisitor) where @@ -182,7 +182,7 @@ impl Visit for FieldVisitor { /// Creates a [`Breadcrumb`] from a given [`tracing_core::Event`]. pub fn breadcrumb_from_event<'context, S>( event: &tracing_core::Event, - ctx: impl Into>>, + ctx: impl Into>>, ) -> Breadcrumb where S: Subscriber + for<'a> LookupSpan<'a>, @@ -261,7 +261,7 @@ fn contexts_from_event( /// Creates an [`Event`] (possibly carrying exceptions) from a given [`tracing_core::Event`]. pub fn event_from_event<'context, S>( event: &tracing_core::Event, - ctx: impl Into>>, + ctx: impl Into>>, ) -> Event<'static> where S: Subscriber + for<'a> LookupSpan<'a>, @@ -329,7 +329,7 @@ where #[cfg(feature = "logs")] pub fn log_from_event<'context, S>( event: &tracing_core::Event, - ctx: impl Into>>, + ctx: impl Into>>, ) -> Log where S: Subscriber + for<'a> LookupSpan<'a>, diff --git a/sentry-tracing/src/layer.rs b/sentry-tracing/src/layer.rs index f9cbf3aa2..582427e72 100644 --- a/sentry-tracing/src/layer.rs +++ b/sentry-tracing/src/layer.rs @@ -3,6 +3,7 @@ use std::cell::RefCell; use std::collections::BTreeMap; use std::sync::Arc; +use bitflags::bitflags; use sentry_core::protocol::Value; use sentry_core::{Breadcrumb, TransactionOrSpan}; use tracing_core::field::Visit; @@ -13,21 +14,22 @@ use tracing_subscriber::registry::LookupSpan; use crate::converters::*; use crate::TAGS_PREFIX; -/// The action that Sentry should perform for a given [`Event`] -#[derive(Debug, Clone, Copy)] -pub enum EventFilter { - /// Ignore the [`Event`] - Ignore, - /// Create a [`Breadcrumb`] from this [`Event`] - Breadcrumb, - /// Create a [`sentry_core::protocol::Event`] from this [`Event`] - Event, - /// Create a [`sentry_core::protocol::Log`] from this [`Event`] - #[cfg(feature = "logs")] - Log, +bitflags! { + /// The action that Sentry should perform for a given [`Event`] + #[derive(Debug, Clone, Copy)] + pub struct EventFilter: u32 { + /// Ignore the [`Event`] + const Ignore = 0b000; + /// Create a [`Breadcrumb`] from this [`Event`] + const Breadcrumb = 0b001; + /// Create a [`sentry_core::protocol::Event`] from this [`Event`] + const Event = 0b010; + /// Create a [`sentry_core::protocol::Log`] from this [`Event`] + const Log = 0b100; + } } -/// The type of data Sentry should ingest for a [`Event`] +/// The type of data Sentry should ingest for an [`Event`]. #[derive(Debug)] #[allow(clippy::large_enum_variant)] pub enum EventMapping { @@ -40,6 +42,28 @@ pub enum EventMapping { /// Captures the [`sentry_core::protocol::Log`] to Sentry. #[cfg(feature = "logs")] Log(sentry_core::protocol::Log), + /// Captures multiple items to Sentry. + /// Nesting multiple `EventMapping::Combined` inside each other will cause the inner mappings to be ignored. + Combined(CombinedEventMapping), +} + +/// A list of event mappings. +#[derive(Debug)] +pub struct CombinedEventMapping(Vec); + +impl From for CombinedEventMapping { + fn from(value: EventMapping) -> Self { + match value { + EventMapping::Combined(combined) => combined, + _ => CombinedEventMapping(vec![value]), + } + } +} + +impl From> for CombinedEventMapping { + fn from(value: Vec) -> Self { + Self(value) + } } /// The default event filter. @@ -211,30 +235,48 @@ where S: Subscriber + for<'a> LookupSpan<'a>, { fn on_event(&self, event: &Event, ctx: Context<'_, S>) { - let item = match &self.event_mapper { + let items = match &self.event_mapper { Some(mapper) => mapper(event, ctx), None => { let span_ctx = self.with_span_attributes.then_some(ctx); - match (self.event_filter)(event.metadata()) { - EventFilter::Ignore => EventMapping::Ignore, - EventFilter::Breadcrumb => { - EventMapping::Breadcrumb(breadcrumb_from_event(event, span_ctx)) - } - EventFilter::Event => EventMapping::Event(event_from_event(event, span_ctx)), - #[cfg(feature = "logs")] - EventFilter::Log => EventMapping::Log(log_from_event(event, span_ctx)), + let filter = (self.event_filter)(event.metadata()); + let mut items = vec![]; + if filter.contains(EventFilter::Breadcrumb) { + items.push(EventMapping::Breadcrumb(breadcrumb_from_event( + event, + span_ctx.as_ref(), + ))); + } + if filter.contains(EventFilter::Event) { + items.push(EventMapping::Event(event_from_event( + event, + span_ctx.as_ref(), + ))); } + #[cfg(feature = "logs")] + if filter.contains(EventFilter::Log) { + items.push(EventMapping::Log(log_from_event(event, span_ctx.as_ref()))); + } + EventMapping::Combined(CombinedEventMapping(items)) } }; - - match item { - EventMapping::Event(event) => { - sentry_core::capture_event(event); + let items = CombinedEventMapping::from(items); + + for item in items.0 { + match item { + EventMapping::Ignore => (), + EventMapping::Breadcrumb(breadcrumb) => sentry_core::add_breadcrumb(breadcrumb), + EventMapping::Event(event) => { + sentry_core::capture_event(event); + } + #[cfg(feature = "logs")] + EventMapping::Log(log) => sentry_core::Hub::with_active(|hub| hub.capture_log(log)), + EventMapping::Combined(_) => { + sentry_core::sentry_debug!( + "[SentryLayer] found nested CombinedEventMapping, ignoring" + ) + } } - EventMapping::Breadcrumb(breadcrumb) => sentry_core::add_breadcrumb(breadcrumb), - #[cfg(feature = "logs")] - EventMapping::Log(log) => sentry_core::Hub::with_active(|hub| hub.capture_log(log)), - _ => (), } } diff --git a/sentry-tracing/src/lib.rs b/sentry-tracing/src/lib.rs index 97115ba0a..01483b8a3 100644 --- a/sentry-tracing/src/lib.rs +++ b/sentry-tracing/src/lib.rs @@ -86,7 +86,7 @@ //! //! Tracing events can be captured as traditional structured logs in Sentry. //! This is gated by the `logs` feature flag and requires setting up a custom Event filter/mapper -//! to capture logs. +//! to capture logs. You also need to pass `enable_logs: true` in your `sentry::init` call. //! //! ``` //! // assuming `tracing::Level::INFO => EventFilter::Log` in your `event_filter` @@ -141,6 +141,23 @@ //! tracing::error!(error = &custom_error as &dyn Error, "my operation failed"); //! ``` //! +//! # Sending multiple items to Sentry +//! +//! To map a `tracing` event to multiple items in Sentry, you can combine multiple event filters +//! using the bitwise or operator: +//! +//! ``` +//! let sentry_layer = sentry::integrations::tracing::layer() +//! .event_filter(|md| match *md.level() { +//! tracing::Level::ERROR => EventFilter::Event | EventFilter::Log, +//! tracing::Level::TRACE => EventFilter::Ignore, +//! _ => EventFilter::Log, +//! }) +//! .span_filter(|md| matches!(*md.level(), tracing::Level::ERROR | tracing::Level::WARN)); +//! ``` +//! +//! If you're using a custom event mapper instead of an event filter, use `EventMapping::Combined`. +//! //! # Tracing Spans //! //! The integration automatically tracks `tracing` spans as spans in Sentry. A convenient way to do diff --git a/sentry/tests/test_tracing.rs b/sentry/tests/test_tracing.rs index 6ec51317d..f71e5b231 100644 --- a/sentry/tests/test_tracing.rs +++ b/sentry/tests/test_tracing.rs @@ -277,3 +277,84 @@ fn test_tracing_logs() { _ => panic!("expected item container"), } } + +#[test] +fn test_combined_event_filters() { + let sentry_layer = sentry_tracing::layer().event_filter(|md| match *md.level() { + tracing::Level::ERROR => { + sentry_tracing::EventFilter::Breadcrumb | sentry_tracing::EventFilter::Event + } + tracing::Level::WARN => sentry_tracing::EventFilter::Event, + _ => sentry_tracing::EventFilter::Ignore, + }); + + let _dispatcher = tracing_subscriber::registry() + .with(sentry_layer) + .set_default(); + + let events = sentry::test::with_captured_events(|| { + tracing::error!("Both a breadcrumb and an event"); + tracing::warn!("An event"); + }); + + assert_eq!(events.len(), 2); + + assert_eq!( + events[0].message, + Some("Both a breadcrumb and an event".to_owned()) + ); + + assert_eq!(events[1].message, Some("An event".to_owned())); + assert_eq!(events[1].breadcrumbs.len(), 1); + assert_eq!( + events[1].breadcrumbs[0].message, + Some("Both a breadcrumb and an event".into()) + ); +} + +#[test] +fn test_combined_event_mapper() { + let sentry_layer = + sentry_tracing::layer().event_mapper(|event, ctx| match *event.metadata().level() { + tracing::Level::ERROR => { + let breadcrumb = sentry_tracing::breadcrumb_from_event(event, Some(&ctx)); + let sentry_event = sentry_tracing::event_from_event(event, Some(&ctx)); + + sentry_tracing::EventMapping::Combined( + vec![ + sentry_tracing::EventMapping::Breadcrumb(breadcrumb), + sentry_tracing::EventMapping::Event(sentry_event), + ] + .into(), + ) + } + tracing::Level::WARN => { + let sentry_event = sentry_tracing::event_from_event(event, Some(&ctx)); + sentry_tracing::EventMapping::Event(sentry_event) + } + _ => sentry_tracing::EventMapping::Ignore, + }); + + let _dispatcher = tracing_subscriber::registry() + .with(sentry_layer) + .set_default(); + + let events = sentry::test::with_captured_events(|| { + tracing::error!("Both a breadcrumb and an event"); + tracing::warn!("An event"); + }); + + assert_eq!(events.len(), 2); + + assert_eq!( + events[0].message, + Some("Both a breadcrumb and an event".to_owned()) + ); + + assert_eq!(events[1].message, Some("An event".to_owned())); + assert_eq!(events[1].breadcrumbs.len(), 1); + assert_eq!( + events[1].breadcrumbs[0].message, + Some("Both a breadcrumb and an event".into()) + ); +} From 3a183827e56c104654023c1b72ae90aa8751537e Mon Sep 17 00:00:00 2001 From: Luna Borowska Date: Mon, 23 Jun 2025 10:42:09 +0200 Subject: [PATCH 111/148] chore(deps): bump `anyhow` and disable its `backtrace` feature (#632) Co-authored-by: lcian --- CHANGELOG.md | 4 ++++ Cargo.lock | 3 --- sentry-anyhow/Cargo.toml | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 40fde2671..c5675e1fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,10 @@ - fix(logs): stringify u64 attributes greater than `i64::MAX` (#846) by @lcian +### Dependencies + +- chore(deps): bump `anyhow` and disable its `backtrace` feature (#632) by @LunaBorowska + ## 0.40.0 ### Breaking changes diff --git a/Cargo.lock b/Cargo.lock index feb8b9446..01a443be4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -265,9 +265,6 @@ name = "anyhow" version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" -dependencies = [ - "backtrace", -] [[package]] name = "as-slice" diff --git a/sentry-anyhow/Cargo.toml b/sentry-anyhow/Cargo.toml index a790a0655..9bce7962e 100644 --- a/sentry-anyhow/Cargo.toml +++ b/sentry-anyhow/Cargo.toml @@ -14,12 +14,12 @@ rust-version = "1.81" [features] default = ["backtrace"] -backtrace = ["anyhow/backtrace"] +backtrace = [] [dependencies] sentry-backtrace = { version = "0.40.0", path = "../sentry-backtrace" } sentry-core = { version = "0.40.0", path = "../sentry-core" } -anyhow = "1.0.39" +anyhow = "1.0.77" [dev-dependencies] sentry = { path = "../sentry", default-features = false, features = ["test"] } From 7dbafef610ff8fb74b4d432a070f116da5a0d3d5 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Mon, 23 Jun 2025 10:58:15 +0200 Subject: [PATCH 112/148] feat(core): emit debug log when calling capture_log but logs are disabled (#849) --- CHANGELOG.md | 4 ++++ sentry-core/src/client.rs | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5675e1fe..924ab6a69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,10 @@ - It's also possible to use `EventMapping::Combined` to map a `tracing` event to multiple items in Sentry. - `ctx` in the signatures of `event_from_event`, `breadcrumb_from_event` and `log_from_event` has been changed to take `impl Into>>` to avoid cloning the `Context` when mapping to multiple items. +### Features + +- feat(core): emit debug log when calling capture_log but logs are disabled (#849) by @lcian + ### Fixes - fix(logs): stringify u64 attributes greater than `i64::MAX` (#846) by @lcian diff --git a/sentry-core/src/client.rs b/sentry-core/src/client.rs index 92262ba5e..a4b72d080 100644 --- a/sentry-core/src/client.rs +++ b/sentry-core/src/client.rs @@ -464,7 +464,8 @@ impl Client { /// Captures a log and sends it to Sentry. #[cfg(feature = "logs")] pub fn capture_log(&self, log: Log, scope: &Scope) { - if !self.options().enable_logs { + if !self.options.enable_logs { + sentry_debug!("[Client] called capture_log, but options.enable_logs is set to false"); return; } if let Some(log) = self.prepare_log(log, scope) { From 1d89cb8b58fa3fe3d13b446a9c37507240cb3ee9 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Mon, 23 Jun 2025 11:20:29 +0200 Subject: [PATCH 113/148] fix(tracing): fix doctest (#850) --- sentry-tracing/src/lib.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sentry-tracing/src/lib.rs b/sentry-tracing/src/lib.rs index 01483b8a3..df6887180 100644 --- a/sentry-tracing/src/lib.rs +++ b/sentry-tracing/src/lib.rs @@ -147,6 +147,9 @@ //! using the bitwise or operator: //! //! ``` +//! use sentry::integrations::tracing::EventFilter; +//! use tracing_subscriber::prelude::*; +//! //! let sentry_layer = sentry::integrations::tracing::layer() //! .event_filter(|md| match *md.level() { //! tracing::Level::ERROR => EventFilter::Event | EventFilter::Log, @@ -154,6 +157,11 @@ //! _ => EventFilter::Log, //! }) //! .span_filter(|md| matches!(*md.level(), tracing::Level::ERROR | tracing::Level::WARN)); +//! +//! tracing_subscriber::registry() +//! .with(tracing_subscriber::fmt::layer()) +//! .with(sentry_layer) +//! .init(); //! ``` //! //! If you're using a custom event mapper instead of an event filter, use `EventMapping::Combined`. From 673e8dd6ec744880283055e0450744e997767c7a Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Mon, 23 Jun 2025 09:25:25 +0000 Subject: [PATCH 114/148] release: 0.41.0 --- CHANGELOG.md | 2 +- Cargo.lock | 28 ++++++++++++++-------------- sentry-actix/Cargo.toml | 4 ++-- sentry-anyhow/Cargo.toml | 6 +++--- sentry-backtrace/Cargo.toml | 4 ++-- sentry-contexts/Cargo.toml | 4 ++-- sentry-core/Cargo.toml | 4 ++-- sentry-core/README.md | 2 +- sentry-debug-images/Cargo.toml | 4 ++-- sentry-debug-images/README.md | 2 +- sentry-log/Cargo.toml | 4 ++-- sentry-opentelemetry/Cargo.toml | 4 ++-- sentry-panic/Cargo.toml | 6 +++--- sentry-slog/Cargo.toml | 4 ++-- sentry-tower/Cargo.toml | 4 ++-- sentry-tower/README.md | 2 +- sentry-tracing/Cargo.toml | 6 +++--- sentry-tracing/README.md | 29 +++++++++++++++++++++++++++-- sentry-types/Cargo.toml | 2 +- sentry/Cargo.toml | 26 +++++++++++++------------- sentry/README.md | 12 ++++++------ 21 files changed, 92 insertions(+), 67 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 924ab6a69..72fb129cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 0.41.0 ### Breaking changes diff --git a/Cargo.lock b/Cargo.lock index 01a443be4..2a13bf162 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3159,7 +3159,7 @@ dependencies = [ [[package]] name = "sentry" -version = "0.40.0" +version = "0.41.0" dependencies = [ "actix-web", "anyhow", @@ -3195,7 +3195,7 @@ dependencies = [ [[package]] name = "sentry-actix" -version = "0.40.0" +version = "0.41.0" dependencies = [ "actix-http", "actix-web", @@ -3209,7 +3209,7 @@ dependencies = [ [[package]] name = "sentry-anyhow" -version = "0.40.0" +version = "0.41.0" dependencies = [ "anyhow", "sentry", @@ -3219,7 +3219,7 @@ dependencies = [ [[package]] name = "sentry-backtrace" -version = "0.40.0" +version = "0.41.0" dependencies = [ "backtrace", "regex", @@ -3228,7 +3228,7 @@ dependencies = [ [[package]] name = "sentry-contexts" -version = "0.40.0" +version = "0.41.0" dependencies = [ "hostname", "libc", @@ -3241,7 +3241,7 @@ dependencies = [ [[package]] name = "sentry-core" -version = "0.40.0" +version = "0.41.0" dependencies = [ "anyhow", "criterion", @@ -3260,7 +3260,7 @@ dependencies = [ [[package]] name = "sentry-debug-images" -version = "0.40.0" +version = "0.41.0" dependencies = [ "findshlibs", "sentry-core", @@ -3268,7 +3268,7 @@ dependencies = [ [[package]] name = "sentry-log" -version = "0.40.0" +version = "0.41.0" dependencies = [ "log", "pretty_env_logger", @@ -3278,7 +3278,7 @@ dependencies = [ [[package]] name = "sentry-opentelemetry" -version = "0.40.0" +version = "0.41.0" dependencies = [ "opentelemetry", "opentelemetry_sdk", @@ -3288,7 +3288,7 @@ dependencies = [ [[package]] name = "sentry-panic" -version = "0.40.0" +version = "0.41.0" dependencies = [ "sentry", "sentry-backtrace", @@ -3297,7 +3297,7 @@ dependencies = [ [[package]] name = "sentry-slog" -version = "0.40.0" +version = "0.41.0" dependencies = [ "erased-serde", "sentry", @@ -3309,7 +3309,7 @@ dependencies = [ [[package]] name = "sentry-tower" -version = "0.40.0" +version = "0.41.0" dependencies = [ "anyhow", "axum 0.8.3", @@ -3329,7 +3329,7 @@ dependencies = [ [[package]] name = "sentry-tracing" -version = "0.40.0" +version = "0.41.0" dependencies = [ "bitflags 2.9.1", "log", @@ -3345,7 +3345,7 @@ dependencies = [ [[package]] name = "sentry-types" -version = "0.40.0" +version = "0.41.0" dependencies = [ "debugid", "hex", diff --git a/sentry-actix/Cargo.toml b/sentry-actix/Cargo.toml index bd4700123..84ae04fb9 100644 --- a/sentry-actix/Cargo.toml +++ b/sentry-actix/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-actix" -version = "0.40.0" +version = "0.41.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -20,7 +20,7 @@ release-health = ["sentry-core/release-health"] actix-web = { version = "4", default-features = false } bytes = "1.2" futures-util = { version = "0.3.5", default-features = false } -sentry-core = { version = "0.40.0", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.41.0", path = "../sentry-core", default-features = false, features = [ "client", ] } actix-http = "3.10" diff --git a/sentry-anyhow/Cargo.toml b/sentry-anyhow/Cargo.toml index 9bce7962e..66cf0bfb6 100644 --- a/sentry-anyhow/Cargo.toml +++ b/sentry-anyhow/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-anyhow" -version = "0.40.0" +version = "0.41.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -17,8 +17,8 @@ default = ["backtrace"] backtrace = [] [dependencies] -sentry-backtrace = { version = "0.40.0", path = "../sentry-backtrace" } -sentry-core = { version = "0.40.0", path = "../sentry-core" } +sentry-backtrace = { version = "0.41.0", path = "../sentry-backtrace" } +sentry-core = { version = "0.41.0", path = "../sentry-core" } anyhow = "1.0.77" [dev-dependencies] diff --git a/sentry-backtrace/Cargo.toml b/sentry-backtrace/Cargo.toml index 37c038a7b..2de5bba13 100644 --- a/sentry-backtrace/Cargo.toml +++ b/sentry-backtrace/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-backtrace" -version = "0.40.0" +version = "0.41.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -18,4 +18,4 @@ regex = { version = "1.5.5", default-features = false, features = [ "std", "unicode-perl", ] } -sentry-core = { version = "0.40.0", path = "../sentry-core" } +sentry-core = { version = "0.41.0", path = "../sentry-core" } diff --git a/sentry-contexts/Cargo.toml b/sentry-contexts/Cargo.toml index 16840b96c..673b143d1 100644 --- a/sentry-contexts/Cargo.toml +++ b/sentry-contexts/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-contexts" -version = "0.40.0" +version = "0.41.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -14,7 +14,7 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.40.0", path = "../sentry-core" } +sentry-core = { version = "0.41.0", path = "../sentry-core" } libc = "0.2.66" hostname = "0.4" diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index 773b58e77..b7994cc4c 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-core" -version = "0.40.0" +version = "0.41.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -29,7 +29,7 @@ logs = [] [dependencies] log = { version = "0.4.8", optional = true, features = ["std"] } rand = { version = "0.9.0", optional = true } -sentry-types = { version = "0.40.0", path = "../sentry-types" } +sentry-types = { version = "0.41.0", path = "../sentry-types" } serde = { version = "1.0.104", features = ["derive"] } serde_json = { version = "1.0.46" } uuid = { version = "1.0.0", features = ["v4", "serde"], optional = true } diff --git a/sentry-core/README.md b/sentry-core/README.md index 8965eed0d..5dfbf4084 100644 --- a/sentry-core/README.md +++ b/sentry-core/README.md @@ -99,7 +99,7 @@ functionality. [Sentry]: https://sentry.io/ [`sentry`]: https://crates.io/crates/sentry [Unified API]: https://develop.sentry.dev/sdk/unified-api/ -[`test`]: https://docs.rs/sentry-core/0.40.0/sentry_core/test/index.html +[`test`]: https://docs.rs/sentry-core/0.41.0/sentry_core/test/index.html ## Resources diff --git a/sentry-debug-images/Cargo.toml b/sentry-debug-images/Cargo.toml index 582b8f6df..8ef8cea64 100644 --- a/sentry-debug-images/Cargo.toml +++ b/sentry-debug-images/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-debug-images" -version = "0.40.0" +version = "0.41.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -14,4 +14,4 @@ rust-version = "1.81" [dependencies] findshlibs = "=0.10.2" -sentry-core = { version = "0.40.0", path = "../sentry-core" } +sentry-core = { version = "0.41.0", path = "../sentry-core" } diff --git a/sentry-debug-images/README.md b/sentry-debug-images/README.md index ad2e3600c..7d57f4baa 100644 --- a/sentry-debug-images/README.md +++ b/sentry-debug-images/README.md @@ -22,7 +22,7 @@ let integration = sentry_debug_images::DebugImagesIntegration::new() .filter(|event| event.level >= Level::Warning); ``` -[`Event`]: https://docs.rs/sentry-debug-images/0.40.0/sentry_debug_images/sentry_core::protocol::Event +[`Event`]: https://docs.rs/sentry-debug-images/0.41.0/sentry_debug_images/sentry_core::protocol::Event ## Resources diff --git a/sentry-log/Cargo.toml b/sentry-log/Cargo.toml index 51e07960e..ed2ba216a 100644 --- a/sentry-log/Cargo.toml +++ b/sentry-log/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-log" -version = "0.40.0" +version = "0.41.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -17,7 +17,7 @@ default = [] logs = ["sentry-core/logs"] [dependencies] -sentry-core = { version = "0.40.0", path = "../sentry-core" } +sentry-core = { version = "0.41.0", path = "../sentry-core" } log = { version = "0.4.8", features = ["std"] } [dev-dependencies] diff --git a/sentry-opentelemetry/Cargo.toml b/sentry-opentelemetry/Cargo.toml index 17a2a70bf..d9bce4410 100644 --- a/sentry-opentelemetry/Cargo.toml +++ b/sentry-opentelemetry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-opentelemetry" -version = "0.40.0" +version = "0.41.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -16,7 +16,7 @@ rust-version = "1.81" all-features = true [dependencies] -sentry-core = { version = "0.40.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.41.0", path = "../sentry-core", features = [ "client", ] } opentelemetry = { version = "0.29.0", default-features = false } diff --git a/sentry-panic/Cargo.toml b/sentry-panic/Cargo.toml index 4f7df7212..e44e3b7f6 100644 --- a/sentry-panic/Cargo.toml +++ b/sentry-panic/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-panic" -version = "0.40.0" +version = "0.41.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -13,8 +13,8 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.40.0", path = "../sentry-core" } -sentry-backtrace = { version = "0.40.0", path = "../sentry-backtrace" } +sentry-core = { version = "0.41.0", path = "../sentry-core" } +sentry-backtrace = { version = "0.41.0", path = "../sentry-backtrace" } [dev-dependencies] sentry = { path = "../sentry", default-features = false, features = ["test"] } diff --git a/sentry-slog/Cargo.toml b/sentry-slog/Cargo.toml index f3c1e5f39..7043bf165 100644 --- a/sentry-slog/Cargo.toml +++ b/sentry-slog/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-slog" -version = "0.40.0" +version = "0.41.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.40.0", path = "../sentry-core" } +sentry-core = { version = "0.41.0", path = "../sentry-core" } slog = { version = "2.5.2", features = ["nested-values"] } serde_json = "1.0.46" diff --git a/sentry-tower/Cargo.toml b/sentry-tower/Cargo.toml index 0a6018d46..10fb801bd 100644 --- a/sentry-tower/Cargo.toml +++ b/sentry-tower/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tower" -version = "0.40.0" +version = "0.41.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -26,7 +26,7 @@ tower-layer = "0.3" tower-service = "0.3" http = { version = "1.0.0", optional = true } pin-project = { version = "1.0.10", optional = true } -sentry-core = { version = "0.40.0", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.41.0", path = "../sentry-core", default-features = false, features = [ "client", ] } url = { version = "2.2.2", optional = true } diff --git a/sentry-tower/README.md b/sentry-tower/README.md index 5a05f140a..20a82831e 100644 --- a/sentry-tower/README.md +++ b/sentry-tower/README.md @@ -103,7 +103,7 @@ feature of the `sentry` crate instead of the `tower` feature. The created transaction will automatically use the request URI as its name. This is sometimes not desirable in case the request URI contains unique IDs or similar. In this case, users should manually override the transaction name -in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.40.0/sentry_tower/sentry_core::Scope::set_transaction) +in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.41.0/sentry_tower/sentry_core::Scope::set_transaction) method. When combining both layers, take care of the ordering of both. For example diff --git a/sentry-tracing/Cargo.toml b/sentry-tracing/Cargo.toml index 73f94cbc8..8e12dc88f 100644 --- a/sentry-tracing/Cargo.toml +++ b/sentry-tracing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tracing" -version = "0.40.0" +version = "0.41.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -21,14 +21,14 @@ backtrace = ["dep:sentry-backtrace"] logs = ["sentry-core/logs"] [dependencies] -sentry-core = { version = "0.40.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.41.0", path = "../sentry-core", features = [ "client", ] } tracing-core = "0.1" tracing-subscriber = { version = "0.3.1", default-features = false, features = [ "std", ] } -sentry-backtrace = { version = "0.40.0", path = "../sentry-backtrace", optional = true } +sentry-backtrace = { version = "0.41.0", path = "../sentry-backtrace", optional = true } bitflags = "2.0.0" [dev-dependencies] diff --git a/sentry-tracing/README.md b/sentry-tracing/README.md index a5db3b2f1..121f1711e 100644 --- a/sentry-tracing/README.md +++ b/sentry-tracing/README.md @@ -94,7 +94,7 @@ for i in 0..10 { Tracing events can be captured as traditional structured logs in Sentry. This is gated by the `logs` feature flag and requires setting up a custom Event filter/mapper -to capture logs. +to capture logs. You also need to pass `enable_logs: true` in your `sentry::init` call. ```rust // assuming `tracing::Level::INFO => EventFilter::Log` in your `event_filter` @@ -121,7 +121,7 @@ tracing::error!( ); ``` -To track [error structs](https://docs.rs/sentry-tracing/0.40.0/sentry_tracing/std::error::Error), assign a reference to error trait object as field +To track [error structs](https://docs.rs/sentry-tracing/0.41.0/sentry_tracing/std::error::Error), assign a reference to error trait object as field in one of the logging macros. By convention, it is recommended to use the `ERROR` level and assign it to a field called `error`, although the integration will also work with all other levels and field names. @@ -149,6 +149,31 @@ let custom_error = io::Error::new(io::ErrorKind::Other, "oh no"); tracing::error!(error = &custom_error as &dyn Error, "my operation failed"); ``` +## Sending multiple items to Sentry + +To map a `tracing` event to multiple items in Sentry, you can combine multiple event filters +using the bitwise or operator: + +```rust +use sentry::integrations::tracing::EventFilter; +use tracing_subscriber::prelude::*; + +let sentry_layer = sentry::integrations::tracing::layer() + .event_filter(|md| match *md.level() { + tracing::Level::ERROR => EventFilter::Event | EventFilter::Log, + tracing::Level::TRACE => EventFilter::Ignore, + _ => EventFilter::Log, + }) + .span_filter(|md| matches!(*md.level(), tracing::Level::ERROR | tracing::Level::WARN)); + +tracing_subscriber::registry() + .with(tracing_subscriber::fmt::layer()) + .with(sentry_layer) + .init(); +``` + +If you're using a custom event mapper instead of an event filter, use `EventMapping::Combined`. + ## Tracing Spans The integration automatically tracks `tracing` spans as spans in Sentry. A convenient way to do diff --git a/sentry-types/Cargo.toml b/sentry-types/Cargo.toml index 992a396f5..0d8eef039 100644 --- a/sentry-types/Cargo.toml +++ b/sentry-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-types" -version = "0.40.0" +version = "0.41.0" authors = ["Sentry "] license = "MIT" readme = "README.md" diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index 216a4f55c..9a43eed10 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry" -version = "0.40.0" +version = "0.41.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -60,20 +60,20 @@ rustls = ["dep:rustls", "reqwest?/rustls-tls", "ureq?/rustls"] embedded-svc-http = ["dep:embedded-svc", "dep:esp-idf-svc"] [dependencies] -sentry-core = { version = "0.40.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.41.0", path = "../sentry-core", features = [ "client", ] } -sentry-anyhow = { version = "0.40.0", path = "../sentry-anyhow", optional = true } -sentry-actix = { version = "0.40.0", path = "../sentry-actix", optional = true, default-features = false } -sentry-backtrace = { version = "0.40.0", path = "../sentry-backtrace", optional = true } -sentry-contexts = { version = "0.40.0", path = "../sentry-contexts", optional = true } -sentry-debug-images = { version = "0.40.0", path = "../sentry-debug-images", optional = true } -sentry-log = { version = "0.40.0", path = "../sentry-log", optional = true } -sentry-panic = { version = "0.40.0", path = "../sentry-panic", optional = true } -sentry-slog = { version = "0.40.0", path = "../sentry-slog", optional = true } -sentry-tower = { version = "0.40.0", path = "../sentry-tower", optional = true } -sentry-tracing = { version = "0.40.0", path = "../sentry-tracing", optional = true } -sentry-opentelemetry = { version = "0.40.0", path = "../sentry-opentelemetry", optional = true } +sentry-anyhow = { version = "0.41.0", path = "../sentry-anyhow", optional = true } +sentry-actix = { version = "0.41.0", path = "../sentry-actix", optional = true, default-features = false } +sentry-backtrace = { version = "0.41.0", path = "../sentry-backtrace", optional = true } +sentry-contexts = { version = "0.41.0", path = "../sentry-contexts", optional = true } +sentry-debug-images = { version = "0.41.0", path = "../sentry-debug-images", optional = true } +sentry-log = { version = "0.41.0", path = "../sentry-log", optional = true } +sentry-panic = { version = "0.41.0", path = "../sentry-panic", optional = true } +sentry-slog = { version = "0.41.0", path = "../sentry-slog", optional = true } +sentry-tower = { version = "0.41.0", path = "../sentry-tower", optional = true } +sentry-tracing = { version = "0.41.0", path = "../sentry-tracing", optional = true } +sentry-opentelemetry = { version = "0.41.0", path = "../sentry-opentelemetry", optional = true } reqwest = { version = "0.12", optional = true, features = [ "blocking", "json", diff --git a/sentry/README.md b/sentry/README.md index 27f0d8140..b2f4475e9 100644 --- a/sentry/README.md +++ b/sentry/README.md @@ -34,8 +34,8 @@ sentry::capture_message("Hello World!", sentry::Level::Info); More complex examples on how to use sentry can also be found in [examples]. Extended instructions may also be found on [Sentry itself]. -[`sentry::init`]: https://docs.rs/sentry/0.40.0/sentry/fn.init.html -[`Hub`]: https://docs.rs/sentry/0.40.0/sentry/struct.Hub.html +[`sentry::init`]: https://docs.rs/sentry/0.41.0/sentry/fn.init.html +[`Hub`]: https://docs.rs/sentry/0.41.0/sentry/struct.Hub.html [examples]: https://github.com/getsentry/sentry-rust/tree/master/sentry/examples [Sentry itself]: https://docs.sentry.io/platforms/rust @@ -47,8 +47,8 @@ the ecosystem require a feature flag. For available integrations and how to use [integrations] and [apply_defaults]. [Features]: #features -[integrations]: https://docs.rs/sentry/0.40.0/sentry/integrations/index.html -[apply_defaults]: https://docs.rs/sentry/0.40.0/sentry/fn.apply_defaults.html +[integrations]: https://docs.rs/sentry/0.41.0/sentry/integrations/index.html +[apply_defaults]: https://docs.rs/sentry/0.41.0/sentry/fn.apply_defaults.html ## Minimal API @@ -56,8 +56,8 @@ This crate comes fully-featured. If the goal is to instrument libraries for usag with sentry, or to extend sentry with a custom [`Integration`] or a [`Transport`], one should use the [`sentry-core`] crate instead. -[`Integration`]: https://docs.rs/sentry/0.40.0/sentry/trait.Integration.html -[`Transport`]: https://docs.rs/sentry/0.40.0/sentry/trait.Transport.html +[`Integration`]: https://docs.rs/sentry/0.41.0/sentry/trait.Integration.html +[`Transport`]: https://docs.rs/sentry/0.41.0/sentry/trait.Transport.html [`sentry-core`]: https://crates.io/crates/sentry-core From 873bb1d0c24c02c643168e6e01a7bfa2c4097440 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Mon, 30 Jun 2025 13:58:54 +0200 Subject: [PATCH 115/148] feat(log): support kv feature of log (#851) --- CHANGELOG.md | 5 ++ sentry-log/Cargo.toml | 2 +- sentry-log/src/converters.rs | 89 +++++++++++++++++++++++++++++++++-- sentry/tests/test_log_logs.rs | 10 +++- 4 files changed, 99 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72fb129cc..bc697884f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## Unreleased + +- feat(log): support kv feature of log (#851) by @lcian + - Attributes added to a `log` record using the `kv` feature are now recorded as attributes on the log sent to Sentry. + ## 0.41.0 ### Breaking changes diff --git a/sentry-log/Cargo.toml b/sentry-log/Cargo.toml index ed2ba216a..6df10711b 100644 --- a/sentry-log/Cargo.toml +++ b/sentry-log/Cargo.toml @@ -18,7 +18,7 @@ logs = ["sentry-core/logs"] [dependencies] sentry-core = { version = "0.41.0", path = "../sentry-core" } -log = { version = "0.4.8", features = ["std"] } +log = { version = "0.4.8", features = ["std", "kv"] } [dev-dependencies] sentry = { path = "../sentry", default-features = false, features = ["test"] } diff --git a/sentry-log/src/converters.rs b/sentry-log/src/converters.rs index baf7d4640..f7a4356e1 100644 --- a/sentry-log/src/converters.rs +++ b/sentry-log/src/converters.rs @@ -1,9 +1,10 @@ -use sentry_core::protocol::Event; +use sentry_core::protocol::{Event, Value}; #[cfg(feature = "logs")] use sentry_core::protocol::{Log, LogAttribute, LogLevel}; use sentry_core::{Breadcrumb, Level}; +use std::collections::BTreeMap; #[cfg(feature = "logs")] -use std::{collections::BTreeMap, time::SystemTime}; +use std::time::SystemTime; /// Converts a [`log::Level`] to a Sentry [`Level`], used for [`Event`] and [`Breadcrumb`]. pub fn convert_log_level(level: log::Level) -> Level { @@ -27,23 +28,97 @@ pub fn convert_log_level_to_sentry_log_level(level: log::Level) -> LogLevel { } } +/// Visitor to extract key-value pairs from log records +#[derive(Default)] +struct AttributeVisitor { + json_values: BTreeMap, +} + +impl AttributeVisitor { + fn record>(&mut self, key: &str, value: T) { + self.json_values.insert(key.to_owned(), value.into()); + } +} + +impl log::kv::VisitSource<'_> for AttributeVisitor { + fn visit_pair( + &mut self, + key: log::kv::Key, + value: log::kv::Value, + ) -> Result<(), log::kv::Error> { + let key = key.as_str(); + + if let Some(value) = value.to_borrowed_str() { + self.record(key, value); + } else if let Some(value) = value.to_u64() { + self.record(key, value); + } else if let Some(value) = value.to_f64() { + self.record(key, value); + } else if let Some(value) = value.to_bool() { + self.record(key, value); + } else { + self.record(key, format!("{:?}", value)); + }; + + Ok(()) + } +} + +fn extract_record_attributes(record: &log::Record<'_>) -> AttributeVisitor { + let mut visitor = AttributeVisitor::default(); + let _ = record.key_values().visit(&mut visitor); + visitor +} + /// Creates a [`Breadcrumb`] from a given [`log::Record`]. pub fn breadcrumb_from_record(record: &log::Record<'_>) -> Breadcrumb { + let visitor = extract_record_attributes(record); + Breadcrumb { ty: "log".into(), level: convert_log_level(record.level()), category: Some(record.target().into()), message: Some(record.args().to_string()), + data: visitor.json_values, ..Default::default() } } /// Creates an [`Event`] from a given [`log::Record`]. pub fn event_from_record(record: &log::Record<'_>) -> Event<'static> { + let visitor = extract_record_attributes(record); + let attributes = visitor.json_values; + + let mut contexts = BTreeMap::new(); + + let mut metadata_map = BTreeMap::new(); + metadata_map.insert("logger.target".into(), record.target().into()); + if let Some(module_path) = record.module_path() { + metadata_map.insert("logger.module_path".into(), module_path.into()); + } + if let Some(file) = record.file() { + metadata_map.insert("logger.file".into(), file.into()); + } + if let Some(line) = record.line() { + metadata_map.insert("logger.line".into(), line.into()); + } + contexts.insert( + "Rust Log Metadata".to_string(), + sentry_core::protocol::Context::Other(metadata_map), + ); + + if !attributes.is_empty() { + contexts.insert( + "Rust Log Attributes".to_string(), + sentry_core::protocol::Context::Other(attributes), + ); + } + Event { logger: Some(record.target().into()), level: convert_log_level(record.level()), message: Some(record.args().to_string()), + contexts, ..Default::default() } } @@ -60,7 +135,13 @@ pub fn exception_from_record(record: &log::Record<'_>) -> Event<'static> { /// Creates a [`Log`] from a given [`log::Record`]. #[cfg(feature = "logs")] pub fn log_from_record(record: &log::Record<'_>) -> Log { - let mut attributes: BTreeMap = BTreeMap::new(); + let visitor = extract_record_attributes(record); + + let mut attributes: BTreeMap = visitor + .json_values + .into_iter() + .map(|(key, val)| (key, val.into())) + .collect(); attributes.insert("logger.target".into(), record.target().into()); if let Some(module_path) = record.module_path() { @@ -75,8 +156,6 @@ pub fn log_from_record(record: &log::Record<'_>) -> Log { attributes.insert("sentry.origin".into(), "auto.logger.log".into()); - // TODO: support the `kv` feature and store key value pairs as attributes - Log { level: convert_log_level_to_sentry_log_level(record.level()), body: format!("{}", record.args()), diff --git a/sentry/tests/test_log_logs.rs b/sentry/tests/test_log_logs.rs index adaa2993a..1d631a5bf 100644 --- a/sentry/tests/test_log_logs.rs +++ b/sentry/tests/test_log_logs.rs @@ -18,7 +18,7 @@ fn test_log_logs() { let envelopes = sentry::test::with_captured_envelopes_options( || { - log::info!("This is a log"); + log::info!(user_id = 42, request_id = "abc123"; "This is a log"); }, options, ); @@ -37,6 +37,14 @@ fn test_log_logs() { .find(|log| log.level == sentry::protocol::LogLevel::Info) .expect("expected info log"); assert_eq!(info_log.body, "This is a log"); + assert_eq!( + info_log.attributes.get("user_id").unwrap().clone(), + 42.into() + ); + assert_eq!( + info_log.attributes.get("request_id").unwrap().clone(), + "abc123".into() + ); assert_eq!( info_log.attributes.get("logger.target").unwrap().clone(), "test_log_logs".into() From 58fd4efef0c81aee808d48a7ce94fb9ad444d3b0 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Fri, 4 Jul 2025 12:42:51 +0200 Subject: [PATCH 116/148] chore: `cargo +stable clippy --fix` (#859) --- sentry-log/src/converters.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sentry-log/src/converters.rs b/sentry-log/src/converters.rs index f7a4356e1..799659ab4 100644 --- a/sentry-log/src/converters.rs +++ b/sentry-log/src/converters.rs @@ -57,7 +57,7 @@ impl log::kv::VisitSource<'_> for AttributeVisitor { } else if let Some(value) = value.to_bool() { self.record(key, value); } else { - self.record(key, format!("{:?}", value)); + self.record(key, format!("{value:?}")); }; Ok(()) From a63853e707af17dbc0348bfbf574253acb5f32b9 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Fri, 4 Jul 2025 13:36:29 +0200 Subject: [PATCH 117/148] feat: send trace origin (#858) --- sentry-actix/src/lib.rs | 1 + sentry-opentelemetry/src/processor.rs | 5 +++++ sentry-tower/src/http.rs | 1 + sentry-tracing/src/layer.rs | 4 +++- sentry-tracing/tests/smoke.rs | 2 +- 5 files changed, 11 insertions(+), 2 deletions(-) diff --git a/sentry-actix/src/lib.rs b/sentry-actix/src/lib.rs index 4a2de94fe..84a33b3b1 100644 --- a/sentry-actix/src/lib.rs +++ b/sentry-actix/src/lib.rs @@ -322,6 +322,7 @@ where let transaction = hub.start_transaction(ctx); transaction.set_request(sentry_req.clone()); + transaction.set_data("origin", "auto.http.actix".into()); Some(transaction) } else { None diff --git a/sentry-opentelemetry/src/processor.rs b/sentry-opentelemetry/src/processor.rs index 4c115cb94..f883d163e 100644 --- a/sentry-opentelemetry/src/processor.rs +++ b/sentry-opentelemetry/src/processor.rs @@ -170,8 +170,13 @@ impl SpanProcessor for SentrySpanProcessor { for attribute in data.attributes { sentry_span.set_data(attribute.key.as_str(), convert_value(attribute.value)); } + // TODO: read OTEL semantic convention span attributes and map them to the appropriate // Sentry span attributes/context values + + if matches!(sentry_span, TransactionOrSpan::Transaction(_)) { + sentry_span.set_data("origin", "auto.otel".into()) + } sentry_span.set_status(convert_span_status(&data.status)); sentry_span.finish_with_timestamp(data.end_time); } diff --git a/sentry-tower/src/http.rs b/sentry-tower/src/http.rs index 95b46ad39..92cc034b2 100644 --- a/sentry-tower/src/http.rs +++ b/sentry-tower/src/http.rs @@ -121,6 +121,7 @@ where let transaction: sentry_core::TransactionOrSpan = sentry_core::start_transaction(trx_ctx).into(); transaction.set_request(sentry_req.clone()); + transaction.set_data("origin", "auto.http.tower".into()); let parent_span = scope.get_span(); scope.set_span(Some(transaction.clone())); *slf.transaction = Some((transaction, parent_span)); diff --git a/sentry-tracing/src/layer.rs b/sentry-tracing/src/layer.rs index 582427e72..efc4da540 100644 --- a/sentry-tracing/src/layer.rs +++ b/sentry-tracing/src/layer.rs @@ -313,7 +313,9 @@ where Some(parent) => parent.start_child(op, &description).into(), None => { let ctx = sentry_core::TransactionContext::new(&description, op); - sentry_core::start_transaction(ctx).into() + let tx = sentry_core::start_transaction(ctx); + tx.set_data("origin", "auto.tracing".into()); + tx.into() } }; // Add the data from the original span to the sentry span. diff --git a/sentry-tracing/tests/smoke.rs b/sentry-tracing/tests/smoke.rs index 5bc0322ae..cb4f04e34 100644 --- a/sentry-tracing/tests/smoke.rs +++ b/sentry-tracing/tests/smoke.rs @@ -33,7 +33,7 @@ fn should_instrument_function_with_event() { unexpected => panic!("Expected transaction, but got {unexpected:#?}"), }; assert_eq!(transaction.tags.len(), 1); - assert_eq!(trace.data.len(), 2); + assert_eq!(trace.data.len(), 3); let tag = transaction .tags From f247ac01323b093a1f7ea17abce6bc6373c68e3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Gonz=C3=A1lez?= <7822554+AlexTMjugador@users.noreply.github.com> Date: Mon, 7 Jul 2025 13:58:28 +0200 Subject: [PATCH 118/148] docs: match description of `debug` option with behavior since #820 (#860) Co-authored-by: Lorenzo Cian --- CHANGELOG.md | 8 +++++++- sentry-core/src/clientoptions.rs | 3 +-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc697884f..65c580e1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,15 @@ ## Unreleased +### Features + - feat(log): support kv feature of log (#851) by @lcian - Attributes added to a `log` record using the `kv` feature are now recorded as attributes on the log sent to Sentry. +### Fixes + +- docs: match description of `debug` option with behavior since PR #820 ([#860](https://github.com/getsentry/sentry-rust/pull/860)) by @AlexTMjugador + ## 0.41.0 ### Breaking changes @@ -15,7 +21,7 @@ - It's also possible to use `EventMapping::Combined` to map a `tracing` event to multiple items in Sentry. - `ctx` in the signatures of `event_from_event`, `breadcrumb_from_event` and `log_from_event` has been changed to take `impl Into>>` to avoid cloning the `Context` when mapping to multiple items. -### Features +### Features - feat(core): emit debug log when calling capture_log but logs are disabled (#849) by @lcian diff --git a/sentry-core/src/clientoptions.rs b/sentry-core/src/clientoptions.rs index a34077880..ff4a07f95 100644 --- a/sentry-core/src/clientoptions.rs +++ b/sentry-core/src/clientoptions.rs @@ -99,8 +99,7 @@ pub struct ClientOptions { /// Enables debug mode. /// /// In debug mode debug information is printed to stderr to help you understand what - /// sentry is doing. When the `log` feature is enabled, Sentry will instead - /// log to the `sentry` logger independently of this flag with the `Debug` level. + /// sentry is doing. pub debug: bool, /// The release to be sent with events. pub release: Option>, From eadb25723d440929eac542978bac0df565cdb083 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Fri, 25 Jul 2025 11:42:33 +0200 Subject: [PATCH 119/148] feat(types): add all the missing supported envelope headers (#867) --- sentry-types/src/protocol/envelope.rs | 86 +++++++++++++++-------- sentry-types/src/protocol/v7.rs | 98 ++++++++++++++++++++++++++- sentry-types/src/utils.rs | 59 ++++++++++++++++ sentry/src/transports/thread.rs | 1 + sentry/src/transports/tokio_thread.rs | 1 + 5 files changed, 215 insertions(+), 30 deletions(-) diff --git a/sentry-types/src/protocol/envelope.rs b/sentry-types/src/protocol/envelope.rs index 190c439b2..9200fa090 100644 --- a/sentry-types/src/protocol/envelope.rs +++ b/sentry-types/src/protocol/envelope.rs @@ -1,14 +1,17 @@ -use std::{io::Write, path::Path}; +use std::{io::Write, path::Path, time::SystemTime}; use serde::{Deserialize, Serialize}; use thiserror::Error; use uuid::Uuid; +use crate::utils::ts_rfc3339_opt; +use crate::Dsn; + use super::v7 as protocol; use protocol::{ - Attachment, AttachmentType, Event, Log, MonitorCheckIn, SessionAggregates, SessionUpdate, - Transaction, + Attachment, AttachmentType, ClientSdkInfo, DynamicSamplingContext, Event, Log, MonitorCheckIn, + SessionAggregates, SessionUpdate, Transaction, }; /// Raised if a envelope cannot be parsed from a given input. @@ -37,9 +40,23 @@ pub enum EnvelopeError { InvalidItemPayload(#[source] serde_json::Error), } -#[derive(Deserialize)] -struct EnvelopeHeader { +/// The supported [Sentry Envelope Headers](https://develop.sentry.dev/sdk/data-model/envelopes/#headers). +#[derive(Clone, Default, Debug, Serialize, Deserialize, PartialEq)] +struct EnvelopeHeaders { + #[serde(default, skip_serializing_if = "Option::is_none")] event_id: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + dsn: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + sdk: Option, + #[serde( + default, + skip_serializing_if = "Option::is_none", + with = "ts_rfc3339_opt" + )] + sent_at: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + trace: Option, } /// An Envelope Item Type. @@ -271,7 +288,7 @@ impl Items { /// for more details. #[derive(Clone, Default, Debug, PartialEq)] pub struct Envelope { - event_id: Option, + headers: EnvelopeHeaders, items: Items, } @@ -297,11 +314,11 @@ impl Envelope { return; }; - if self.event_id.is_none() { + if self.headers.event_id.is_none() { if let EnvelopeItem::Event(ref event) = item { - self.event_id = Some(event.event_id); + self.headers.event_id = Some(event.event_id); } else if let EnvelopeItem::Transaction(ref transaction) = item { - self.event_id = Some(transaction.event_id); + self.headers.event_id = Some(transaction.event_id); } } items.push(item); @@ -319,7 +336,7 @@ impl Envelope { /// Returns the Envelopes Uuid, if any. pub fn uuid(&self) -> Option<&Uuid> { - self.event_id.as_ref() + self.headers.event_id.as_ref() } /// Returns the [`Event`] contained in this Envelope, if any. @@ -391,11 +408,8 @@ impl Envelope { }; // write the headers: - let event_id = self.uuid(); - match event_id { - Some(uuid) => writeln!(writer, r#"{{"event_id":"{uuid}"}}"#)?, - _ => writeln!(writer, "{{}}")?, - } + serde_json::to_writer(&mut writer, &self.headers)?; + writeln!(writer)?; let mut item_buf = Vec::new(); // write each item: @@ -466,11 +480,11 @@ impl Envelope { /// Creates a new Envelope from slice. pub fn from_slice(slice: &[u8]) -> Result { - let (header, offset) = Self::parse_header(slice)?; + let (headers, offset) = Self::parse_headers(slice)?; let items = Self::parse_items(slice, offset)?; let mut envelope = Envelope { - event_id: header.event_id, + headers, ..Default::default() }; @@ -484,8 +498,8 @@ impl Envelope { /// Creates a new raw Envelope from the given buffer. pub fn from_bytes_raw(bytes: Vec) -> Result { Ok(Self { - event_id: None, items: Items::Raw(bytes), + ..Default::default() }) } @@ -504,19 +518,19 @@ impl Envelope { Self::from_bytes_raw(bytes) } - fn parse_header(slice: &[u8]) -> Result<(EnvelopeHeader, usize), EnvelopeError> { - let mut stream = serde_json::Deserializer::from_slice(slice).into_iter(); + fn parse_headers(slice: &[u8]) -> Result<(EnvelopeHeaders, usize), EnvelopeError> { + let first_line = slice + .split(|b| *b == b'\n') + .next() + .ok_or(EnvelopeError::MissingHeader)?; - let header: EnvelopeHeader = match stream.next() { - None => return Err(EnvelopeError::MissingHeader), - Some(Err(error)) => return Err(EnvelopeError::InvalidHeader(error)), - Some(Ok(header)) => header, - }; + let headers: EnvelopeHeaders = + serde_json::from_slice(first_line).map_err(EnvelopeError::InvalidHeader)?; - // Each header is terminated by a UNIX newline. - Self::require_termination(slice, stream.byte_offset())?; + let offset = first_line.len(); + Self::require_termination(slice, offset)?; - Ok((header, stream.byte_offset() + 1)) + Ok((headers, offset + 1)) } fn parse_items(slice: &[u8], mut offset: usize) -> Result, EnvelopeError> { @@ -848,7 +862,7 @@ some content let envelope = Envelope::from_slice(bytes).unwrap(); let event_id = Uuid::from_str("9ec79c33ec9942ab8353589fcb2e04dc").unwrap(); - assert_eq!(envelope.event_id, Some(event_id)); + assert_eq!(envelope.headers.event_id, Some(event_id)); assert_eq!(envelope.items().count(), 0); } @@ -1011,6 +1025,20 @@ some content } } + #[test] + fn test_all_envelope_headers_roundtrip() { + let bytes = br#"{"event_id":"22d00b3f-d1b1-4b5d-8d20-49d138cd8a9c","sdk":{"name":"3e934135-3f2b-49bc-8756-9f025b55143e","version":"3e31738e-4106-42d0-8be2-4a3a1bc648d3","integrations":["daec50ae-8729-49b5-82f7-991446745cd5","8fc94968-3499-4a2c-b4d7-ecc058d9c1b0"],"packages":[{"name":"b59a1949-9950-4203-b394-ddd8d02c9633","version":"3d7790f3-7f32-43f7-b82f-9f5bc85205a8"}]},"sent_at":"2020-02-07T14:16:00Z","trace":{"trace_id":"65bcd18546c942069ed957b15b4ace7c","public_key":"5d593cac-f833-4845-bb23-4eabdf720da2","sample_rate":"0.00000021","sample_rand":"0.123456","sampled":"true","environment":"0666ab02-6364-4135-aa59-02e8128ce052","transaction":"0252ec25-cd0a-4230-bd2f-936a4585637e"}} +{"type":"event","length":74} +{"event_id":"22d00b3fd1b14b5d8d2049d138cd8a9c","timestamp":1595256674.296} +"#; + + let envelope = Envelope::from_slice(bytes); + assert!(envelope.is_ok()); + let envelope = envelope.unwrap(); + let serialized = to_str(envelope); + assert_eq!(bytes, serialized.as_bytes()); + } + // Test all possible item types in a single envelope #[test] fn test_deserialize_serialized() { diff --git a/sentry-types/src/protocol/v7.rs b/sentry-types/src/protocol/v7.rs index 6871d7998..945727bf6 100644 --- a/sentry-types/src/protocol/v7.rs +++ b/sentry-types/src/protocol/v7.rs @@ -22,7 +22,7 @@ use thiserror::Error; pub use url::Url; pub use uuid::Uuid; -use crate::utils::{ts_rfc3339_opt, ts_seconds_float}; +use crate::utils::{display_from_str_opt, ts_rfc3339_opt, ts_seconds_float}; pub use super::attachment::*; pub use super::envelope::*; @@ -2336,3 +2336,99 @@ impl<'de> Deserialize<'de> for LogAttribute { deserializer.deserialize_map(LogAttributeVisitor) } } + +/// An ID that identifies an organization in the Sentry backend. +#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq)] +struct OrganizationId(u64); + +impl From for OrganizationId { + fn from(value: u64) -> Self { + Self(value) + } +} + +impl std::str::FromStr for OrganizationId { + type Err = std::num::ParseIntError; + + fn from_str(s: &str) -> Result { + s.parse().map(Self) + } +} + +impl std::fmt::Display for OrganizationId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + +/// A random number generated at the start of a trace by the head of trace SDK. +#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq)] +struct SampleRand(f64); + +impl From for SampleRand { + fn from(value: f64) -> Self { + Self(value) + } +} + +impl std::str::FromStr for SampleRand { + type Err = std::num::ParseFloatError; + + fn from_str(s: &str) -> Result { + s.parse().map(Self) + } +} + +impl std::fmt::Display for SampleRand { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:.6}", self.0) + } +} + +/// The [Dynamic Sampling +/// Context](https://develop.sentry.dev/sdk/telemetry/traces/dynamic-sampling-context/). +/// +/// Sentry supports sampling at the server level through [Dynamic Sampling](https://docs.sentry.io/organization/dynamic-sampling/). +/// This feature allows users to specify target sample rates for each project via the frontend instead of requiring an application redeployment. +/// The backend needs additional information from the SDK to support these features, contained in +/// the Dynamic Sampling Context. +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +pub(crate) struct DynamicSamplingContext { + // Strictly required fields + // Still typed as optional, as when deserializing an envelope created by an older SDK they might still be missing + #[serde(default, skip_serializing_if = "Option::is_none")] + trace_id: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + public_key: Option, + #[serde( + default, + skip_serializing_if = "Option::is_none", + with = "display_from_str_opt" + )] + sample_rate: Option, + // Required fields + #[serde( + default, + skip_serializing_if = "Option::is_none", + with = "display_from_str_opt" + )] + sample_rand: Option, + #[serde( + default, + skip_serializing_if = "Option::is_none", + with = "display_from_str_opt" + )] + sampled: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + release: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + environment: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + transaction: Option, + #[serde( + default, + skip_serializing_if = "Option::is_none", + with = "display_from_str_opt" + )] + org_id: Option, +} diff --git a/sentry-types/src/utils.rs b/sentry-types/src/utils.rs index f5edfb575..83d7a6581 100644 --- a/sentry-types/src/utils.rs +++ b/sentry-types/src/utils.rs @@ -189,6 +189,65 @@ pub mod ts_rfc3339_opt { } } +/// Serialize and deserialize the inner value into/from a string using the `ToString`/`FromStr` implementation. +/// +/// # Example +/// +/// ```ignore +/// use serde::{Deserialize, Serialize}; +/// +/// #[derive(Debug, PartialEq, Serialize, Deserialize)] +/// struct Config { +/// #[serde(with = "sentry_types::utils::display_from_str_opt")] +/// host: Option, +/// #[serde(with = "sentry_types::utils::display_from_str_opt")] +/// port: Option, +/// #[serde(with = "sentry_types::utils::display_from_str_opt")] +/// enabled: Option, +/// } +/// +/// let config = Config { +/// host: Some("localhost".to_string()), +/// port: Some(8080), +/// enabled: Some(true), +/// }; +/// let json = serde_json::to_string(&config).unwrap(); +/// assert_eq!(json, r#"{"host":"localhost","port":"8080","enabled":"true"}"#); +/// +/// let deserialized: Config = serde_json::from_str(&json).unwrap(); +/// assert_eq!(deserialized, config); +/// ``` +pub(crate) mod display_from_str_opt { + use serde::{de, ser, Deserialize}; + + pub fn serialize(value: &Option, serializer: S) -> Result + where + T: ToString, + S: ser::Serializer, + { + match value { + Some(t) => serializer.serialize_str(&t.to_string()), + None => serializer.serialize_none(), + } + } + + pub fn deserialize<'de, T, D>(deserializer: D) -> Result, D::Error> + where + T: std::str::FromStr, + T::Err: std::fmt::Display, + D: de::Deserializer<'de>, + { + let opt_string = Option::::deserialize(deserializer)?; + + match opt_string { + Some(s) => T::from_str(&s) + .map(Some) + .map_err(|e| de::Error::custom(format!("failed to parse string to type: {e}"))), + None => Ok(None), + } + } +} + #[cfg(test)] mod tests { use super::timestamp_to_datetime; diff --git a/sentry/src/transports/thread.rs b/sentry/src/transports/thread.rs index 7f45990ff..45d6a0219 100644 --- a/sentry/src/transports/thread.rs +++ b/sentry/src/transports/thread.rs @@ -7,6 +7,7 @@ use std::time::Duration; use super::ratelimit::{RateLimiter, RateLimitingCategory}; use crate::{sentry_debug, Envelope}; +#[expect(clippy::large_enum_variant)] enum Task { SendEnvelope(Envelope), Flush(SyncSender<()>), diff --git a/sentry/src/transports/tokio_thread.rs b/sentry/src/transports/tokio_thread.rs index 9323e482c..21cd19043 100644 --- a/sentry/src/transports/tokio_thread.rs +++ b/sentry/src/transports/tokio_thread.rs @@ -7,6 +7,7 @@ use std::time::Duration; use super::ratelimit::{RateLimiter, RateLimitingCategory}; use crate::{sentry_debug, Envelope}; +#[expect(clippy::large_enum_variant)] enum Task { SendEnvelope(Envelope), Flush(SyncSender<()>), From 03ae06a1401616f51bbec581f47d493ebbd4dce3 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Mon, 28 Jul 2025 18:02:04 +0200 Subject: [PATCH 120/148] feat: filter username and password in URLs (#864) --- CHANGELOG.md | 7 +++++++ Cargo.lock | 1 + sentry-actix/src/lib.rs | 5 +++-- sentry-core/Cargo.toml | 1 + sentry-core/src/utils.rs | 15 +++++++++++++++ sentry-tower/src/http.rs | 4 ++-- 6 files changed, 29 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65c580e1d..38b19b3ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,13 @@ - feat(log): support kv feature of log (#851) by @lcian - Attributes added to a `log` record using the `kv` feature are now recorded as attributes on the log sent to Sentry. +### Behavioral changes + +- feat: filter username and password in URLs ([#864](https://github.com/getsentry/sentry-rust/pull/864)) by @lcian + - Usernames and passwords that could be contained in URLs captured when using the Actix Web or axum integration are now always filtered out. + - If the `Request` is created manually by the user, then these fields are not filtered out. + - This information was already filtered by Relay, but should also be filtered by the SDK itself as a first line of defense. + ### Fixes - docs: match description of `debug` option with behavior since PR #820 ([#860](https://github.com/getsentry/sentry-rust/pull/860)) by @AlexTMjugador diff --git a/Cargo.lock b/Cargo.lock index 2a13bf162..d164347d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3255,6 +3255,7 @@ dependencies = [ "serde_json", "thiserror 2.0.12", "tokio", + "url", "uuid", ] diff --git a/sentry-actix/src/lib.rs b/sentry-actix/src/lib.rs index 84a33b3b1..ede7d7497 100644 --- a/sentry-actix/src/lib.rs +++ b/sentry-actix/src/lib.rs @@ -88,7 +88,7 @@ use futures_util::future::{ok, Future, Ready}; use futures_util::{FutureExt as _, TryStreamExt as _}; use sentry_core::protocol::{self, ClientSdkPackage, Event, Request}; -use sentry_core::utils::is_sensitive_header; +use sentry_core::utils::{is_sensitive_header, scrub_pii_from_url}; use sentry_core::MaxRequestBodySize; use sentry_core::{Hub, SentryFutureExt}; @@ -428,7 +428,8 @@ fn sentry_request_from_http(request: &ServiceRequest, with_pii: bool) -> Request request.uri() ) .parse() - .ok(), + .ok() + .map(scrub_pii_from_url), method: Some(request.method().to_string()), headers: request .headers() diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index b7994cc4c..999564b5a 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -32,6 +32,7 @@ rand = { version = "0.9.0", optional = true } sentry-types = { version = "0.41.0", path = "../sentry-types" } serde = { version = "1.0.104", features = ["derive"] } serde_json = { version = "1.0.46" } +url = { version = "2.1.1" } uuid = { version = "1.0.0", features = ["v4", "serde"], optional = true } [dev-dependencies] diff --git a/sentry-core/src/utils.rs b/sentry-core/src/utils.rs index b78adba3c..8f1333fcd 100644 --- a/sentry-core/src/utils.rs +++ b/sentry-core/src/utils.rs @@ -10,8 +10,23 @@ const SENSITIVE_HEADERS_UPPERCASE: &[&str] = &[ "X_API_KEY", ]; +const PII_REPLACEMENT: &str = "[Filtered]"; + /// Determines if the HTTP header with the given name shall be considered as potentially carrying /// sensitive data. pub fn is_sensitive_header(name: &str) -> bool { SENSITIVE_HEADERS_UPPERCASE.contains(&name.to_ascii_uppercase().replace("-", "_").as_str()) } + +/// Scrub PII (username and password) from the given URL. +pub fn scrub_pii_from_url(mut url: url::Url) -> url::Url { + // the set calls will fail and return an error if the URL is relative + // in those cases, just ignore the errors + if !url.username().is_empty() { + let _ = url.set_username(PII_REPLACEMENT); + } + if url.password().is_some() { + let _ = url.set_password(Some(PII_REPLACEMENT)); + } + url +} diff --git a/sentry-tower/src/http.rs b/sentry-tower/src/http.rs index 92cc034b2..c8ff949e0 100644 --- a/sentry-tower/src/http.rs +++ b/sentry-tower/src/http.rs @@ -5,7 +5,7 @@ use std::task::{Context, Poll}; use http::{header, uri, Request, Response, StatusCode}; use pin_project::pinned_drop; -use sentry_core::utils::is_sensitive_header; +use sentry_core::utils::{is_sensitive_header, scrub_pii_from_url}; use sentry_core::{protocol, Hub}; use tower_layer::Layer; use tower_service::Service; @@ -187,7 +187,7 @@ where fn call(&mut self, request: Request) -> Self::Future { let sentry_req = sentry_core::protocol::Request { method: Some(request.method().to_string()), - url: get_url_from_request(&request), + url: get_url_from_request(&request).map(scrub_pii_from_url), headers: request .headers() .into_iter() From 611b2cdc32839d3aecf0b65736c0d086e18e4d57 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Mon, 28 Jul 2025 18:05:18 +0200 Subject: [PATCH 121/148] feat(types): add setters for envelope headers (#868) --- CHANGELOG.md | 3 + sentry-types/src/protocol/envelope.rs | 75 ++++++++++++++++- sentry-types/src/protocol/v7.rs | 116 +++++++++++++++++++++++--- sentry/src/transports/thread.rs | 6 +- sentry/src/transports/tokio_thread.rs | 6 +- 5 files changed, 191 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38b19b3ca..c12e34fab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ - feat(log): support kv feature of log (#851) by @lcian - Attributes added to a `log` record using the `kv` feature are now recorded as attributes on the log sent to Sentry. +- feat(types): add all the missing supported envelope headers ([#867](https://github.com/getsentry/sentry-rust/pull/867)) by @lcian +- feat(types): add setters for envelope headers ([#868](https://github.com/getsentry/sentry-rust/pull/868)) by @lcian + - It's now possible to set all of the [envelope headers](https://develop.sentry.dev/sdk/data-model/envelopes/#headers) supported by the protocol when constructing envelopes. ### Behavioral changes diff --git a/sentry-types/src/protocol/envelope.rs b/sentry-types/src/protocol/envelope.rs index 9200fa090..3a9bed50d 100644 --- a/sentry-types/src/protocol/envelope.rs +++ b/sentry-types/src/protocol/envelope.rs @@ -42,7 +42,7 @@ pub enum EnvelopeError { /// The supported [Sentry Envelope Headers](https://develop.sentry.dev/sdk/data-model/envelopes/#headers). #[derive(Clone, Default, Debug, Serialize, Deserialize, PartialEq)] -struct EnvelopeHeaders { +pub struct EnvelopeHeaders { #[serde(default, skip_serializing_if = "Option::is_none")] event_id: Option, #[serde(default, skip_serializing_if = "Option::is_none")] @@ -59,6 +59,49 @@ struct EnvelopeHeaders { trace: Option, } +impl EnvelopeHeaders { + /// Creates empty Envelope headers. + pub fn new() -> EnvelopeHeaders { + Default::default() + } + + /// Sets the Event ID. + #[must_use] + pub fn with_event_id(mut self, event_id: Uuid) -> Self { + self.event_id = Some(event_id); + self + } + + /// Sets the DSN. + #[must_use] + pub fn with_dsn(mut self, dsn: Dsn) -> Self { + self.dsn = Some(dsn); + self + } + + /// Sets the SDK information. + #[must_use] + pub fn with_sdk(mut self, sdk: ClientSdkInfo) -> Self { + self.sdk = Some(sdk); + self + } + + /// Sets the time this envelope was sent at. + /// This timestamp should be generated as close as possible to the transmission of the event. + #[must_use] + pub fn with_sent_at(mut self, sent_at: SystemTime) -> Self { + self.sent_at = Some(sent_at); + self + } + + /// Sets the Dynamic Sampling Context. + #[must_use] + pub fn with_trace(mut self, trace: DynamicSamplingContext) -> Self { + self.trace = Some(trace); + self + } +} + /// An Envelope Item Type. #[derive(Clone, Debug, Eq, PartialEq, Deserialize)] #[non_exhaustive] @@ -334,6 +377,18 @@ impl Envelope { EnvelopeItemIter { inner } } + /// Returns the Envelope headers. + pub fn headers(&self) -> &EnvelopeHeaders { + &self.headers + } + + /// Sets the Envelope headers. + #[must_use] + pub fn with_headers(mut self, headers: EnvelopeHeaders) -> Self { + self.headers = headers; + self + } + /// Returns the Envelopes Uuid, if any. pub fn uuid(&self) -> Option<&Uuid> { self.headers.event_id.as_ref() @@ -646,7 +701,7 @@ mod test { use super::*; use crate::protocol::v7::{ - Level, MonitorCheckInStatus, MonitorConfig, MonitorSchedule, SessionAttributes, + Level, MonitorCheckInStatus, MonitorConfig, MonitorSchedule, SampleRand, SessionAttributes, SessionStatus, Span, }; @@ -1039,6 +1094,21 @@ some content assert_eq!(bytes, serialized.as_bytes()); } + #[test] + fn test_sample_rand_rounding() { + let envelope = Envelope::new().with_headers( + EnvelopeHeaders::new().with_trace( + DynamicSamplingContext::new() + .with_sample_rand(SampleRand::try_from(0.999_999_9).unwrap()), + ), + ); + let expected = br#"{"trace":{"sample_rand":"0.999999"}} +"#; + + let serialized = to_str(envelope); + assert_eq!(expected, serialized.as_bytes()); + } + // Test all possible item types in a single envelope #[test] fn test_deserialize_serialized() { @@ -1116,7 +1186,6 @@ some content .into(); let mut envelope: Envelope = Envelope::new(); - envelope.add_item(event); envelope.add_item(transaction); envelope.add_item(session); diff --git a/sentry-types/src/protocol/v7.rs b/sentry-types/src/protocol/v7.rs index 945727bf6..ced3bd3e8 100644 --- a/sentry-types/src/protocol/v7.rs +++ b/sentry-types/src/protocol/v7.rs @@ -2339,7 +2339,7 @@ impl<'de> Deserialize<'de> for LogAttribute { /// An ID that identifies an organization in the Sentry backend. #[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq)] -struct OrganizationId(u64); +pub struct OrganizationId(u64); impl From for OrganizationId { fn from(value: u64) -> Self { @@ -2363,25 +2363,51 @@ impl std::fmt::Display for OrganizationId { /// A random number generated at the start of a trace by the head of trace SDK. #[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq)] -struct SampleRand(f64); +pub struct SampleRand(f64); -impl From for SampleRand { - fn from(value: f64) -> Self { - Self(value) +/// An error that indicates failure to construct a SampleRand. +#[derive(Debug, Error)] +pub enum InvalidSampleRandError { + /// Indicates that the given value cannot be converted to a f64 succesfully. + #[error("failed to parse f64: {0}")] + InvalidFloat(#[from] std::num::ParseFloatError), + + /// Indicates that the given float is outside of the valid range for a sample rand, that is the + /// half-open interval [0.0, 1.0). + #[error("sample rand value out of admissible interval [0.0, 1.0)")] + OutOfRange, +} + +impl TryFrom for SampleRand { + type Error = InvalidSampleRandError; + + fn try_from(value: f64) -> Result { + if !(0.0..1.0).contains(&value) { + return Err(InvalidSampleRandError::OutOfRange); + } + Ok(Self(value)) } } impl std::str::FromStr for SampleRand { - type Err = std::num::ParseFloatError; + type Err = InvalidSampleRandError; fn from_str(s: &str) -> Result { - s.parse().map(Self) + let x: f64 = s.parse().map_err(InvalidSampleRandError::InvalidFloat)?; + Self::try_from(x) } } impl std::fmt::Display for SampleRand { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:.6}", self.0) + // Special case: "{:.6}" would round values greater than or equal to 0.9999995 to 1.0, + // as Rust uses [rounding half-to-even](https://doc.rust-lang.org/std/fmt/#precision). + // Round to 0.999999 instead to comply with spec. + if self.0 >= 0.9999995 { + write!(f, "0.999999") + } else { + write!(f, "{:.6}", self.0) + } } } @@ -2392,8 +2418,8 @@ impl std::fmt::Display for SampleRand { /// This feature allows users to specify target sample rates for each project via the frontend instead of requiring an application redeployment. /// The backend needs additional information from the SDK to support these features, contained in /// the Dynamic Sampling Context. -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] -pub(crate) struct DynamicSamplingContext { +#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)] +pub struct DynamicSamplingContext { // Strictly required fields // Still typed as optional, as when deserializing an envelope created by an older SDK they might still be missing #[serde(default, skip_serializing_if = "Option::is_none")] @@ -2432,3 +2458,73 @@ pub(crate) struct DynamicSamplingContext { )] org_id: Option, } + +impl DynamicSamplingContext { + /// Creates an empty Dynamic Sampling Context. + pub fn new() -> Self { + Default::default() + } + + /// Sets the trace ID. + #[must_use] + pub fn with_trace_id(mut self, trace_id: TraceId) -> Self { + self.trace_id = Some(trace_id); + self + } + + /// Sets the DSN public key. + #[must_use] + pub fn with_public_key(mut self, public_key: String) -> Self { + self.public_key = Some(public_key); + self + } + + /// Sets the sample rate. + #[must_use] + pub fn with_sample_rate(mut self, sample_rate: f32) -> Self { + self.sample_rate = Some(sample_rate); + self + } + + /// Sets the sample random value generated by the head of trace SDK. + #[must_use] + pub fn with_sample_rand(mut self, sample_rand: SampleRand) -> Self { + self.sample_rand = Some(sample_rand); + self + } + + /// Sets the sampled flag. + #[must_use] + pub fn with_sampled(mut self, sampled: bool) -> Self { + self.sampled = Some(sampled); + self + } + + /// Sets the release. + #[must_use] + pub fn with_release(mut self, release: String) -> Self { + self.release = Some(release); + self + } + + /// Sets the environment. + #[must_use] + pub fn with_environment(mut self, environment: String) -> Self { + self.environment = Some(environment); + self + } + + /// Sets the transaction. + #[must_use] + pub fn with_transaction(mut self, transaction: String) -> Self { + self.transaction = Some(transaction); + self + } + + /// Sets the organization ID. + #[must_use] + pub fn with_org_id(mut self, org_id: OrganizationId) -> Self { + self.org_id = Some(org_id); + self + } +} diff --git a/sentry/src/transports/thread.rs b/sentry/src/transports/thread.rs index 45d6a0219..6ccca6fae 100644 --- a/sentry/src/transports/thread.rs +++ b/sentry/src/transports/thread.rs @@ -7,7 +7,11 @@ use std::time::Duration; use super::ratelimit::{RateLimiter, RateLimitingCategory}; use crate::{sentry_debug, Envelope}; -#[expect(clippy::large_enum_variant)] +#[expect( + clippy::large_enum_variant, + reason = "In normal usage this is usually SendEnvelope, the other variants are only used when \ + the user manually calls transport.flush() or when the transport is shut down." +)] enum Task { SendEnvelope(Envelope), Flush(SyncSender<()>), diff --git a/sentry/src/transports/tokio_thread.rs b/sentry/src/transports/tokio_thread.rs index 21cd19043..5ef734e31 100644 --- a/sentry/src/transports/tokio_thread.rs +++ b/sentry/src/transports/tokio_thread.rs @@ -7,7 +7,11 @@ use std::time::Duration; use super::ratelimit::{RateLimiter, RateLimitingCategory}; use crate::{sentry_debug, Envelope}; -#[expect(clippy::large_enum_variant)] +#[expect( + clippy::large_enum_variant, + reason = "In normal usage this is usually SendEnvelope, the other variants are only used when \ + the user manually calls transport.flush() or when the transport is shut down." +)] enum Task { SendEnvelope(Envelope), Flush(SyncSender<()>), From a42596252f404f6ee4f1615225777614074c0374 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Mon, 28 Jul 2025 18:14:46 +0200 Subject: [PATCH 122/148] feat(core): add some DSC fields to transaction envelope headers (#869) --- CHANGELOG.md | 2 ++ sentry-core/src/performance.rs | 48 ++++++++++++++++++++++++++-------- sentry/tests/test_basic.rs | 42 +++++++++++++++++++++++++++-- 3 files changed, 79 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c12e34fab..2be06572a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ - feat(types): add all the missing supported envelope headers ([#867](https://github.com/getsentry/sentry-rust/pull/867)) by @lcian - feat(types): add setters for envelope headers ([#868](https://github.com/getsentry/sentry-rust/pull/868)) by @lcian - It's now possible to set all of the [envelope headers](https://develop.sentry.dev/sdk/data-model/envelopes/#headers) supported by the protocol when constructing envelopes. +- feat(core): add some DSC fields to transaction envelope headers ([#869](https://github.com/getsentry/sentry-rust/pull/869)) by @lcian + - The SDK now sends additional envelope headers with transactions. This should solve some extrapolation issues for span metrics. ### Behavioral changes diff --git a/sentry-core/src/performance.rs b/sentry-core/src/performance.rs index 10c98ac1d..18a96d1f3 100644 --- a/sentry-core/src/performance.rs +++ b/sentry-core/src/performance.rs @@ -594,26 +594,33 @@ fn transaction_sample_rate( ) -> f32 { match (traces_sampler, traces_sample_rate) { (Some(traces_sampler), _) => traces_sampler(ctx), - (None, traces_sample_rate) => ctx - .sampled - .map(|sampled| if sampled { 1.0 } else { 0.0 }) - .unwrap_or(traces_sample_rate), + (None, traces_sample_rate) => ctx.sampled.map(f32::from).unwrap_or(traces_sample_rate), } } /// Determine whether the new transaction should be sampled. #[cfg(feature = "client")] impl Client { - fn is_transaction_sampled(&self, ctx: &TransactionContext) -> bool { + fn determine_sampling_decision(&self, ctx: &TransactionContext) -> (bool, f32) { let client_options = self.options(); - self.sample_should_send(transaction_sample_rate( + let sample_rate = transaction_sample_rate( client_options.traces_sampler.as_deref(), ctx, client_options.traces_sample_rate, - )) + ); + let sampled = self.sample_should_send(sample_rate); + (sampled, sample_rate) } } +/// Some metadata associated with a transaction. +#[cfg(feature = "client")] +#[derive(Clone, Debug)] +struct TransactionMetadata { + /// The sample rate used when making the sampling decision for the associated transaction. + sample_rate: f32, +} + /// A running Performance Monitoring Transaction. /// /// The transaction needs to be explicitly finished via [`Transaction::finish`], @@ -622,6 +629,8 @@ impl Client { #[derive(Clone, Debug)] pub struct Transaction { pub(crate) inner: TransactionArc, + #[cfg(feature = "client")] + metadata: TransactionMetadata, } /// Iterable for a transaction's [data attributes](protocol::TraceContext::data). @@ -660,15 +669,21 @@ impl<'a> TransactionData<'a> { impl Transaction { #[cfg(feature = "client")] fn new(client: Option>, ctx: TransactionContext) -> Self { - let (sampled, transaction) = match client.as_ref() { + let ((sampled, sample_rate), transaction) = match client.as_ref() { Some(client) => ( - client.is_transaction_sampled(&ctx), + client.determine_sampling_decision(&ctx), Some(protocol::Transaction { name: Some(ctx.name), ..Default::default() }), ), - None => (ctx.sampled.unwrap_or(false), None), + None => ( + ( + ctx.sampled.unwrap_or(false), + ctx.sampled.map_or(0.0, f32::from), + ), + None, + ), }; let context = protocol::TraceContext { @@ -686,6 +701,7 @@ impl Transaction { context, transaction, })), + metadata: TransactionMetadata { sample_rate }, } } @@ -820,9 +836,19 @@ impl Transaction { transaction.sdk = Some(std::borrow::Cow::Owned(client.sdk_info.clone())); transaction.server_name.clone_from(&opts.server_name); + let mut dsc = protocol::DynamicSamplingContext::new() + .with_trace_id(inner.context.trace_id) + .with_sample_rate(self.metadata.sample_rate) + .with_sampled(inner.sampled); + if let Some(public_key) = client.dsn().map(|dsn| dsn.public_key()) { + dsc = dsc.with_public_key(public_key.to_owned()); + } + drop(inner); - let mut envelope = protocol::Envelope::new(); + let mut envelope = protocol::Envelope::new().with_headers( + protocol::EnvelopeHeaders::new().with_trace(dsc) + ); envelope.add_item(transaction); client.send_envelope(envelope) diff --git a/sentry/tests/test_basic.rs b/sentry/tests/test_basic.rs index 8f5f4d0bc..21cb98ab3 100644 --- a/sentry/tests/test_basic.rs +++ b/sentry/tests/test_basic.rs @@ -3,8 +3,10 @@ use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; -use sentry::protocol::{Attachment, Context, EnvelopeItem}; -use sentry::types::Uuid; +use sentry::protocol::{ + Attachment, Context, DynamicSamplingContext, EnvelopeHeaders, EnvelopeItem, +}; +use sentry::types::{Dsn, Uuid}; #[test] fn test_basic_capture_message() { @@ -578,3 +580,39 @@ fn test_basic_capture_log_macro_message_formatted_with_attributes() { _ => panic!("expected item container"), } } + +#[test] +fn test_transaction_envelope_dsc_headers() { + let mut trace_id: Option = None; + let dsn: Option = "http://foo@example.com/42".parse().ok(); + let envelopes = sentry::test::with_captured_envelopes_options( + || { + let transaction_ctx = sentry::TransactionContext::new("name transaction", "op"); + trace_id = Some(transaction_ctx.trace_id()); + let transaction = sentry::start_transaction(transaction_ctx); + sentry::configure_scope(|scope| scope.set_span(Some(transaction.clone().into()))); + transaction.finish(); + }, + sentry::ClientOptions { + dsn: dsn.clone(), + traces_sample_rate: 1.0, + ..Default::default() + }, + ); + + assert!(trace_id.is_some()); + let trace_id = trace_id.unwrap(); + assert_eq!(envelopes.len(), 1); + let envelope = envelopes.into_iter().next().unwrap(); + assert!(envelope.uuid().is_some()); + let uuid = envelope.uuid().copied().unwrap(); + + let expected = EnvelopeHeaders::new().with_event_id(uuid).with_trace( + DynamicSamplingContext::new() + .with_trace_id(trace_id) + .with_public_key(dsn.unwrap().public_key().to_owned()) + .with_sample_rate(1.0) + .with_sampled(true), + ); + assert_eq!(envelope.headers(), &expected); +} From 1936fd7638532d09ee4fdd6029abdc763199d0c2 Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Tue, 29 Jul 2025 08:15:04 +0000 Subject: [PATCH 123/148] release: 0.42.0 --- CHANGELOG.md | 2 +- Cargo.lock | 28 ++++++++++++++-------------- sentry-actix/Cargo.toml | 4 ++-- sentry-anyhow/Cargo.toml | 6 +++--- sentry-backtrace/Cargo.toml | 4 ++-- sentry-contexts/Cargo.toml | 4 ++-- sentry-core/Cargo.toml | 4 ++-- sentry-core/README.md | 2 +- sentry-debug-images/Cargo.toml | 4 ++-- sentry-debug-images/README.md | 2 +- sentry-log/Cargo.toml | 4 ++-- sentry-opentelemetry/Cargo.toml | 4 ++-- sentry-panic/Cargo.toml | 6 +++--- sentry-slog/Cargo.toml | 4 ++-- sentry-tower/Cargo.toml | 4 ++-- sentry-tower/README.md | 2 +- sentry-tracing/Cargo.toml | 6 +++--- sentry-tracing/README.md | 2 +- sentry-types/Cargo.toml | 2 +- sentry/Cargo.toml | 26 +++++++++++++------------- sentry/README.md | 12 ++++++------ 21 files changed, 66 insertions(+), 66 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2be06572a..c8e9b12d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 0.42.0 ### Features diff --git a/Cargo.lock b/Cargo.lock index d164347d5..fa575e93c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3159,7 +3159,7 @@ dependencies = [ [[package]] name = "sentry" -version = "0.41.0" +version = "0.42.0" dependencies = [ "actix-web", "anyhow", @@ -3195,7 +3195,7 @@ dependencies = [ [[package]] name = "sentry-actix" -version = "0.41.0" +version = "0.42.0" dependencies = [ "actix-http", "actix-web", @@ -3209,7 +3209,7 @@ dependencies = [ [[package]] name = "sentry-anyhow" -version = "0.41.0" +version = "0.42.0" dependencies = [ "anyhow", "sentry", @@ -3219,7 +3219,7 @@ dependencies = [ [[package]] name = "sentry-backtrace" -version = "0.41.0" +version = "0.42.0" dependencies = [ "backtrace", "regex", @@ -3228,7 +3228,7 @@ dependencies = [ [[package]] name = "sentry-contexts" -version = "0.41.0" +version = "0.42.0" dependencies = [ "hostname", "libc", @@ -3241,7 +3241,7 @@ dependencies = [ [[package]] name = "sentry-core" -version = "0.41.0" +version = "0.42.0" dependencies = [ "anyhow", "criterion", @@ -3261,7 +3261,7 @@ dependencies = [ [[package]] name = "sentry-debug-images" -version = "0.41.0" +version = "0.42.0" dependencies = [ "findshlibs", "sentry-core", @@ -3269,7 +3269,7 @@ dependencies = [ [[package]] name = "sentry-log" -version = "0.41.0" +version = "0.42.0" dependencies = [ "log", "pretty_env_logger", @@ -3279,7 +3279,7 @@ dependencies = [ [[package]] name = "sentry-opentelemetry" -version = "0.41.0" +version = "0.42.0" dependencies = [ "opentelemetry", "opentelemetry_sdk", @@ -3289,7 +3289,7 @@ dependencies = [ [[package]] name = "sentry-panic" -version = "0.41.0" +version = "0.42.0" dependencies = [ "sentry", "sentry-backtrace", @@ -3298,7 +3298,7 @@ dependencies = [ [[package]] name = "sentry-slog" -version = "0.41.0" +version = "0.42.0" dependencies = [ "erased-serde", "sentry", @@ -3310,7 +3310,7 @@ dependencies = [ [[package]] name = "sentry-tower" -version = "0.41.0" +version = "0.42.0" dependencies = [ "anyhow", "axum 0.8.3", @@ -3330,7 +3330,7 @@ dependencies = [ [[package]] name = "sentry-tracing" -version = "0.41.0" +version = "0.42.0" dependencies = [ "bitflags 2.9.1", "log", @@ -3346,7 +3346,7 @@ dependencies = [ [[package]] name = "sentry-types" -version = "0.41.0" +version = "0.42.0" dependencies = [ "debugid", "hex", diff --git a/sentry-actix/Cargo.toml b/sentry-actix/Cargo.toml index 84ae04fb9..b817e5e73 100644 --- a/sentry-actix/Cargo.toml +++ b/sentry-actix/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-actix" -version = "0.41.0" +version = "0.42.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -20,7 +20,7 @@ release-health = ["sentry-core/release-health"] actix-web = { version = "4", default-features = false } bytes = "1.2" futures-util = { version = "0.3.5", default-features = false } -sentry-core = { version = "0.41.0", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.42.0", path = "../sentry-core", default-features = false, features = [ "client", ] } actix-http = "3.10" diff --git a/sentry-anyhow/Cargo.toml b/sentry-anyhow/Cargo.toml index 66cf0bfb6..204696124 100644 --- a/sentry-anyhow/Cargo.toml +++ b/sentry-anyhow/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-anyhow" -version = "0.41.0" +version = "0.42.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -17,8 +17,8 @@ default = ["backtrace"] backtrace = [] [dependencies] -sentry-backtrace = { version = "0.41.0", path = "../sentry-backtrace" } -sentry-core = { version = "0.41.0", path = "../sentry-core" } +sentry-backtrace = { version = "0.42.0", path = "../sentry-backtrace" } +sentry-core = { version = "0.42.0", path = "../sentry-core" } anyhow = "1.0.77" [dev-dependencies] diff --git a/sentry-backtrace/Cargo.toml b/sentry-backtrace/Cargo.toml index 2de5bba13..3661e7016 100644 --- a/sentry-backtrace/Cargo.toml +++ b/sentry-backtrace/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-backtrace" -version = "0.41.0" +version = "0.42.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -18,4 +18,4 @@ regex = { version = "1.5.5", default-features = false, features = [ "std", "unicode-perl", ] } -sentry-core = { version = "0.41.0", path = "../sentry-core" } +sentry-core = { version = "0.42.0", path = "../sentry-core" } diff --git a/sentry-contexts/Cargo.toml b/sentry-contexts/Cargo.toml index 673b143d1..64ea2a6bf 100644 --- a/sentry-contexts/Cargo.toml +++ b/sentry-contexts/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-contexts" -version = "0.41.0" +version = "0.42.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -14,7 +14,7 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.41.0", path = "../sentry-core" } +sentry-core = { version = "0.42.0", path = "../sentry-core" } libc = "0.2.66" hostname = "0.4" diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index 999564b5a..c97f9d004 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-core" -version = "0.41.0" +version = "0.42.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -29,7 +29,7 @@ logs = [] [dependencies] log = { version = "0.4.8", optional = true, features = ["std"] } rand = { version = "0.9.0", optional = true } -sentry-types = { version = "0.41.0", path = "../sentry-types" } +sentry-types = { version = "0.42.0", path = "../sentry-types" } serde = { version = "1.0.104", features = ["derive"] } serde_json = { version = "1.0.46" } url = { version = "2.1.1" } diff --git a/sentry-core/README.md b/sentry-core/README.md index 5dfbf4084..720149b1f 100644 --- a/sentry-core/README.md +++ b/sentry-core/README.md @@ -99,7 +99,7 @@ functionality. [Sentry]: https://sentry.io/ [`sentry`]: https://crates.io/crates/sentry [Unified API]: https://develop.sentry.dev/sdk/unified-api/ -[`test`]: https://docs.rs/sentry-core/0.41.0/sentry_core/test/index.html +[`test`]: https://docs.rs/sentry-core/0.42.0/sentry_core/test/index.html ## Resources diff --git a/sentry-debug-images/Cargo.toml b/sentry-debug-images/Cargo.toml index 8ef8cea64..8f8a27971 100644 --- a/sentry-debug-images/Cargo.toml +++ b/sentry-debug-images/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-debug-images" -version = "0.41.0" +version = "0.42.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -14,4 +14,4 @@ rust-version = "1.81" [dependencies] findshlibs = "=0.10.2" -sentry-core = { version = "0.41.0", path = "../sentry-core" } +sentry-core = { version = "0.42.0", path = "../sentry-core" } diff --git a/sentry-debug-images/README.md b/sentry-debug-images/README.md index 7d57f4baa..ee41563a4 100644 --- a/sentry-debug-images/README.md +++ b/sentry-debug-images/README.md @@ -22,7 +22,7 @@ let integration = sentry_debug_images::DebugImagesIntegration::new() .filter(|event| event.level >= Level::Warning); ``` -[`Event`]: https://docs.rs/sentry-debug-images/0.41.0/sentry_debug_images/sentry_core::protocol::Event +[`Event`]: https://docs.rs/sentry-debug-images/0.42.0/sentry_debug_images/sentry_core::protocol::Event ## Resources diff --git a/sentry-log/Cargo.toml b/sentry-log/Cargo.toml index 6df10711b..049d6951a 100644 --- a/sentry-log/Cargo.toml +++ b/sentry-log/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-log" -version = "0.41.0" +version = "0.42.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -17,7 +17,7 @@ default = [] logs = ["sentry-core/logs"] [dependencies] -sentry-core = { version = "0.41.0", path = "../sentry-core" } +sentry-core = { version = "0.42.0", path = "../sentry-core" } log = { version = "0.4.8", features = ["std", "kv"] } [dev-dependencies] diff --git a/sentry-opentelemetry/Cargo.toml b/sentry-opentelemetry/Cargo.toml index d9bce4410..7d8b84d49 100644 --- a/sentry-opentelemetry/Cargo.toml +++ b/sentry-opentelemetry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-opentelemetry" -version = "0.41.0" +version = "0.42.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -16,7 +16,7 @@ rust-version = "1.81" all-features = true [dependencies] -sentry-core = { version = "0.41.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.42.0", path = "../sentry-core", features = [ "client", ] } opentelemetry = { version = "0.29.0", default-features = false } diff --git a/sentry-panic/Cargo.toml b/sentry-panic/Cargo.toml index e44e3b7f6..a4080c504 100644 --- a/sentry-panic/Cargo.toml +++ b/sentry-panic/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-panic" -version = "0.41.0" +version = "0.42.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -13,8 +13,8 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.41.0", path = "../sentry-core" } -sentry-backtrace = { version = "0.41.0", path = "../sentry-backtrace" } +sentry-core = { version = "0.42.0", path = "../sentry-core" } +sentry-backtrace = { version = "0.42.0", path = "../sentry-backtrace" } [dev-dependencies] sentry = { path = "../sentry", default-features = false, features = ["test"] } diff --git a/sentry-slog/Cargo.toml b/sentry-slog/Cargo.toml index 7043bf165..f78bec304 100644 --- a/sentry-slog/Cargo.toml +++ b/sentry-slog/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-slog" -version = "0.41.0" +version = "0.42.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.41.0", path = "../sentry-core" } +sentry-core = { version = "0.42.0", path = "../sentry-core" } slog = { version = "2.5.2", features = ["nested-values"] } serde_json = "1.0.46" diff --git a/sentry-tower/Cargo.toml b/sentry-tower/Cargo.toml index 10fb801bd..1fc8ab10d 100644 --- a/sentry-tower/Cargo.toml +++ b/sentry-tower/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tower" -version = "0.41.0" +version = "0.42.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -26,7 +26,7 @@ tower-layer = "0.3" tower-service = "0.3" http = { version = "1.0.0", optional = true } pin-project = { version = "1.0.10", optional = true } -sentry-core = { version = "0.41.0", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.42.0", path = "../sentry-core", default-features = false, features = [ "client", ] } url = { version = "2.2.2", optional = true } diff --git a/sentry-tower/README.md b/sentry-tower/README.md index 20a82831e..6cf8c2aa4 100644 --- a/sentry-tower/README.md +++ b/sentry-tower/README.md @@ -103,7 +103,7 @@ feature of the `sentry` crate instead of the `tower` feature. The created transaction will automatically use the request URI as its name. This is sometimes not desirable in case the request URI contains unique IDs or similar. In this case, users should manually override the transaction name -in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.41.0/sentry_tower/sentry_core::Scope::set_transaction) +in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.42.0/sentry_tower/sentry_core::Scope::set_transaction) method. When combining both layers, take care of the ordering of both. For example diff --git a/sentry-tracing/Cargo.toml b/sentry-tracing/Cargo.toml index 8e12dc88f..51751345b 100644 --- a/sentry-tracing/Cargo.toml +++ b/sentry-tracing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tracing" -version = "0.41.0" +version = "0.42.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -21,14 +21,14 @@ backtrace = ["dep:sentry-backtrace"] logs = ["sentry-core/logs"] [dependencies] -sentry-core = { version = "0.41.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.42.0", path = "../sentry-core", features = [ "client", ] } tracing-core = "0.1" tracing-subscriber = { version = "0.3.1", default-features = false, features = [ "std", ] } -sentry-backtrace = { version = "0.41.0", path = "../sentry-backtrace", optional = true } +sentry-backtrace = { version = "0.42.0", path = "../sentry-backtrace", optional = true } bitflags = "2.0.0" [dev-dependencies] diff --git a/sentry-tracing/README.md b/sentry-tracing/README.md index 121f1711e..fcd9206ed 100644 --- a/sentry-tracing/README.md +++ b/sentry-tracing/README.md @@ -121,7 +121,7 @@ tracing::error!( ); ``` -To track [error structs](https://docs.rs/sentry-tracing/0.41.0/sentry_tracing/std::error::Error), assign a reference to error trait object as field +To track [error structs](https://docs.rs/sentry-tracing/0.42.0/sentry_tracing/std::error::Error), assign a reference to error trait object as field in one of the logging macros. By convention, it is recommended to use the `ERROR` level and assign it to a field called `error`, although the integration will also work with all other levels and field names. diff --git a/sentry-types/Cargo.toml b/sentry-types/Cargo.toml index 0d8eef039..14c5162cb 100644 --- a/sentry-types/Cargo.toml +++ b/sentry-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-types" -version = "0.41.0" +version = "0.42.0" authors = ["Sentry "] license = "MIT" readme = "README.md" diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index 9a43eed10..4974a7cee 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry" -version = "0.41.0" +version = "0.42.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -60,20 +60,20 @@ rustls = ["dep:rustls", "reqwest?/rustls-tls", "ureq?/rustls"] embedded-svc-http = ["dep:embedded-svc", "dep:esp-idf-svc"] [dependencies] -sentry-core = { version = "0.41.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.42.0", path = "../sentry-core", features = [ "client", ] } -sentry-anyhow = { version = "0.41.0", path = "../sentry-anyhow", optional = true } -sentry-actix = { version = "0.41.0", path = "../sentry-actix", optional = true, default-features = false } -sentry-backtrace = { version = "0.41.0", path = "../sentry-backtrace", optional = true } -sentry-contexts = { version = "0.41.0", path = "../sentry-contexts", optional = true } -sentry-debug-images = { version = "0.41.0", path = "../sentry-debug-images", optional = true } -sentry-log = { version = "0.41.0", path = "../sentry-log", optional = true } -sentry-panic = { version = "0.41.0", path = "../sentry-panic", optional = true } -sentry-slog = { version = "0.41.0", path = "../sentry-slog", optional = true } -sentry-tower = { version = "0.41.0", path = "../sentry-tower", optional = true } -sentry-tracing = { version = "0.41.0", path = "../sentry-tracing", optional = true } -sentry-opentelemetry = { version = "0.41.0", path = "../sentry-opentelemetry", optional = true } +sentry-anyhow = { version = "0.42.0", path = "../sentry-anyhow", optional = true } +sentry-actix = { version = "0.42.0", path = "../sentry-actix", optional = true, default-features = false } +sentry-backtrace = { version = "0.42.0", path = "../sentry-backtrace", optional = true } +sentry-contexts = { version = "0.42.0", path = "../sentry-contexts", optional = true } +sentry-debug-images = { version = "0.42.0", path = "../sentry-debug-images", optional = true } +sentry-log = { version = "0.42.0", path = "../sentry-log", optional = true } +sentry-panic = { version = "0.42.0", path = "../sentry-panic", optional = true } +sentry-slog = { version = "0.42.0", path = "../sentry-slog", optional = true } +sentry-tower = { version = "0.42.0", path = "../sentry-tower", optional = true } +sentry-tracing = { version = "0.42.0", path = "../sentry-tracing", optional = true } +sentry-opentelemetry = { version = "0.42.0", path = "../sentry-opentelemetry", optional = true } reqwest = { version = "0.12", optional = true, features = [ "blocking", "json", diff --git a/sentry/README.md b/sentry/README.md index b2f4475e9..fb5060077 100644 --- a/sentry/README.md +++ b/sentry/README.md @@ -34,8 +34,8 @@ sentry::capture_message("Hello World!", sentry::Level::Info); More complex examples on how to use sentry can also be found in [examples]. Extended instructions may also be found on [Sentry itself]. -[`sentry::init`]: https://docs.rs/sentry/0.41.0/sentry/fn.init.html -[`Hub`]: https://docs.rs/sentry/0.41.0/sentry/struct.Hub.html +[`sentry::init`]: https://docs.rs/sentry/0.42.0/sentry/fn.init.html +[`Hub`]: https://docs.rs/sentry/0.42.0/sentry/struct.Hub.html [examples]: https://github.com/getsentry/sentry-rust/tree/master/sentry/examples [Sentry itself]: https://docs.sentry.io/platforms/rust @@ -47,8 +47,8 @@ the ecosystem require a feature flag. For available integrations and how to use [integrations] and [apply_defaults]. [Features]: #features -[integrations]: https://docs.rs/sentry/0.41.0/sentry/integrations/index.html -[apply_defaults]: https://docs.rs/sentry/0.41.0/sentry/fn.apply_defaults.html +[integrations]: https://docs.rs/sentry/0.42.0/sentry/integrations/index.html +[apply_defaults]: https://docs.rs/sentry/0.42.0/sentry/fn.apply_defaults.html ## Minimal API @@ -56,8 +56,8 @@ This crate comes fully-featured. If the goal is to instrument libraries for usag with sentry, or to extend sentry with a custom [`Integration`] or a [`Transport`], one should use the [`sentry-core`] crate instead. -[`Integration`]: https://docs.rs/sentry/0.41.0/sentry/trait.Integration.html -[`Transport`]: https://docs.rs/sentry/0.41.0/sentry/trait.Transport.html +[`Integration`]: https://docs.rs/sentry/0.42.0/sentry/trait.Integration.html +[`Transport`]: https://docs.rs/sentry/0.42.0/sentry/trait.Transport.html [`sentry-core`]: https://crates.io/crates/sentry-core From 9df38167d50b93a4c4cd7a990ae4d871c40d7ad3 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Mon, 4 Aug 2025 13:38:06 +0200 Subject: [PATCH 124/148] docs(tower): suggest reordering layers when using axum (#881) --- sentry-tower/src/lib.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sentry-tower/src/lib.rs b/sentry-tower/src/lib.rs index a97c068c9..cdfe998ed 100644 --- a/sentry-tower/src/lib.rs +++ b/sentry-tower/src/lib.rs @@ -130,6 +130,19 @@ //! # } //! ``` //! +//! When using `axum`, either use [`tower::ServiceBuilder`] as shown above, or make sure you +//! reorder the layers, like so: +//! +//! ```rust +//! let app = Router::new() +//! .route("/", get(handler)) +//! .layer(sentry_tower::SentryHttpLayer::with_transaction()) +//! .layer(sentry_tower::NewSentryLayer::::new_from_top()) +//! ``` +//! +//! This is because `axum` applies middleware in the opposite order as [`tower::ServiceBuilder`]. +//! Applying the layers in the wrong order can result in memory leaks. +//! //! [`tower::ServiceBuilder`]: https://docs.rs/tower/latest/tower/struct.ServiceBuilder.html #![doc(html_favicon_url = "https://sentry-brand.storage.googleapis.com/favicon.ico")] From 0336a02c7f251519c7b6d3f7de2abaa4389bfe73 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Mon, 4 Aug 2025 18:02:19 +0200 Subject: [PATCH 125/148] feat(types): add Response context (#874) --- CHANGELOG.md | 21 +++++++++++++++ sentry-types/src/protocol/v7.rs | 29 +++++++++++++++++++- sentry-types/tests/test_protocol_v7.rs | 37 ++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8e9b12d0..dedcc18d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,26 @@ # Changelog +## Unreleased + +## Features + +- feat(core): add Response context ([#874](https://github.com/getsentry/sentry-rust/pull/874)) by @lcian + - The `Response` context can now be attached to events, to include information about HTTP responses such as headers, cookies and status code. + - Example: + ```rust + let mut event = Event::new(); + let response = ResponseContext { + cookies: Some(r#""csrftoken": "1234567""#.to_owned()), + headers: Some(headers_map), + status_code: Some(500), + body_size: Some(15), + data: Some("Invalid request"), + }; + event + .contexts + .insert("response".to_owned(), response.into()); + ``` + ## 0.42.0 ### Features diff --git a/sentry-types/src/protocol/v7.rs b/sentry-types/src/protocol/v7.rs index ced3bd3e8..617fd5e82 100644 --- a/sentry-types/src/protocol/v7.rs +++ b/sentry-types/src/protocol/v7.rs @@ -1100,6 +1100,8 @@ pub enum Context { Gpu(Box), /// OpenTelemetry data. Otel(Box), + /// HTTP response data. + Response(Box), /// Generic other context data. #[serde(rename = "unknown")] Other(Map), @@ -1117,6 +1119,7 @@ impl Context { Context::Trace(..) => "trace", Context::Gpu(..) => "gpu", Context::Otel(..) => "otel", + Context::Response(..) => "response", Context::Other(..) => "unknown", } } @@ -1351,6 +1354,29 @@ pub struct OtelContext { pub other: Map, } +/// Holds information about an HTTP response. +#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)] +pub struct ResponseContext { + /// The unparsed cookie values. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cookies: Option, + /// A map of submitted headers. + /// + /// If a header appears multiple times, it needs to be merged according to the HTTP standard + /// for header merging. Header names are treated case-insensitively by Sentry. + #[serde(default, skip_serializing_if = "Map::is_empty")] + pub headers: Map, + /// The HTTP response status code. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub status_code: Option, + /// The response body size in bytes. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub body_size: Option, + /// Response data in any format that makes sense. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub data: Option, +} + /// Holds the identifier for a Span #[derive(Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Hash)] #[serde(try_from = "String", into = "String")] @@ -1501,9 +1527,10 @@ into_context!(Browser, BrowserContext); into_context!(Trace, TraceContext); into_context!(Gpu, GpuContext); into_context!(Otel, OtelContext); +into_context!(Response, ResponseContext); const INFERABLE_CONTEXTS: &[&str] = &[ - "device", "os", "runtime", "app", "browser", "trace", "gpu", "otel", + "device", "os", "runtime", "app", "browser", "trace", "gpu", "otel", "response", ]; struct ContextsVisitor; diff --git a/sentry-types/tests/test_protocol_v7.rs b/sentry-types/tests/test_protocol_v7.rs index 5638d3141..841cf19d1 100644 --- a/sentry-types/tests/test_protocol_v7.rs +++ b/sentry-types/tests/test_protocol_v7.rs @@ -1313,6 +1313,43 @@ mod test_contexts { ); } + #[test] + fn test_response_context() { + let event = v7::Event { + event_id: event_id(), + timestamp: event_time(), + contexts: { + let mut m = v7::Map::new(); + m.insert( + "response".into(), + v7::ResponseContext { + status_code: Some(400), + cookies: Some("sessionId=abc123; Path=/; HttpOnly,authToken=xyz789; Secure; SameSite=Strict".into()), + headers: { + let mut hm = v7::Map::new(); + hm.insert("Content-Type".into(), "text/plain".into()); + hm + }, + body_size: Some(1000), + data: Some("lol".into()), + } + .into(), + ); + m + }, + ..Default::default() + }; + + assert_roundtrip(&event); + assert_eq!( + serde_json::to_string(&event).unwrap(), + "{\"event_id\":\"d43e86c96e424a93a4fbda156dd17341\",\"timestamp\":1514103120,\ + \"contexts\":{\"response\":{\"type\":\"response\",\ + \"cookies\":\"sessionId=abc123; Path=/; HttpOnly,authToken=xyz789; Secure; SameSite=Strict\",\ + \"headers\":{\"Content-Type\":\"text/plain\"},\"status_code\":400,\"body_size\":1000,\"data\":\"lol\"}}}" + ); + } + #[test] fn test_renamed_contexts() { let event = v7::Event { From c29c01f6a15c9c8b684ede9686ed14179112c2a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Janou=C5=A1ek?= Date: Wed, 6 Aug 2025 10:58:57 +0200 Subject: [PATCH 126/148] build(panic): Fix build without other dependencies (#883) Co-authored-by: lcian --- CHANGELOG.md | 7 ++++++- sentry-panic/Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dedcc18d9..03acbefec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## Unreleased -## Features +### Features - feat(core): add Response context ([#874](https://github.com/getsentry/sentry-rust/pull/874)) by @lcian - The `Response` context can now be attached to events, to include information about HTTP responses such as headers, cookies and status code. @@ -21,6 +21,11 @@ .insert("response".to_owned(), response.into()); ``` +### Fixes + +- build(panic): Fix build without other dependencies ([#883](https://github.com/getsentry/sentry-rust/pull/883)) by @liskin + - The `sentry-panic` crate now builds successfully when used as a standalone dependency. + ## 0.42.0 ### Features diff --git a/sentry-panic/Cargo.toml b/sentry-panic/Cargo.toml index a4080c504..964fe7265 100644 --- a/sentry-panic/Cargo.toml +++ b/sentry-panic/Cargo.toml @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.42.0", path = "../sentry-core" } +sentry-core = { version = "0.42.0", path = "../sentry-core", features = ["client"] } sentry-backtrace = { version = "0.42.0", path = "../sentry-backtrace" } [dev-dependencies] From cd933d3e55cbabf6927f7813d290cde95dd3ceb6 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Wed, 6 Aug 2025 14:50:14 +0200 Subject: [PATCH 127/148] fix(actix): capture only server errors (#877) --- CHANGELOG.md | 8 +++++ sentry-actix/src/lib.rs | 69 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 74 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 03acbefec..3f6d89558 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ ## Unreleased +### Breaking changes + +- fix(actix): capture only server errors ([#877](https://github.com/getsentry/sentry-rust/pull/877)) + - The Actix integration now properly honors the `capture_server_errors` option (enabled by default), capturing errors returned by middleware only if they are server errors (HTTP status code 5xx). + - Previously, if a middleware were to process the request after the Sentry middleware and return an error, our middleware would always capture it and send it to Sentry, regardless if it was a client, server or some other kind of error. + - With this change, we capture errors returned by middleware only if those errors can be classified as server errors. + - There is no change in behavior when it comes to errors returned by services, in which case the Sentry middleware only captures server errors exclusively. + ### Features - feat(core): add Response context ([#874](https://github.com/getsentry/sentry-rust/pull/874)) by @lcian diff --git a/sentry-actix/src/lib.rs b/sentry-actix/src/lib.rs index ede7d7497..19fa4394f 100644 --- a/sentry-actix/src/lib.rs +++ b/sentry-actix/src/lib.rs @@ -351,7 +351,9 @@ where let mut res: Self::Response = match fut.await { Ok(res) => res, Err(e) => { - if inner.capture_server_errors { + // Errors returned by middleware, and possibly other lower level errors + if inner.capture_server_errors && e.error_response().status().is_server_error() + { hub.capture_error(&e); } @@ -474,6 +476,7 @@ fn process_event(mut event: Event<'static>, request: &Request) -> Event<'static> mod tests { use std::io; + use actix_web::body::BoxBody; use actix_web::test::{call_service, init_service, TestRequest}; use actix_web::{get, web, App, HttpRequest, HttpResponse}; use futures::executor::block_on; @@ -622,9 +625,9 @@ mod tests { } } - /// Ensures client errors (4xx) are not captured. + /// Ensures client errors (4xx) returned by service are not captured. #[actix_web::test] - async fn test_client_errors_discarded() { + async fn test_service_client_errors_discarded() { let events = sentry::test::with_captured_events(|| { block_on(async { let service = HttpResponse::NotFound; @@ -645,6 +648,66 @@ mod tests { assert!(events.is_empty()); } + /// Ensures client errors (4xx) returned by middleware are not captured. + #[actix_web::test] + async fn test_middleware_client_errors_discarded() { + let events = sentry::test::with_captured_events(|| { + block_on(async { + async fn hello_world() -> HttpResponse { + HttpResponse::Ok().body("Hello, world!") + } + + let app = init_service( + App::new() + .wrap_fn(|_, _| async { + Err(actix_web::error::ErrorNotFound("Not found")) + as Result, _> + }) + .wrap(Sentry::builder().with_hub(Hub::current()).finish()) + .service(web::resource("/test").to(hello_world)), + ) + .await; + + let req = TestRequest::get().uri("/test").to_request(); + let res = app.call(req).await; + assert!(res.is_err()); + assert!(res.unwrap_err().error_response().status().is_client_error()); + }) + }); + + assert!(events.is_empty()); + } + + /// Ensures server errors (5xx) returned by middleware are captured. + #[actix_web::test] + async fn test_middleware_server_errors_captured() { + let events = sentry::test::with_captured_events(|| { + block_on(async { + async fn hello_world() -> HttpResponse { + HttpResponse::Ok().body("Hello, world!") + } + + let app = init_service( + App::new() + .wrap_fn(|_, _| async { + Err(actix_web::error::ErrorInternalServerError("Server error")) + as Result, _> + }) + .wrap(Sentry::builder().with_hub(Hub::current()).finish()) + .service(web::resource("/test").to(hello_world)), + ) + .await; + + let req = TestRequest::get().uri("/test").to_request(); + let res = app.call(req).await; + assert!(res.is_err()); + assert!(res.unwrap_err().error_response().status().is_server_error()); + }) + }); + + assert_eq!(events.len(), 1); + } + /// Ensures transaction name can be overridden in handler scope. #[actix_web::test] async fn test_override_transaction_name() { From 663032ed972f9371b0e208760e711170b169723b Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Thu, 28 Aug 2025 15:22:51 +0200 Subject: [PATCH 128/148] test(tower): fix doctests (#888) --- Makefile | 5 +++++ sentry-backtrace/src/utils.rs | 2 +- sentry-core/src/performance.rs | 4 ++-- sentry-tower/src/lib.rs | 4 ++-- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index daf0d92b4..685a92bca 100644 --- a/Makefile +++ b/Makefile @@ -33,6 +33,11 @@ lint: cargo +stable clippy --all-features --tests --examples -- -D clippy::all .PHONY: lint +fix: + @rustup component add clippy --toolchain stable 2> /dev/null + cargo +stable clippy --all-features --workspace --tests --examples --fix -- -D clippy::all +.PHONY: fix + # Tests test: checkall testall diff --git a/sentry-backtrace/src/utils.rs b/sentry-backtrace/src/utils.rs index fa8b04400..1ce0750e0 100644 --- a/sentry-backtrace/src/utils.rs +++ b/sentry-backtrace/src/utils.rs @@ -57,7 +57,7 @@ pub fn filename(s: &str) -> &str { s.rsplit(&['/', '\\'][..]).next().unwrap() } -pub fn strip_symbol(s: &str) -> Cow { +pub fn strip_symbol(s: &str) -> Cow<'_, str> { let stripped_trailing_hash = HASH_FUNC_RE .captures(s) .map(|c| c.get(1).unwrap().as_str()) diff --git a/sentry-core/src/performance.rs b/sentry-core/src/performance.rs index 18a96d1f3..4e7a3ac3a 100644 --- a/sentry-core/src/performance.rs +++ b/sentry-core/src/performance.rs @@ -757,7 +757,7 @@ impl Transaction { /// for as long as it lives. Therefore you must take care not to keep the returned /// `TransactionData` around too long or it will never relinquish the lock and you may run into /// a deadlock. - pub fn data(&self) -> TransactionData { + pub fn data(&self) -> TransactionData<'_> { TransactionData(self.inner.lock().unwrap()) } @@ -988,7 +988,7 @@ impl Span { /// for as long as it lives. Therefore you must take care not to keep the returned /// `Data` around too long or it will never relinquish the lock and you may run into /// a deadlock. - pub fn data(&self) -> Data { + pub fn data(&self) -> Data<'_> { Data(self.span.lock().unwrap()) } diff --git a/sentry-tower/src/lib.rs b/sentry-tower/src/lib.rs index cdfe998ed..8c40e5b0c 100644 --- a/sentry-tower/src/lib.rs +++ b/sentry-tower/src/lib.rs @@ -133,10 +133,10 @@ //! When using `axum`, either use [`tower::ServiceBuilder`] as shown above, or make sure you //! reorder the layers, like so: //! -//! ```rust +//! ```ignore //! let app = Router::new() //! .route("/", get(handler)) -//! .layer(sentry_tower::SentryHttpLayer::with_transaction()) +//! .layer(sentry_tower::SentryHttpLayer::new().enable_transaction()) //! .layer(sentry_tower::NewSentryLayer::::new_from_top()) //! ``` //! From 280dab99bef30513b675eda27d290e779ae527e1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Sep 2025 15:10:54 +0200 Subject: [PATCH 129/148] build(deps): bump tracing-subscriber from 0.3.19 to 0.3.20 (#891) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 17 +++++------------ sentry-tracing/Cargo.toml | 4 ++-- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fa575e93c..7c7d3f82e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2333,12 +2333,11 @@ dependencies = [ [[package]] name = "nu-ansi-term" -version = "0.46.0" +version = "0.50.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" dependencies = [ - "overload", - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -2486,12 +2485,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - [[package]] name = "parking_lot" version = "0.12.3" @@ -3922,9 +3915,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.19" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" dependencies = [ "nu-ansi-term", "sharded-slab", diff --git a/sentry-tracing/Cargo.toml b/sentry-tracing/Cargo.toml index 51751345b..d3ff3a4a9 100644 --- a/sentry-tracing/Cargo.toml +++ b/sentry-tracing/Cargo.toml @@ -25,7 +25,7 @@ sentry-core = { version = "0.42.0", path = "../sentry-core", features = [ "client", ] } tracing-core = "0.1" -tracing-subscriber = { version = "0.3.1", default-features = false, features = [ +tracing-subscriber = { version = "0.3.20", default-features = false, features = [ "std", ] } sentry-backtrace = { version = "0.42.0", path = "../sentry-backtrace", optional = true } @@ -36,5 +36,5 @@ log = "0.4" sentry = { path = "../sentry", default-features = false, features = ["test", "tracing"] } serde_json = "1" tracing = "0.1" -tracing-subscriber = { version = "0.3.1", features = ["fmt", "registry"] } +tracing-subscriber = { version = "0.3.20", features = ["fmt", "registry"] } tokio = { version = "1.44", features = ["rt-multi-thread", "macros", "time"] } From a5932c029587f7a4733bfbd7b00bddfbe6ef03a4 Mon Sep 17 00:00:00 2001 From: Giannis Gkiortzis <58184179+giortzisg@users.noreply.github.com> Date: Thu, 11 Sep 2025 14:10:09 +0200 Subject: [PATCH 130/148] fix(transport): add rate limit for logs (#894) Co-authored-by: Lorenzo Cian --- CHANGELOG.md | 1 + sentry/src/transports/ratelimit.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f6d89558..a95c7f332 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ - build(panic): Fix build without other dependencies ([#883](https://github.com/getsentry/sentry-rust/pull/883)) by @liskin - The `sentry-panic` crate now builds successfully when used as a standalone dependency. +- fix(transport): add rate limits for logs ([#894](https://github.com/getsentry/sentry-rust/pull/894)) by @giortzisg ## 0.42.0 diff --git a/sentry/src/transports/ratelimit.rs b/sentry/src/transports/ratelimit.rs index 3cadfa057..fbe053590 100644 --- a/sentry/src/transports/ratelimit.rs +++ b/sentry/src/transports/ratelimit.rs @@ -2,6 +2,7 @@ use httpdate::parse_http_date; use std::time::{Duration, SystemTime}; use crate::protocol::EnvelopeItem; +use crate::protocol::ItemContainer; use crate::Envelope; /// A Utility that helps with rate limiting sentry requests. @@ -12,6 +13,7 @@ pub struct RateLimiter { session: Option, transaction: Option, attachment: Option, + log_item: Option, } impl RateLimiter { @@ -56,6 +58,7 @@ impl RateLimiter { "session" => self.session = new_time, "transaction" => self.transaction = new_time, "attachment" => self.attachment = new_time, + "log_item" => self.log_item = new_time, _ => {} } } @@ -89,6 +92,7 @@ impl RateLimiter { RateLimitingCategory::Session => self.session, RateLimitingCategory::Transaction => self.transaction, RateLimitingCategory::Attachment => self.attachment, + RateLimitingCategory::LogItem => self.log_item, }?; time_left.duration_since(SystemTime::now()).ok() } @@ -112,6 +116,9 @@ impl RateLimiter { } EnvelopeItem::Transaction(_) => RateLimitingCategory::Transaction, EnvelopeItem::Attachment(_) => RateLimitingCategory::Attachment, + EnvelopeItem::ItemContainer(ItemContainer::Logs(_)) => { + RateLimitingCategory::LogItem + } _ => RateLimitingCategory::Any, }) }) @@ -131,6 +138,8 @@ pub enum RateLimitingCategory { Transaction, /// Rate Limit pertaining to Attachments. Attachment, + /// Rate Limit pertaining to Log Items. + LogItem, } #[cfg(test)] @@ -145,6 +154,7 @@ mod tests { assert!(rl.is_disabled(RateLimitingCategory::Error).unwrap() <= Duration::from_secs(120)); assert!(rl.is_disabled(RateLimitingCategory::Session).unwrap() <= Duration::from_secs(60)); assert!(rl.is_disabled(RateLimitingCategory::Transaction).is_none()); + assert!(rl.is_disabled(RateLimitingCategory::LogItem).is_none()); assert!(rl.is_disabled(RateLimitingCategory::Any).is_none()); rl.update_from_sentry_header( @@ -161,6 +171,23 @@ mod tests { assert!(rl.is_disabled(RateLimitingCategory::Any).unwrap() <= Duration::from_secs(30)); } + #[test] + fn test_sentry_header_no_categories() { + let mut rl = RateLimiter::new(); + rl.update_from_sentry_header("120::bar"); + + assert!(rl.is_disabled(RateLimitingCategory::Error).unwrap() <= Duration::from_secs(120)); + assert!(rl.is_disabled(RateLimitingCategory::Session).unwrap() <= Duration::from_secs(120)); + assert!( + rl.is_disabled(RateLimitingCategory::Transaction).unwrap() <= Duration::from_secs(120) + ); + assert!(rl.is_disabled(RateLimitingCategory::LogItem).unwrap() <= Duration::from_secs(120)); + assert!( + rl.is_disabled(RateLimitingCategory::Attachment).unwrap() <= Duration::from_secs(120) + ); + assert!(rl.is_disabled(RateLimitingCategory::Any).unwrap() <= Duration::from_secs(120)); + } + #[test] fn test_retry_after() { let mut rl = RateLimiter::new(); From 045c2e2fed440d00def9c26b0bdf20ee19b83eb6 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Thu, 11 Sep 2025 15:06:40 +0200 Subject: [PATCH 131/148] feat(tracing): send both breadcrumbs and logs by default (#878) --- CHANGELOG.md | 5 +++++ sentry-tracing/src/layer.rs | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a95c7f332..2127cd47b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,11 @@ - With this change, we capture errors returned by middleware only if those errors can be classified as server errors. - There is no change in behavior when it comes to errors returned by services, in which case the Sentry middleware only captures server errors exclusively. +### Behavioral changes + +- feat(tracing): send both breadcrumbs and logs by default ([#878](https://github.com/getsentry/sentry-rust/pull/878)) by @lcian + - If the `logs` feature flag is enabled, and `enable_logs: true` is set on your client options, the default Sentry `tracing` layer now sends logs for all events at or above INFO. + ### Features - feat(core): add Response context ([#874](https://github.com/getsentry/sentry-rust/pull/874)) by @lcian diff --git a/sentry-tracing/src/layer.rs b/sentry-tracing/src/layer.rs index efc4da540..5d3c59ece 100644 --- a/sentry-tracing/src/layer.rs +++ b/sentry-tracing/src/layer.rs @@ -72,7 +72,13 @@ impl From> for CombinedEventMapping { /// `warning` and `info`, and `debug` and `trace` logs are ignored. pub fn default_event_filter(metadata: &Metadata) -> EventFilter { match metadata.level() { + #[cfg(feature = "logs")] + &Level::ERROR => EventFilter::Event | EventFilter::Log, + #[cfg(not(feature = "logs"))] &Level::ERROR => EventFilter::Event, + #[cfg(feature = "logs")] + &Level::WARN | &Level::INFO => EventFilter::Breadcrumb | EventFilter::Log, + #[cfg(not(feature = "logs"))] &Level::WARN | &Level::INFO => EventFilter::Breadcrumb, &Level::DEBUG | &Level::TRACE => EventFilter::Ignore, } From 5c8ab31b61f61d030fa0d35d6a5aee812362d7c1 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Fri, 12 Sep 2025 15:01:51 +0200 Subject: [PATCH 132/148] ref(tracing): rework `tracing` to Sentry span name/op conversion (#887) --- CHANGELOG.md | 29 ++++++- sentry-core/src/performance.rs | 42 ++++++++++ sentry-tracing/src/layer.rs | 107 +++++++++++++++++++----- sentry-tracing/src/lib.rs | 45 +++++++++- sentry-tracing/tests/name_op_updates.rs | 45 ++++++++++ sentry-tracing/tests/smoke.rs | 16 +++- 6 files changed, 257 insertions(+), 27 deletions(-) create mode 100644 sentry-tracing/tests/name_op_updates.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 2127cd47b..c89740cfa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,13 @@ ### Breaking changes -- fix(actix): capture only server errors ([#877](https://github.com/getsentry/sentry-rust/pull/877)) +- ref(tracing): rework tracing to Sentry span name/op conversion ([#887](https://github.com/getsentry/sentry-rust/pull/887)) by @lcian + - The `tracing` integration now uses the tracing span name as the Sentry span name by default. + - Before this change, the span name would be set based on the `tracing` span target (:: when using the `tracing::instrument` macro). + - The `tracing` integration now uses `default` as the default Sentry span op. + - Before this change, the span op would be set based on the `tracing` span name. + - When upgrading, please ensure to adapt any queries, metrics or dashboards to use the new span names/ops. +- fix(actix): capture only server errors ([#877](https://github.com/getsentry/sentry-rust/pull/877)) by @lcian - The Actix integration now properly honors the `capture_server_errors` option (enabled by default), capturing errors returned by middleware only if they are server errors (HTTP status code 5xx). - Previously, if a middleware were to process the request after the Sentry middleware and return an error, our middleware would always capture it and send it to Sentry, regardless if it was a client, server or some other kind of error. - With this change, we capture errors returned by middleware only if those errors can be classified as server errors. @@ -17,6 +23,27 @@ ### Features +- ref(tracing): rework tracing to Sentry span name/op conversion ([#887](https://github.com/getsentry/sentry-rust/pull/887)) by @lcian + - Additional special fields have been added that allow overriding certain data on the Sentry span: + - `sentry.op`: override the Sentry span op. + - `sentry.name`: override the Sentry span name. + - `sentry.trace`: given a string matching a valid `sentry-trace` header (sent automatically by client SDKs), continues the distributed trace instead of starting a new one. If the value is not a valid `sentry-trace` header or a trace is already started, this value is ignored. + - `sentry.op` and `sentry.name` can also be applied retroactively by declaring fields with value `tracing::field::Empty` and then recorded using `tracing::Span::record`. + - Example usage: + ```rust + #[tracing::instrument(skip_all, fields( + sentry.op = "http.server", + sentry.name = "GET /payments", + sentry.trace = headers.get("sentry-trace").unwrap_or(&"".to_owned()), + ))] + async fn handle_request(headers: std::collections::HashMap) { + // ... + } + ``` + - Additional attributes are sent along with each span by default: + - `sentry.tracing.target`: corresponds to the `tracing` span's `metadata.target()` + - `code.module.name`, `code.file.path`, `code.line.number` + - feat(core): add Response context ([#874](https://github.com/getsentry/sentry-rust/pull/874)) by @lcian - The `Response` context can now be attached to events, to include information about HTTP responses such as headers, cookies and status code. - Example: diff --git a/sentry-core/src/performance.rs b/sentry-core/src/performance.rs index 4e7a3ac3a..7e6b723be 100644 --- a/sentry-core/src/performance.rs +++ b/sentry-core/src/performance.rs @@ -465,6 +465,22 @@ impl TransactionOrSpan { } } + /// Set the operation for this Transaction/Span. + pub fn set_op(&self, op: &str) { + match self { + TransactionOrSpan::Transaction(transaction) => transaction.set_op(op), + TransactionOrSpan::Span(span) => span.set_op(op), + } + } + + /// Set the name (description) for this Transaction/Span. + pub fn set_name(&self, name: &str) { + match self { + TransactionOrSpan::Transaction(transaction) => transaction.set_name(name), + TransactionOrSpan::Span(span) => span.set_name(name), + } + } + /// Set the HTTP request information for this Transaction/Span. pub fn set_request(&self, request: protocol::Request) { match self { @@ -781,6 +797,20 @@ impl Transaction { inner.context.status = Some(status); } + /// Set the operation of the Transaction. + pub fn set_op(&self, op: &str) { + let mut inner = self.inner.lock().unwrap(); + inner.context.op = Some(op.to_string()); + } + + /// Set the name of the Transaction. + pub fn set_name(&self, name: &str) { + let mut inner = self.inner.lock().unwrap(); + if let Some(transaction) = inner.transaction.as_mut() { + transaction.name = Some(name.to_string()); + } + } + /// Set the HTTP request information for this Transaction. pub fn set_request(&self, request: protocol::Request) { let mut inner = self.inner.lock().unwrap(); @@ -1018,6 +1048,18 @@ impl Span { span.status = Some(status); } + /// Set the operation of the Span. + pub fn set_op(&self, op: &str) { + let mut span = self.span.lock().unwrap(); + span.op = Some(op.to_string()); + } + + /// Set the name (description) of the Span. + pub fn set_name(&self, name: &str) { + let mut span = self.span.lock().unwrap(); + span.description = Some(name.to_string()); + } + /// Set the HTTP request information for this Span. pub fn set_request(&self, request: protocol::Request) { let mut span = self.span.lock().unwrap(); diff --git a/sentry-tracing/src/layer.rs b/sentry-tracing/src/layer.rs index 5d3c59ece..202f7cf38 100644 --- a/sentry-tracing/src/layer.rs +++ b/sentry-tracing/src/layer.rs @@ -12,6 +12,9 @@ use tracing_subscriber::layer::{Context, Layer}; use tracing_subscriber::registry::LookupSpan; use crate::converters::*; +use crate::SENTRY_NAME_FIELD; +use crate::SENTRY_OP_FIELD; +use crate::SENTRY_TRACE_FIELD; use crate::TAGS_PREFIX; bitflags! { @@ -298,27 +301,26 @@ where return; } - let (description, data) = extract_span_data(attrs); - let op = span.name(); - - // Spans don't always have a description, this ensures our data is not empty, - // therefore the Sentry UI will be a lot more valuable for navigating spans. - let description = description.unwrap_or_else(|| { - let target = span.metadata().target(); - if target.is_empty() { - op.to_string() - } else { - format!("{target}::{op}") - } - }); + let (data, sentry_name, sentry_op, sentry_trace) = extract_span_data(attrs); + let sentry_name = sentry_name.as_deref().unwrap_or_else(|| span.name()); + let sentry_op = sentry_op.as_deref().unwrap_or("default"); let hub = sentry_core::Hub::current(); let parent_sentry_span = hub.configure_scope(|scope| scope.get_span()); - let sentry_span: sentry_core::TransactionOrSpan = match &parent_sentry_span { - Some(parent) => parent.start_child(op, &description).into(), + let mut sentry_span: sentry_core::TransactionOrSpan = match &parent_sentry_span { + Some(parent) => parent.start_child(sentry_op, sentry_name).into(), None => { - let ctx = sentry_core::TransactionContext::new(&description, op); + let ctx = if let Some(trace_header) = sentry_trace { + sentry_core::TransactionContext::continue_from_headers( + sentry_name, + sentry_op, + [("sentry-trace", trace_header.as_str())], + ) + } else { + sentry_core::TransactionContext::new(sentry_name, sentry_op) + }; + let tx = sentry_core::start_transaction(ctx); tx.set_data("origin", "auto.tracing".into()); tx.into() @@ -328,6 +330,8 @@ where // This comes from typically the `fields` in `tracing::instrument`. record_fields(&sentry_span, data); + set_default_attributes(&mut sentry_span, span.metadata()); + let mut extensions = span.extensions_mut(); extensions.insert(SentrySpanData { sentry_span, @@ -403,10 +407,52 @@ where let mut data = FieldVisitor::default(); values.record(&mut data); + let sentry_name = data + .json_values + .remove(SENTRY_NAME_FIELD) + .and_then(|v| match v { + Value::String(s) => Some(s), + _ => None, + }); + + let sentry_op = data + .json_values + .remove(SENTRY_OP_FIELD) + .and_then(|v| match v { + Value::String(s) => Some(s), + _ => None, + }); + + // `sentry.trace` cannot be applied retroactively + data.json_values.remove(SENTRY_TRACE_FIELD); + + if let Some(name) = sentry_name { + span.set_name(&name); + } + if let Some(op) = sentry_op { + span.set_op(&op); + } + record_fields(span, data.json_values); } } +fn set_default_attributes(span: &mut TransactionOrSpan, metadata: &Metadata<'_>) { + span.set_data("sentry.tracing.target", metadata.target().into()); + + if let Some(module) = metadata.module_path() { + span.set_data("code.module.name", module.into()); + } + + if let Some(file) = metadata.file() { + span.set_data("code.file.path", file.into()); + } + + if let Some(line) = metadata.line() { + span.set_data("code.line.number", line.into()); + } +} + /// Creates a default Sentry layer pub fn layer() -> SentryLayer where @@ -415,8 +461,16 @@ where Default::default() } -/// Extracts the message and attributes from a span -fn extract_span_data(attrs: &span::Attributes) -> (Option, BTreeMap<&'static str, Value>) { +/// Extracts the attributes from a span, +/// returning the values of SENTRY_NAME_FIELD, SENTRY_OP_FIELD, SENTRY_TRACE_FIELD separately +fn extract_span_data( + attrs: &span::Attributes, +) -> ( + BTreeMap<&'static str, Value>, + Option, + Option, + Option, +) { let mut json_values = VISITOR_BUFFER.with_borrow_mut(|debug_buffer| { let mut visitor = SpanFieldVisitor { debug_buffer, @@ -426,13 +480,24 @@ fn extract_span_data(attrs: &span::Attributes) -> (Option, BTreeMap<&'st visitor.json_values }); - // Find message of the span, if any - let message = json_values.remove("message").and_then(|v| match v { + let name = json_values.remove(SENTRY_NAME_FIELD).and_then(|v| match v { Value::String(s) => Some(s), _ => None, }); - (message, json_values) + let op = json_values.remove(SENTRY_OP_FIELD).and_then(|v| match v { + Value::String(s) => Some(s), + _ => None, + }); + + let sentry_trace = json_values + .remove(SENTRY_TRACE_FIELD) + .and_then(|v| match v { + Value::String(s) => Some(s), + _ => None, + }); + + (json_values, name, op, sentry_trace) } thread_local! { diff --git a/sentry-tracing/src/lib.rs b/sentry-tracing/src/lib.rs index df6887180..100b8efd4 100644 --- a/sentry-tracing/src/lib.rs +++ b/sentry-tracing/src/lib.rs @@ -169,7 +169,7 @@ //! # Tracing Spans //! //! The integration automatically tracks `tracing` spans as spans in Sentry. A convenient way to do -//! this is with the `#[instrument]` attribute macro, which creates a transaction for the function +//! this is with the `#[instrument]` attribute macro, which creates a span/transaction for the function //! in Sentry. //! //! Function arguments are added as context fields automatically, which can be configured through @@ -180,8 +180,8 @@ //! //! use tracing_subscriber::prelude::*; //! -//! // Functions instrumented by tracing automatically report -//! // their span as transactions. +//! // Functions instrumented by tracing automatically +//! // create spans/transactions around their execution. //! #[tracing::instrument] //! async fn outer() { //! for i in 0..10 { @@ -198,6 +198,42 @@ //! tokio::time::sleep(Duration::from_millis(100)).await; //! } //! ``` +//! +//! By default, the name of the span sent to Sentry matches the name of the `tracing` span, which +//! is the name of the function when using `tracing::instrument`, or the name passed to the +//! `tracing::_span` macros. +//! +//! By default, the `op` of the span sent to Sentry is `default`. +//! +//! ## Special Span Fields +//! +//! Some fields on spans are treated specially by the Sentry tracing integration: +//! - `sentry.name`: overrides the span name sent to Sentry. +//! This is useful to customize the span name when using `#[tracing::instrument]`, or to update +//! it retroactively (using `span.record`) after the span has been created. +//! - `sentry.op`: overrides the span `op` sent to Sentry. +//! - `sentry.trace`: in Sentry, the `sentry-trace` header is sent with HTTP requests to achieve distributed tracing. +//! If the value of this field is set to the value of a valid `sentry-trace` header, which +//! other Sentry SDKs send automatically with outgoing requests, then the SDK will continue the trace using the given distributed tracing information. +//! This is useful to achieve distributed tracing at service boundaries by using only the +//! `tracing` API. +//! Note that `sentry.trace` will only be effective on span creation (it cannot be applied retroactively) +//! and requires the span it's applied to to be a root span, i.e. no span should active upon its +//! creation. +//! +//! +//! Example: +//! +//! ``` +//! #[tracing::instrument(skip_all, fields( +//! sentry.name = "GET /payments", +//! sentry.op = "http.server", +//! sentry.trace = headers.get("sentry-trace").unwrap_or(&"".to_owned()), +//! ))] +//! async fn handle_request(headers: std::collections::HashMap) { +//! // ... +//! } +//! ``` #![doc(html_favicon_url = "https://sentry-brand.storage.googleapis.com/favicon.ico")] #![doc(html_logo_url = "https://sentry-brand.storage.googleapis.com/sentry-glyph-black.png")] @@ -210,3 +246,6 @@ pub use converters::*; pub use layer::*; const TAGS_PREFIX: &str = "tags."; +const SENTRY_OP_FIELD: &str = "sentry.op"; +const SENTRY_NAME_FIELD: &str = "sentry.name"; +const SENTRY_TRACE_FIELD: &str = "sentry.trace"; diff --git a/sentry-tracing/tests/name_op_updates.rs b/sentry-tracing/tests/name_op_updates.rs new file mode 100644 index 000000000..a6f3d15a9 --- /dev/null +++ b/sentry-tracing/tests/name_op_updates.rs @@ -0,0 +1,45 @@ +mod shared; + +#[tracing::instrument(fields( + some = "value", + sentry.name = "updated name", + sentry.op = "updated op", +))] +fn test_fun_record_on_creation() {} + +#[tracing::instrument(fields( + some = "value", + sentry.name = tracing::field::Empty, + sentry.op = tracing::field::Empty, +))] +fn test_fun_record_later() { + tracing::Span::current().record("sentry.name", "updated name"); + tracing::Span::current().record("sentry.op", "updated op"); +} + +#[test] +fn should_update_sentry_op_and_name_based_on_fields() { + let transport = shared::init_sentry(1.0); + + for f in [test_fun_record_on_creation, test_fun_record_later] { + f(); + + let data = transport.fetch_and_clear_envelopes(); + assert_eq!(data.len(), 1); + + let transaction = data.first().expect("should have 1 transaction"); + let transaction = match transaction.items().next().unwrap() { + sentry::protocol::EnvelopeItem::Transaction(transaction) => transaction, + unexpected => panic!("Expected transaction, but got {unexpected:#?}"), + }; + + assert_eq!(transaction.name.as_deref().unwrap(), "updated name"); + let ctx = transaction.contexts.get("trace"); + match ctx { + Some(sentry::protocol::Context::Trace(trace_ctx)) => { + assert_eq!(trace_ctx.op, Some("updated op".to_owned())) + } + _ => panic!("expected trace context"), + } + } +} diff --git a/sentry-tracing/tests/smoke.rs b/sentry-tracing/tests/smoke.rs index cb4f04e34..cca7b1f4c 100644 --- a/sentry-tracing/tests/smoke.rs +++ b/sentry-tracing/tests/smoke.rs @@ -24,7 +24,7 @@ fn should_instrument_function_with_event() { sentry::protocol::Context::Trace(trace) => trace, unexpected => panic!("Expected trace context but got {unexpected:?}"), }; - assert_eq!(trace.op.as_deref().unwrap(), "function_with_tags"); + assert_eq!(trace.op.as_deref().unwrap(), "default"); //Confirm transaction values let transaction = data.get(1).expect("should have 1 transaction"); @@ -32,8 +32,9 @@ fn should_instrument_function_with_event() { sentry::protocol::EnvelopeItem::Transaction(transaction) => transaction, unexpected => panic!("Expected transaction, but got {unexpected:#?}"), }; + assert_eq!(transaction.name, Some("function_with_tags".into())); assert_eq!(transaction.tags.len(), 1); - assert_eq!(trace.data.len(), 3); + assert_eq!(trace.data.len(), 7); let tag = transaction .tags @@ -50,4 +51,15 @@ fn should_instrument_function_with_event() { .get("value") .expect("to have data attribute with name 'value'"); assert_eq!(value, 1); + + assert_eq!( + trace.data.get("sentry.tracing.target"), + Some("smoke".into()).as_ref() + ); + assert_eq!( + trace.data.get("code.module.name"), + Some("smoke".into()).as_ref() + ); + assert!(trace.data.contains_key("code.file.path")); + assert!(trace.data.contains_key("code.line.number")); } From bbd667ab00a62e1e69fdaccd349be08258b86be6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Daxb=C3=B6ck?= <114897+dingsdax@users.noreply.github.com> Date: Tue, 16 Sep 2025 11:08:40 +0200 Subject: [PATCH 133/148] meta: add pull request template (#898) Co-authored-by: Lorenzo Cian --- .github/pull_request_template.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/pull_request_template.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 000000000..bedde672b --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,14 @@ +### Description + + +#### Issues + + +#### Reminders +- Add GH Issue ID _&_ Linear ID (if applicable) +- Add an entry to CHANGELOG.md, following the format of existing entries +- The PR title should use [Conventional Commits](https://develop.sentry.dev/engineering-practices/commit-messages/#type) style (`feat:`, `fix:`, `ref:`, `meta:`, etc.) +- Useful links for external contributors: [Sentry SDK development docs](https://develop.sentry.dev/sdk/), [Discord community](https://discord.gg/sentry) From 75a8c03de752feda9762291ed9673908d94dbd7d Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Wed, 17 Sep 2025 17:05:39 +0200 Subject: [PATCH 134/148] ref(tracing): use standard code attributes (#899) --- CHANGELOG.md | 2 ++ sentry-tracing/src/converters.rs | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c89740cfa..ccd508d45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ - The `tracing` integration now uses `default` as the default Sentry span op. - Before this change, the span op would be set based on the `tracing` span name. - When upgrading, please ensure to adapt any queries, metrics or dashboards to use the new span names/ops. +- ref(tracing): use standard code attributes ([#899](https://github.com/getsentry/sentry-rust/pull/899)) by @lcian + - Logs now carry the attributes `code.module.name`, `code.file.path` and `code.line.number` standardized in OTEL to surface the respective information, in contrast with the previously sent `tracing.module_path`, `tracing.file` and `tracing.line`. - fix(actix): capture only server errors ([#877](https://github.com/getsentry/sentry-rust/pull/877)) by @lcian - The Actix integration now properly honors the `capture_server_errors` option (enabled by default), capturing errors returned by middleware only if they are server errors (HTTP status code 5xx). - Previously, if a middleware were to process the request after the Sentry middleware and return an error, our middleware would always capture it and send it to Sentry, regardless if it was a client, server or some other kind of error. diff --git a/sentry-tracing/src/converters.rs b/sentry-tracing/src/converters.rs index d09f5325a..1243082ae 100644 --- a/sentry-tracing/src/converters.rs +++ b/sentry-tracing/src/converters.rs @@ -344,13 +344,13 @@ where let event_meta = event.metadata(); if let Some(module_path) = event_meta.module_path() { - attributes.insert("tracing.module_path".to_owned(), module_path.into()); + attributes.insert("code.module.name".to_owned(), module_path.into()); } if let Some(file) = event_meta.file() { - attributes.insert("tracing.file".to_owned(), file.into()); + attributes.insert("code.file.path".to_owned(), file.into()); } if let Some(line) = event_meta.line() { - attributes.insert("tracing.line".to_owned(), line.into()); + attributes.insert("code.line.number".to_owned(), line.into()); } attributes.insert("sentry.origin".to_owned(), "auto.tracing".into()); From 6b61b31367db6637523add4966bc4a3173aebd02 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Mon, 22 Sep 2025 14:51:23 +0200 Subject: [PATCH 135/148] fix: send trace origin correctly (#906) --- CHANGELOG.md | 2 ++ sentry-actix/src/lib.rs | 2 +- sentry-core/src/performance.rs | 6 ++++++ sentry-opentelemetry/src/processor.rs | 4 ++-- sentry-tower/src/http.rs | 6 +++--- sentry-tracing/src/layer.rs | 2 +- sentry-tracing/tests/smoke.rs | 2 +- sentry-types/src/protocol/v7.rs | 4 ++++ 8 files changed, 20 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ccd508d45..0463e7faf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ - Previously, if a middleware were to process the request after the Sentry middleware and return an error, our middleware would always capture it and send it to Sentry, regardless if it was a client, server or some other kind of error. - With this change, we capture errors returned by middleware only if those errors can be classified as server errors. - There is no change in behavior when it comes to errors returned by services, in which case the Sentry middleware only captures server errors exclusively. +- fix: send trace origin correctly ([#906](https://github.com/getsentry/sentry-rust/pull/906)) by @lcian + - `TraceContext` now has an additional field `origin`, used to report which integration created a transaction. ### Behavioral changes diff --git a/sentry-actix/src/lib.rs b/sentry-actix/src/lib.rs index 19fa4394f..2a69a41c7 100644 --- a/sentry-actix/src/lib.rs +++ b/sentry-actix/src/lib.rs @@ -322,7 +322,7 @@ where let transaction = hub.start_transaction(ctx); transaction.set_request(sentry_req.clone()); - transaction.set_data("origin", "auto.http.actix".into()); + transaction.set_origin("auto.http.actix"); Some(transaction) } else { None diff --git a/sentry-core/src/performance.rs b/sentry-core/src/performance.rs index 7e6b723be..9b48e911b 100644 --- a/sentry-core/src/performance.rs +++ b/sentry-core/src/performance.rs @@ -819,6 +819,12 @@ impl Transaction { } } + /// Sets the origin for this transaction, indicating what created it. + pub fn set_origin(&self, origin: &str) { + let mut inner = self.inner.lock().unwrap(); + inner.context.origin = Some(origin.to_owned()); + } + /// Returns the headers needed for distributed tracing. /// Use [`crate::Scope::iter_trace_propagation_headers`] to obtain the active /// trace's distributed tracing headers. diff --git a/sentry-opentelemetry/src/processor.rs b/sentry-opentelemetry/src/processor.rs index f883d163e..77b143875 100644 --- a/sentry-opentelemetry/src/processor.rs +++ b/sentry-opentelemetry/src/processor.rs @@ -174,8 +174,8 @@ impl SpanProcessor for SentrySpanProcessor { // TODO: read OTEL semantic convention span attributes and map them to the appropriate // Sentry span attributes/context values - if matches!(sentry_span, TransactionOrSpan::Transaction(_)) { - sentry_span.set_data("origin", "auto.otel".into()) + if let TransactionOrSpan::Transaction(transaction) = &sentry_span { + transaction.set_origin("auto.otel"); } sentry_span.set_status(convert_span_status(&data.status)); sentry_span.finish_with_timestamp(data.end_time); diff --git a/sentry-tower/src/http.rs b/sentry-tower/src/http.rs index c8ff949e0..5b7c2f4eb 100644 --- a/sentry-tower/src/http.rs +++ b/sentry-tower/src/http.rs @@ -118,10 +118,10 @@ where if let Some((sentry_req, trx_ctx)) = slf.on_first_poll.take() { sentry_core::configure_scope(|scope| { if let Some(trx_ctx) = trx_ctx { - let transaction: sentry_core::TransactionOrSpan = - sentry_core::start_transaction(trx_ctx).into(); + let transaction = sentry_core::start_transaction(trx_ctx); + transaction.set_origin("auto.http.tower"); + let transaction: sentry_core::TransactionOrSpan = transaction.into(); transaction.set_request(sentry_req.clone()); - transaction.set_data("origin", "auto.http.tower".into()); let parent_span = scope.get_span(); scope.set_span(Some(transaction.clone())); *slf.transaction = Some((transaction, parent_span)); diff --git a/sentry-tracing/src/layer.rs b/sentry-tracing/src/layer.rs index 202f7cf38..d7de47ad4 100644 --- a/sentry-tracing/src/layer.rs +++ b/sentry-tracing/src/layer.rs @@ -322,7 +322,7 @@ where }; let tx = sentry_core::start_transaction(ctx); - tx.set_data("origin", "auto.tracing".into()); + tx.set_origin("auto.tracing"); tx.into() } }; diff --git a/sentry-tracing/tests/smoke.rs b/sentry-tracing/tests/smoke.rs index cca7b1f4c..570800cda 100644 --- a/sentry-tracing/tests/smoke.rs +++ b/sentry-tracing/tests/smoke.rs @@ -34,7 +34,7 @@ fn should_instrument_function_with_event() { }; assert_eq!(transaction.name, Some("function_with_tags".into())); assert_eq!(transaction.tags.len(), 1); - assert_eq!(trace.data.len(), 7); + assert_eq!(trace.data.len(), 6); let tag = transaction .tags diff --git a/sentry-types/src/protocol/v7.rs b/sentry-types/src/protocol/v7.rs index 617fd5e82..b2f8ee99a 100644 --- a/sentry-types/src/protocol/v7.rs +++ b/sentry-types/src/protocol/v7.rs @@ -1504,6 +1504,10 @@ pub struct TraceContext { /// Describes the status of the span (e.g. `ok`, `cancelled`, etc.) #[serde(default, skip_serializing_if = "Option::is_none")] pub status: Option, + /// Describes what created the transaction. See the [develop + /// docs](https://develop.sentry.dev/sdk/telemetry/traces/trace-origin/) for more information. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub origin: Option, /// Optional data attributes to be associated with the transaction. #[serde(default, skip_serializing_if = "Map::is_empty")] pub data: Map, From 75aff83c65dec687f301512ca1ba943db6acaa93 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Tue, 23 Sep 2025 09:50:09 +0200 Subject: [PATCH 136/148] fix(tracing): skip default span attributes when propagating to event (#904) --- sentry-tracing/src/converters.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/sentry-tracing/src/converters.rs b/sentry-tracing/src/converters.rs index 1243082ae..9ae410946 100644 --- a/sentry-tracing/src/converters.rs +++ b/sentry-tracing/src/converters.rs @@ -101,6 +101,9 @@ where match &span_data.sentry_span { TransactionOrSpan::Span(span) => { for (key, value) in span.data().iter() { + if is_sentry_span_attribute(key) { + continue; + } if key != "message" { let key = format!("{name}:{key}"); visitor.json_values.insert(key, value.clone()); @@ -109,6 +112,9 @@ where } TransactionOrSpan::Transaction(transaction) => { for (key, value) in transaction.data().iter() { + if is_sentry_span_attribute(key) { + continue; + } if key != "message" { let key = format!("{name}:{key}"); visitor.json_values.insert(key, value.clone()); @@ -123,6 +129,15 @@ where (message, visitor) } +/// Checks whether the given attribute name is one of those set on a span by the Sentry layer. +/// In that case, we want to skip materializing it when propagating attributes, as it would mostly create noise. +fn is_sentry_span_attribute(name: &str) -> bool { + matches!( + name, + "sentry.tracing.target" | "code.module.name" | "code.file.path" | "code.line.number" + ) +} + /// Records the fields of a [`tracing_core::Event`]. #[derive(Default)] pub(crate) struct FieldVisitor { From 1c08ca867155b030741c7ef6f2617df47f9ed6c4 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian Date: Tue, 23 Sep 2025 09:54:16 +0200 Subject: [PATCH 137/148] ref(tracing): keep old span name as op instead of default (#905) --- CHANGELOG.md | 5 +++-- sentry-tracing/src/layer.rs | 9 +++++---- sentry-tracing/tests/smoke.rs | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0463e7faf..ee941dca1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,9 +6,10 @@ - ref(tracing): rework tracing to Sentry span name/op conversion ([#887](https://github.com/getsentry/sentry-rust/pull/887)) by @lcian - The `tracing` integration now uses the tracing span name as the Sentry span name by default. - - Before this change, the span name would be set based on the `tracing` span target (:: when using the `tracing::instrument` macro). - - The `tracing` integration now uses `default` as the default Sentry span op. + - Before this change, the span name would be set based on the `tracing` span target (`::` when using the `tracing::instrument` macro). + - The `tracing` integration now uses `::` as the default Sentry span op (i.e. `::` when using `tracing::instrument`). - Before this change, the span op would be set based on the `tracing` span name. + - Read below to learn how to customize the span name and op. - When upgrading, please ensure to adapt any queries, metrics or dashboards to use the new span names/ops. - ref(tracing): use standard code attributes ([#899](https://github.com/getsentry/sentry-rust/pull/899)) by @lcian - Logs now carry the attributes `code.module.name`, `code.file.path` and `code.line.number` standardized in OTEL to surface the respective information, in contrast with the previously sent `tracing.module_path`, `tracing.file` and `tracing.line`. diff --git a/sentry-tracing/src/layer.rs b/sentry-tracing/src/layer.rs index d7de47ad4..d02c0496d 100644 --- a/sentry-tracing/src/layer.rs +++ b/sentry-tracing/src/layer.rs @@ -303,22 +303,23 @@ where let (data, sentry_name, sentry_op, sentry_trace) = extract_span_data(attrs); let sentry_name = sentry_name.as_deref().unwrap_or_else(|| span.name()); - let sentry_op = sentry_op.as_deref().unwrap_or("default"); + let sentry_op = + sentry_op.unwrap_or_else(|| format!("{}::{}", span.metadata().target(), span.name())); let hub = sentry_core::Hub::current(); let parent_sentry_span = hub.configure_scope(|scope| scope.get_span()); let mut sentry_span: sentry_core::TransactionOrSpan = match &parent_sentry_span { - Some(parent) => parent.start_child(sentry_op, sentry_name).into(), + Some(parent) => parent.start_child(&sentry_op, sentry_name).into(), None => { let ctx = if let Some(trace_header) = sentry_trace { sentry_core::TransactionContext::continue_from_headers( sentry_name, - sentry_op, + &sentry_op, [("sentry-trace", trace_header.as_str())], ) } else { - sentry_core::TransactionContext::new(sentry_name, sentry_op) + sentry_core::TransactionContext::new(sentry_name, &sentry_op) }; let tx = sentry_core::start_transaction(ctx); diff --git a/sentry-tracing/tests/smoke.rs b/sentry-tracing/tests/smoke.rs index 570800cda..5778c662c 100644 --- a/sentry-tracing/tests/smoke.rs +++ b/sentry-tracing/tests/smoke.rs @@ -24,7 +24,7 @@ fn should_instrument_function_with_event() { sentry::protocol::Context::Trace(trace) => trace, unexpected => panic!("Expected trace context but got {unexpected:?}"), }; - assert_eq!(trace.op.as_deref().unwrap(), "default"); + assert_eq!(trace.op.as_deref().unwrap(), "smoke::function_with_tags"); //Confirm transaction values let transaction = data.get(1).expect("should have 1 transaction"); From b08b24a057370f9c5894faec4b9c0b7875f16d7d Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Wed, 24 Sep 2025 09:08:26 +0000 Subject: [PATCH 138/148] release: 0.43.0 --- CHANGELOG.md | 2 +- Cargo.lock | 28 ++++++++++----------- sentry-actix/Cargo.toml | 4 +-- sentry-anyhow/Cargo.toml | 6 ++--- sentry-backtrace/Cargo.toml | 4 +-- sentry-contexts/Cargo.toml | 4 +-- sentry-core/Cargo.toml | 4 +-- sentry-core/README.md | 2 +- sentry-debug-images/Cargo.toml | 4 +-- sentry-debug-images/README.md | 2 +- sentry-log/Cargo.toml | 4 +-- sentry-opentelemetry/Cargo.toml | 4 +-- sentry-panic/Cargo.toml | 6 ++--- sentry-slog/Cargo.toml | 4 +-- sentry-tower/Cargo.toml | 4 +-- sentry-tower/README.md | 15 ++++++++++- sentry-tracing/Cargo.toml | 6 ++--- sentry-tracing/README.md | 44 ++++++++++++++++++++++++++++++--- sentry-types/Cargo.toml | 2 +- sentry/Cargo.toml | 26 +++++++++---------- sentry/README.md | 12 ++++----- 21 files changed, 118 insertions(+), 69 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee941dca1..1b6cd5e90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 0.43.0 ### Breaking changes diff --git a/Cargo.lock b/Cargo.lock index 7c7d3f82e..6a7469908 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3152,7 +3152,7 @@ dependencies = [ [[package]] name = "sentry" -version = "0.42.0" +version = "0.43.0" dependencies = [ "actix-web", "anyhow", @@ -3188,7 +3188,7 @@ dependencies = [ [[package]] name = "sentry-actix" -version = "0.42.0" +version = "0.43.0" dependencies = [ "actix-http", "actix-web", @@ -3202,7 +3202,7 @@ dependencies = [ [[package]] name = "sentry-anyhow" -version = "0.42.0" +version = "0.43.0" dependencies = [ "anyhow", "sentry", @@ -3212,7 +3212,7 @@ dependencies = [ [[package]] name = "sentry-backtrace" -version = "0.42.0" +version = "0.43.0" dependencies = [ "backtrace", "regex", @@ -3221,7 +3221,7 @@ dependencies = [ [[package]] name = "sentry-contexts" -version = "0.42.0" +version = "0.43.0" dependencies = [ "hostname", "libc", @@ -3234,7 +3234,7 @@ dependencies = [ [[package]] name = "sentry-core" -version = "0.42.0" +version = "0.43.0" dependencies = [ "anyhow", "criterion", @@ -3254,7 +3254,7 @@ dependencies = [ [[package]] name = "sentry-debug-images" -version = "0.42.0" +version = "0.43.0" dependencies = [ "findshlibs", "sentry-core", @@ -3262,7 +3262,7 @@ dependencies = [ [[package]] name = "sentry-log" -version = "0.42.0" +version = "0.43.0" dependencies = [ "log", "pretty_env_logger", @@ -3272,7 +3272,7 @@ dependencies = [ [[package]] name = "sentry-opentelemetry" -version = "0.42.0" +version = "0.43.0" dependencies = [ "opentelemetry", "opentelemetry_sdk", @@ -3282,7 +3282,7 @@ dependencies = [ [[package]] name = "sentry-panic" -version = "0.42.0" +version = "0.43.0" dependencies = [ "sentry", "sentry-backtrace", @@ -3291,7 +3291,7 @@ dependencies = [ [[package]] name = "sentry-slog" -version = "0.42.0" +version = "0.43.0" dependencies = [ "erased-serde", "sentry", @@ -3303,7 +3303,7 @@ dependencies = [ [[package]] name = "sentry-tower" -version = "0.42.0" +version = "0.43.0" dependencies = [ "anyhow", "axum 0.8.3", @@ -3323,7 +3323,7 @@ dependencies = [ [[package]] name = "sentry-tracing" -version = "0.42.0" +version = "0.43.0" dependencies = [ "bitflags 2.9.1", "log", @@ -3339,7 +3339,7 @@ dependencies = [ [[package]] name = "sentry-types" -version = "0.42.0" +version = "0.43.0" dependencies = [ "debugid", "hex", diff --git a/sentry-actix/Cargo.toml b/sentry-actix/Cargo.toml index b817e5e73..fa7424b2c 100644 --- a/sentry-actix/Cargo.toml +++ b/sentry-actix/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-actix" -version = "0.42.0" +version = "0.43.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -20,7 +20,7 @@ release-health = ["sentry-core/release-health"] actix-web = { version = "4", default-features = false } bytes = "1.2" futures-util = { version = "0.3.5", default-features = false } -sentry-core = { version = "0.42.0", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.43.0", path = "../sentry-core", default-features = false, features = [ "client", ] } actix-http = "3.10" diff --git a/sentry-anyhow/Cargo.toml b/sentry-anyhow/Cargo.toml index 204696124..eadff0ac5 100644 --- a/sentry-anyhow/Cargo.toml +++ b/sentry-anyhow/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-anyhow" -version = "0.42.0" +version = "0.43.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -17,8 +17,8 @@ default = ["backtrace"] backtrace = [] [dependencies] -sentry-backtrace = { version = "0.42.0", path = "../sentry-backtrace" } -sentry-core = { version = "0.42.0", path = "../sentry-core" } +sentry-backtrace = { version = "0.43.0", path = "../sentry-backtrace" } +sentry-core = { version = "0.43.0", path = "../sentry-core" } anyhow = "1.0.77" [dev-dependencies] diff --git a/sentry-backtrace/Cargo.toml b/sentry-backtrace/Cargo.toml index 3661e7016..1a7c21f24 100644 --- a/sentry-backtrace/Cargo.toml +++ b/sentry-backtrace/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-backtrace" -version = "0.42.0" +version = "0.43.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -18,4 +18,4 @@ regex = { version = "1.5.5", default-features = false, features = [ "std", "unicode-perl", ] } -sentry-core = { version = "0.42.0", path = "../sentry-core" } +sentry-core = { version = "0.43.0", path = "../sentry-core" } diff --git a/sentry-contexts/Cargo.toml b/sentry-contexts/Cargo.toml index 64ea2a6bf..2dee512c3 100644 --- a/sentry-contexts/Cargo.toml +++ b/sentry-contexts/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-contexts" -version = "0.42.0" +version = "0.43.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -14,7 +14,7 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.42.0", path = "../sentry-core" } +sentry-core = { version = "0.43.0", path = "../sentry-core" } libc = "0.2.66" hostname = "0.4" diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index c97f9d004..9c3fc6a57 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-core" -version = "0.42.0" +version = "0.43.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -29,7 +29,7 @@ logs = [] [dependencies] log = { version = "0.4.8", optional = true, features = ["std"] } rand = { version = "0.9.0", optional = true } -sentry-types = { version = "0.42.0", path = "../sentry-types" } +sentry-types = { version = "0.43.0", path = "../sentry-types" } serde = { version = "1.0.104", features = ["derive"] } serde_json = { version = "1.0.46" } url = { version = "2.1.1" } diff --git a/sentry-core/README.md b/sentry-core/README.md index 720149b1f..3d3c20997 100644 --- a/sentry-core/README.md +++ b/sentry-core/README.md @@ -99,7 +99,7 @@ functionality. [Sentry]: https://sentry.io/ [`sentry`]: https://crates.io/crates/sentry [Unified API]: https://develop.sentry.dev/sdk/unified-api/ -[`test`]: https://docs.rs/sentry-core/0.42.0/sentry_core/test/index.html +[`test`]: https://docs.rs/sentry-core/0.43.0/sentry_core/test/index.html ## Resources diff --git a/sentry-debug-images/Cargo.toml b/sentry-debug-images/Cargo.toml index 8f8a27971..a1550946b 100644 --- a/sentry-debug-images/Cargo.toml +++ b/sentry-debug-images/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-debug-images" -version = "0.42.0" +version = "0.43.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -14,4 +14,4 @@ rust-version = "1.81" [dependencies] findshlibs = "=0.10.2" -sentry-core = { version = "0.42.0", path = "../sentry-core" } +sentry-core = { version = "0.43.0", path = "../sentry-core" } diff --git a/sentry-debug-images/README.md b/sentry-debug-images/README.md index ee41563a4..5c7eddbd5 100644 --- a/sentry-debug-images/README.md +++ b/sentry-debug-images/README.md @@ -22,7 +22,7 @@ let integration = sentry_debug_images::DebugImagesIntegration::new() .filter(|event| event.level >= Level::Warning); ``` -[`Event`]: https://docs.rs/sentry-debug-images/0.42.0/sentry_debug_images/sentry_core::protocol::Event +[`Event`]: https://docs.rs/sentry-debug-images/0.43.0/sentry_debug_images/sentry_core::protocol::Event ## Resources diff --git a/sentry-log/Cargo.toml b/sentry-log/Cargo.toml index 049d6951a..4559551d0 100644 --- a/sentry-log/Cargo.toml +++ b/sentry-log/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-log" -version = "0.42.0" +version = "0.43.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -17,7 +17,7 @@ default = [] logs = ["sentry-core/logs"] [dependencies] -sentry-core = { version = "0.42.0", path = "../sentry-core" } +sentry-core = { version = "0.43.0", path = "../sentry-core" } log = { version = "0.4.8", features = ["std", "kv"] } [dev-dependencies] diff --git a/sentry-opentelemetry/Cargo.toml b/sentry-opentelemetry/Cargo.toml index 7d8b84d49..6edc3c17b 100644 --- a/sentry-opentelemetry/Cargo.toml +++ b/sentry-opentelemetry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-opentelemetry" -version = "0.42.0" +version = "0.43.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -16,7 +16,7 @@ rust-version = "1.81" all-features = true [dependencies] -sentry-core = { version = "0.42.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.43.0", path = "../sentry-core", features = [ "client", ] } opentelemetry = { version = "0.29.0", default-features = false } diff --git a/sentry-panic/Cargo.toml b/sentry-panic/Cargo.toml index 964fe7265..4accf4e61 100644 --- a/sentry-panic/Cargo.toml +++ b/sentry-panic/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-panic" -version = "0.42.0" +version = "0.43.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -13,8 +13,8 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.42.0", path = "../sentry-core", features = ["client"] } -sentry-backtrace = { version = "0.42.0", path = "../sentry-backtrace" } +sentry-core = { version = "0.43.0", path = "../sentry-core", features = ["client"] } +sentry-backtrace = { version = "0.43.0", path = "../sentry-backtrace" } [dev-dependencies] sentry = { path = "../sentry", default-features = false, features = ["test"] } diff --git a/sentry-slog/Cargo.toml b/sentry-slog/Cargo.toml index f78bec304..5c2ab1f38 100644 --- a/sentry-slog/Cargo.toml +++ b/sentry-slog/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-slog" -version = "0.42.0" +version = "0.43.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.42.0", path = "../sentry-core" } +sentry-core = { version = "0.43.0", path = "../sentry-core" } slog = { version = "2.5.2", features = ["nested-values"] } serde_json = "1.0.46" diff --git a/sentry-tower/Cargo.toml b/sentry-tower/Cargo.toml index 1fc8ab10d..4f3d98a1e 100644 --- a/sentry-tower/Cargo.toml +++ b/sentry-tower/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tower" -version = "0.42.0" +version = "0.43.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -26,7 +26,7 @@ tower-layer = "0.3" tower-service = "0.3" http = { version = "1.0.0", optional = true } pin-project = { version = "1.0.10", optional = true } -sentry-core = { version = "0.42.0", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.43.0", path = "../sentry-core", default-features = false, features = [ "client", ] } url = { version = "2.2.2", optional = true } diff --git a/sentry-tower/README.md b/sentry-tower/README.md index 6cf8c2aa4..cd3aea7a9 100644 --- a/sentry-tower/README.md +++ b/sentry-tower/README.md @@ -103,7 +103,7 @@ feature of the `sentry` crate instead of the `tower` feature. The created transaction will automatically use the request URI as its name. This is sometimes not desirable in case the request URI contains unique IDs or similar. In this case, users should manually override the transaction name -in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.42.0/sentry_tower/sentry_core::Scope::set_transaction) +in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.43.0/sentry_tower/sentry_core::Scope::set_transaction) method. When combining both layers, take care of the ordering of both. For example @@ -116,6 +116,19 @@ let layer = tower::ServiceBuilder::new() .layer(sentry_tower::SentryHttpLayer::new().enable_transaction()); ``` +When using `axum`, either use [`tower::ServiceBuilder`] as shown above, or make sure you +reorder the layers, like so: + +```rust +let app = Router::new() + .route("/", get(handler)) + .layer(sentry_tower::SentryHttpLayer::new().enable_transaction()) + .layer(sentry_tower::NewSentryLayer::::new_from_top()) +``` + +This is because `axum` applies middleware in the opposite order as [`tower::ServiceBuilder`]. +Applying the layers in the wrong order can result in memory leaks. + [`tower::ServiceBuilder`]: https://docs.rs/tower/latest/tower/struct.ServiceBuilder.html ## Resources diff --git a/sentry-tracing/Cargo.toml b/sentry-tracing/Cargo.toml index d3ff3a4a9..07a6ec456 100644 --- a/sentry-tracing/Cargo.toml +++ b/sentry-tracing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tracing" -version = "0.42.0" +version = "0.43.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -21,14 +21,14 @@ backtrace = ["dep:sentry-backtrace"] logs = ["sentry-core/logs"] [dependencies] -sentry-core = { version = "0.42.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.43.0", path = "../sentry-core", features = [ "client", ] } tracing-core = "0.1" tracing-subscriber = { version = "0.3.20", default-features = false, features = [ "std", ] } -sentry-backtrace = { version = "0.42.0", path = "../sentry-backtrace", optional = true } +sentry-backtrace = { version = "0.43.0", path = "../sentry-backtrace", optional = true } bitflags = "2.0.0" [dev-dependencies] diff --git a/sentry-tracing/README.md b/sentry-tracing/README.md index fcd9206ed..3bbcd4984 100644 --- a/sentry-tracing/README.md +++ b/sentry-tracing/README.md @@ -121,7 +121,7 @@ tracing::error!( ); ``` -To track [error structs](https://docs.rs/sentry-tracing/0.42.0/sentry_tracing/std::error::Error), assign a reference to error trait object as field +To track [error structs](https://docs.rs/sentry-tracing/0.43.0/sentry_tracing/std::error::Error), assign a reference to error trait object as field in one of the logging macros. By convention, it is recommended to use the `ERROR` level and assign it to a field called `error`, although the integration will also work with all other levels and field names. @@ -177,7 +177,7 @@ If you're using a custom event mapper instead of an event filter, use `EventMapp ## Tracing Spans The integration automatically tracks `tracing` spans as spans in Sentry. A convenient way to do -this is with the `#[instrument]` attribute macro, which creates a transaction for the function +this is with the `#[instrument]` attribute macro, which creates a span/transaction for the function in Sentry. Function arguments are added as context fields automatically, which can be configured through @@ -188,8 +188,8 @@ use std::time::Duration; use tracing_subscriber::prelude::*; -// Functions instrumented by tracing automatically report -// their span as transactions. +// Functions instrumented by tracing automatically +// create spans/transactions around their execution. #[tracing::instrument] async fn outer() { for i in 0..10 { @@ -207,6 +207,42 @@ async fn inner(i: u32) { } ``` +By default, the name of the span sent to Sentry matches the name of the `tracing` span, which +is the name of the function when using `tracing::instrument`, or the name passed to the +`tracing::_span` macros. + +By default, the `op` of the span sent to Sentry is `default`. + +### Special Span Fields + +Some fields on spans are treated specially by the Sentry tracing integration: +- `sentry.name`: overrides the span name sent to Sentry. + This is useful to customize the span name when using `#[tracing::instrument]`, or to update + it retroactively (using `span.record`) after the span has been created. +- `sentry.op`: overrides the span `op` sent to Sentry. +- `sentry.trace`: in Sentry, the `sentry-trace` header is sent with HTTP requests to achieve distributed tracing. + If the value of this field is set to the value of a valid `sentry-trace` header, which + other Sentry SDKs send automatically with outgoing requests, then the SDK will continue the trace using the given distributed tracing information. + This is useful to achieve distributed tracing at service boundaries by using only the + `tracing` API. + Note that `sentry.trace` will only be effective on span creation (it cannot be applied retroactively) + and requires the span it's applied to to be a root span, i.e. no span should active upon its + creation. + + +Example: + +```rust +#[tracing::instrument(skip_all, fields( + sentry.name = "GET /payments", + sentry.op = "http.server", + sentry.trace = headers.get("sentry-trace").unwrap_or(&"".to_owned()), +))] +async fn handle_request(headers: std::collections::HashMap) { + // ... +} +``` + ## Resources License: MIT diff --git a/sentry-types/Cargo.toml b/sentry-types/Cargo.toml index 14c5162cb..9b42fd5c5 100644 --- a/sentry-types/Cargo.toml +++ b/sentry-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-types" -version = "0.42.0" +version = "0.43.0" authors = ["Sentry "] license = "MIT" readme = "README.md" diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index 4974a7cee..98a134c90 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry" -version = "0.42.0" +version = "0.43.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -60,20 +60,20 @@ rustls = ["dep:rustls", "reqwest?/rustls-tls", "ureq?/rustls"] embedded-svc-http = ["dep:embedded-svc", "dep:esp-idf-svc"] [dependencies] -sentry-core = { version = "0.42.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.43.0", path = "../sentry-core", features = [ "client", ] } -sentry-anyhow = { version = "0.42.0", path = "../sentry-anyhow", optional = true } -sentry-actix = { version = "0.42.0", path = "../sentry-actix", optional = true, default-features = false } -sentry-backtrace = { version = "0.42.0", path = "../sentry-backtrace", optional = true } -sentry-contexts = { version = "0.42.0", path = "../sentry-contexts", optional = true } -sentry-debug-images = { version = "0.42.0", path = "../sentry-debug-images", optional = true } -sentry-log = { version = "0.42.0", path = "../sentry-log", optional = true } -sentry-panic = { version = "0.42.0", path = "../sentry-panic", optional = true } -sentry-slog = { version = "0.42.0", path = "../sentry-slog", optional = true } -sentry-tower = { version = "0.42.0", path = "../sentry-tower", optional = true } -sentry-tracing = { version = "0.42.0", path = "../sentry-tracing", optional = true } -sentry-opentelemetry = { version = "0.42.0", path = "../sentry-opentelemetry", optional = true } +sentry-anyhow = { version = "0.43.0", path = "../sentry-anyhow", optional = true } +sentry-actix = { version = "0.43.0", path = "../sentry-actix", optional = true, default-features = false } +sentry-backtrace = { version = "0.43.0", path = "../sentry-backtrace", optional = true } +sentry-contexts = { version = "0.43.0", path = "../sentry-contexts", optional = true } +sentry-debug-images = { version = "0.43.0", path = "../sentry-debug-images", optional = true } +sentry-log = { version = "0.43.0", path = "../sentry-log", optional = true } +sentry-panic = { version = "0.43.0", path = "../sentry-panic", optional = true } +sentry-slog = { version = "0.43.0", path = "../sentry-slog", optional = true } +sentry-tower = { version = "0.43.0", path = "../sentry-tower", optional = true } +sentry-tracing = { version = "0.43.0", path = "../sentry-tracing", optional = true } +sentry-opentelemetry = { version = "0.43.0", path = "../sentry-opentelemetry", optional = true } reqwest = { version = "0.12", optional = true, features = [ "blocking", "json", diff --git a/sentry/README.md b/sentry/README.md index fb5060077..7223f2cc5 100644 --- a/sentry/README.md +++ b/sentry/README.md @@ -34,8 +34,8 @@ sentry::capture_message("Hello World!", sentry::Level::Info); More complex examples on how to use sentry can also be found in [examples]. Extended instructions may also be found on [Sentry itself]. -[`sentry::init`]: https://docs.rs/sentry/0.42.0/sentry/fn.init.html -[`Hub`]: https://docs.rs/sentry/0.42.0/sentry/struct.Hub.html +[`sentry::init`]: https://docs.rs/sentry/0.43.0/sentry/fn.init.html +[`Hub`]: https://docs.rs/sentry/0.43.0/sentry/struct.Hub.html [examples]: https://github.com/getsentry/sentry-rust/tree/master/sentry/examples [Sentry itself]: https://docs.sentry.io/platforms/rust @@ -47,8 +47,8 @@ the ecosystem require a feature flag. For available integrations and how to use [integrations] and [apply_defaults]. [Features]: #features -[integrations]: https://docs.rs/sentry/0.42.0/sentry/integrations/index.html -[apply_defaults]: https://docs.rs/sentry/0.42.0/sentry/fn.apply_defaults.html +[integrations]: https://docs.rs/sentry/0.43.0/sentry/integrations/index.html +[apply_defaults]: https://docs.rs/sentry/0.43.0/sentry/fn.apply_defaults.html ## Minimal API @@ -56,8 +56,8 @@ This crate comes fully-featured. If the goal is to instrument libraries for usag with sentry, or to extend sentry with a custom [`Integration`] or a [`Transport`], one should use the [`sentry-core`] crate instead. -[`Integration`]: https://docs.rs/sentry/0.42.0/sentry/trait.Integration.html -[`Transport`]: https://docs.rs/sentry/0.42.0/sentry/trait.Transport.html +[`Integration`]: https://docs.rs/sentry/0.43.0/sentry/trait.Integration.html +[`Transport`]: https://docs.rs/sentry/0.43.0/sentry/trait.Transport.html [`sentry-core`]: https://crates.io/crates/sentry-core From 750dec01620d77e7f62849b62bcdf20da1faf254 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian <17258265+lcian@users.noreply.github.com> Date: Tue, 30 Sep 2025 13:47:11 +0200 Subject: [PATCH 139/148] ci: integrate Sentry Prevent (#911) --- .config/nextest.toml | 5 +++++ .github/workflows/ci.yml | 15 +++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 .config/nextest.toml diff --git a/.config/nextest.toml b/.config/nextest.toml new file mode 100644 index 000000000..6a109e171 --- /dev/null +++ b/.config/nextest.toml @@ -0,0 +1,5 @@ +[profile.ci] +fail-fast = false + +[profile.ci.junit] +path = "junit.xml" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a26c3cf27..87f0dd07c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,6 +50,8 @@ jobs: name: Test using Rust stable on ${{ matrix.os }} runs-on: ${{ matrix.os }} + permissions: + id-token: write # required by `getsentry/prevent-action` steps: - name: Checkout sources @@ -57,8 +59,17 @@ jobs: - uses: Swatinem/rust-cache@v2 - - name: Run cargo test - run: cargo test --workspace --all-features --all-targets + - uses: taiki-e/install-action@nextest + + - name: Run tests with nextest + run: cargo nextest run --profile ci --all-features --all-targets + + - name: Upload test results to Sentry Prevent + if: ${{ !cancelled() }} + uses: getsentry/prevent-action@v0 + with: + files: target/nextest/ci/junit.xml + disable_search: true MSRV: strategy: From 9ba9a6452df7b8e828030f4d91ebd0c6664b6707 Mon Sep 17 00:00:00 2001 From: Daniel Szoke <7881302+szokeasaurusrex@users.noreply.github.com> Date: Tue, 30 Sep 2025 16:51:08 +0200 Subject: [PATCH 140/148] meta(vscode): Run `rust-analyzer` with all features (#902) So that rust-analyzer also analyzes feature-flag-guarded portions of code when using VSCode/Cursor --------- Co-authored-by: Lorenzo Cian <17258265+lcian@users.noreply.github.com> --- .vscode/settings.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 23fd35f0e..bd1e33d73 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,4 @@ { - "editor.formatOnSave": true + "editor.formatOnSave": true, + "rust-analyzer.cargo.features": "all" } \ No newline at end of file From 3b78cf86536642f73bf0d548235e06832e200f5e Mon Sep 17 00:00:00 2001 From: Lorenzo Cian <17258265+lcian@users.noreply.github.com> Date: Tue, 7 Oct 2025 11:09:36 +0200 Subject: [PATCH 141/148] feat(log): support combined LogFilters and RecordMappings (#914) --- CHANGELOG.md | 9 +++ Cargo.lock | 29 +++---- sentry-log/Cargo.toml | 1 + sentry-log/src/lib.rs | 36 +++++++++ sentry-log/src/logger.rs | 96 ++++++++++++++--------- sentry-tracing/Cargo.toml | 2 +- sentry/tests/test_log_combined_filters.rs | 37 +++++++++ 7 files changed, 160 insertions(+), 50 deletions(-) create mode 100644 sentry/tests/test_log_combined_filters.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b6cd5e90..6654e4013 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## Unreleased + +### Breaking changes + +- feat(log): support combined LogFilters and RecordMappings ([#914](https://github.com/getsentry/sentry-rust/pull/914)) by @lcian + - `sentry::integrations::log::LogFilter` has been changed to a `bitflags` struct. + - It's now possible to map a `log` record to multiple items in Sentry by combining multiple log filters in the filter, e.g. `log::Level::ERROR => LogFilter::Event | LogFilter::Log`. + - If using a custom `mapper` instead, it's possible to return a `Vec` to map a `log` record to multiple items in Sentry. + ## 0.43.0 ### Breaking changes diff --git a/Cargo.lock b/Cargo.lock index 6a7469908..ec238430e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,7 +8,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "bytes", "futures-core", "futures-sink", @@ -30,7 +30,7 @@ dependencies = [ "actix-service", "actix-utils", "base64", - "bitflags 2.9.1", + "bitflags 2.9.4", "brotli", "bytes", "bytestring", @@ -445,7 +445,7 @@ version = "0.71.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "cexpr", "clang-sys", "itertools 0.13.0", @@ -467,9 +467,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.1" +version = "2.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" [[package]] name = "block-buffer" @@ -2149,7 +2149,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "libc", "redox_syscall", ] @@ -2306,7 +2306,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "cfg-if", "cfg_aliases", "libc", @@ -2403,7 +2403,7 @@ version = "0.10.72" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "cfg-if", "foreign-types", "libc", @@ -2842,7 +2842,7 @@ version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", ] [[package]] @@ -3018,7 +3018,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "errno", "libc", "linux-raw-sys 0.4.15", @@ -3031,7 +3031,7 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "errno", "libc", "linux-raw-sys 0.9.4", @@ -3124,7 +3124,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "core-foundation", "core-foundation-sys", "libc", @@ -3264,6 +3264,7 @@ dependencies = [ name = "sentry-log" version = "0.43.0" dependencies = [ + "bitflags 2.9.4", "log", "pretty_env_logger", "sentry", @@ -3325,7 +3326,7 @@ dependencies = [ name = "sentry-tracing" version = "0.43.0" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "log", "sentry", "sentry-backtrace", @@ -4506,7 +4507,7 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", ] [[package]] diff --git a/sentry-log/Cargo.toml b/sentry-log/Cargo.toml index 4559551d0..de92399f3 100644 --- a/sentry-log/Cargo.toml +++ b/sentry-log/Cargo.toml @@ -19,6 +19,7 @@ logs = ["sentry-core/logs"] [dependencies] sentry-core = { version = "0.43.0", path = "../sentry-core" } log = { version = "0.4.8", features = ["std", "kv"] } +bitflags = "2.9.4" [dev-dependencies] sentry = { path = "../sentry", default-features = false, features = ["test"] } diff --git a/sentry-log/src/lib.rs b/sentry-log/src/lib.rs index 56d986539..2c2d56c5b 100644 --- a/sentry-log/src/lib.rs +++ b/sentry-log/src/lib.rs @@ -46,6 +46,42 @@ //! _ => LogFilter::Ignore, //! }); //! ``` +//! +//! # Sending multiple items to Sentry +//! +//! To map a log record to multiple items in Sentry, you can combine multiple log filters +//! using the bitwise or operator: +//! +//! ``` +//! use sentry_log::LogFilter; +//! +//! let logger = sentry_log::SentryLogger::new().filter(|md| match md.level() { +//! log::Level::Error => LogFilter::Event, +//! log::Level::Warn => LogFilter::Breadcrumb | LogFilter::Log, +//! _ => LogFilter::Ignore, +//! }); +//! ``` +//! +//! If you're using a custom record mapper instead of a filter, you can return a `Vec` +//! from your mapper function to send multiple items to Sentry from a single log record: +//! +//! ``` +//! use sentry_log::{RecordMapping, SentryLogger, event_from_record, breadcrumb_from_record}; +//! +//! let logger = SentryLogger::new().mapper(|record| { +//! match record.level() { +//! log::Level::Error => { +//! // Send both an event and a breadcrumb for errors +//! vec![ +//! RecordMapping::Event(event_from_record(record)), +//! RecordMapping::Breadcrumb(breadcrumb_from_record(record)), +//! ] +//! } +//! log::Level::Warn => RecordMapping::Breadcrumb(breadcrumb_from_record(record)).into(), +//! _ => RecordMapping::Ignore.into(), +//! } +//! }); +//! ``` #![doc(html_favicon_url = "https://sentry-brand.storage.googleapis.com/favicon.ico")] #![doc(html_logo_url = "https://sentry-brand.storage.googleapis.com/sentry-glyph-black.png")] diff --git a/sentry-log/src/logger.rs b/sentry-log/src/logger.rs index 7308afa95..0b5177d1d 100644 --- a/sentry-log/src/logger.rs +++ b/sentry-log/src/logger.rs @@ -1,24 +1,28 @@ use log::Record; use sentry_core::protocol::{Breadcrumb, Event}; +use bitflags::bitflags; + #[cfg(feature = "logs")] use crate::converters::log_from_record; use crate::converters::{breadcrumb_from_record, event_from_record, exception_from_record}; -/// The action that Sentry should perform for a [`log::Metadata`]. -#[derive(Debug)] -pub enum LogFilter { - /// Ignore the [`Record`]. - Ignore, - /// Create a [`Breadcrumb`] from this [`Record`]. - Breadcrumb, - /// Create a message [`Event`] from this [`Record`]. - Event, - /// Create an exception [`Event`] from this [`Record`]. - Exception, - /// Create a [`sentry_core::protocol::Log`] from this [`Record`]. - #[cfg(feature = "logs")] - Log, +bitflags! { + /// The action that Sentry should perform for a [`log::Metadata`]. + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + pub struct LogFilter: u32 { + /// Ignore the [`Record`]. + const Ignore = 0b0000; + /// Create a [`Breadcrumb`] from this [`Record`]. + const Breadcrumb = 0b0001; + /// Create a message [`Event`] from this [`Record`]. + const Event = 0b0010; + /// Create an exception [`Event`] from this [`Record`]. + const Exception = 0b0100; + /// Create a [`sentry_core::protocol::Log`] from this [`Record`]. + #[cfg(feature = "logs")] + const Log = 0b1000; + } } /// The type of Data Sentry should ingest for a [`log::Record`]. @@ -36,6 +40,12 @@ pub enum RecordMapping { Log(sentry_core::protocol::Log), } +impl From for Vec { + fn from(mapping: RecordMapping) -> Self { + vec![mapping] + } +} + /// The default log filter. /// /// By default, an exception event is captured for `error`, a breadcrumb for @@ -73,7 +83,7 @@ pub struct SentryLogger { dest: L, filter: Box) -> LogFilter + Send + Sync>, #[allow(clippy::type_complexity)] - mapper: Option) -> RecordMapping + Send + Sync>>, + mapper: Option) -> Vec + Send + Sync>>, } impl Default for SentryLogger { @@ -119,43 +129,59 @@ impl SentryLogger { /// Sets a custom mapper function. /// /// The mapper is responsible for creating either breadcrumbs or events - /// from [`Record`]s. + /// from [`Record`]s. It can return either a single [`RecordMapping`] or + /// a `Vec` to send multiple items to Sentry from one log record. #[must_use] - pub fn mapper(mut self, mapper: M) -> Self + pub fn mapper(mut self, mapper: M) -> Self where - M: Fn(&Record<'_>) -> RecordMapping + Send + Sync + 'static, + M: Fn(&Record<'_>) -> T + Send + Sync + 'static, + T: Into>, { - self.mapper = Some(Box::new(mapper)); + self.mapper = Some(Box::new(move |record| mapper(record).into())); self } } impl log::Log for SentryLogger { fn enabled(&self, metadata: &log::Metadata<'_>) -> bool { - self.dest.enabled(metadata) || !matches!((self.filter)(metadata), LogFilter::Ignore) + self.dest.enabled(metadata) || !((self.filter)(metadata) == LogFilter::Ignore) } fn log(&self, record: &log::Record<'_>) { - let item: RecordMapping = match &self.mapper { + let items = match &self.mapper { Some(mapper) => mapper(record), - None => match (self.filter)(record.metadata()) { - LogFilter::Ignore => RecordMapping::Ignore, - LogFilter::Breadcrumb => RecordMapping::Breadcrumb(breadcrumb_from_record(record)), - LogFilter::Event => RecordMapping::Event(event_from_record(record)), - LogFilter::Exception => RecordMapping::Event(exception_from_record(record)), + None => { + let filter = (self.filter)(record.metadata()); + let mut items = vec![]; + if filter.contains(LogFilter::Breadcrumb) { + items.push(RecordMapping::Breadcrumb(breadcrumb_from_record(record))); + } + if filter.contains(LogFilter::Event) { + items.push(RecordMapping::Event(event_from_record(record))); + } + if filter.contains(LogFilter::Exception) { + items.push(RecordMapping::Event(exception_from_record(record))); + } #[cfg(feature = "logs")] - LogFilter::Log => RecordMapping::Log(log_from_record(record)), - }, + if filter.contains(LogFilter::Log) { + items.push(RecordMapping::Log(log_from_record(record))); + } + items + } }; - match item { - RecordMapping::Ignore => {} - RecordMapping::Breadcrumb(b) => sentry_core::add_breadcrumb(b), - RecordMapping::Event(e) => { - sentry_core::capture_event(e); + for mapping in items { + match mapping { + RecordMapping::Ignore => {} + RecordMapping::Breadcrumb(breadcrumb) => sentry_core::add_breadcrumb(breadcrumb), + RecordMapping::Event(event) => { + sentry_core::capture_event(event); + } + #[cfg(feature = "logs")] + RecordMapping::Log(log) => { + sentry_core::Hub::with_active(|hub| hub.capture_log(log)) + } } - #[cfg(feature = "logs")] - RecordMapping::Log(log) => sentry_core::Hub::with_active(|hub| hub.capture_log(log)), } self.dest.log(record) diff --git a/sentry-tracing/Cargo.toml b/sentry-tracing/Cargo.toml index 07a6ec456..be30833e6 100644 --- a/sentry-tracing/Cargo.toml +++ b/sentry-tracing/Cargo.toml @@ -29,7 +29,7 @@ tracing-subscriber = { version = "0.3.20", default-features = false, features = "std", ] } sentry-backtrace = { version = "0.43.0", path = "../sentry-backtrace", optional = true } -bitflags = "2.0.0" +bitflags = "2.9.4" [dev-dependencies] log = "0.4" diff --git a/sentry/tests/test_log_combined_filters.rs b/sentry/tests/test_log_combined_filters.rs new file mode 100644 index 000000000..3342743ba --- /dev/null +++ b/sentry/tests/test_log_combined_filters.rs @@ -0,0 +1,37 @@ +#![cfg(feature = "test")] + +// Test `log` integration with combined `LogFilter`s. +// This must be in a separate file because `log::set_boxed_logger` can only be called once. + +#[test] +fn test_log_combined_filters() { + let logger = sentry_log::SentryLogger::new().filter(|md| match md.level() { + log::Level::Error => sentry_log::LogFilter::Breadcrumb | sentry_log::LogFilter::Event, + log::Level::Warn => sentry_log::LogFilter::Event, + _ => sentry_log::LogFilter::Ignore, + }); + + log::set_boxed_logger(Box::new(logger)) + .map(|()| log::set_max_level(log::LevelFilter::Trace)) + .unwrap(); + + let events = sentry::test::with_captured_events(|| { + log::error!("Both a breadcrumb and an event"); + log::warn!("An event"); + log::trace!("Ignored"); + }); + + assert_eq!(events.len(), 2); + + assert_eq!( + events[0].message, + Some("Both a breadcrumb and an event".to_owned()) + ); + + assert_eq!(events[1].message, Some("An event".to_owned())); + assert_eq!(events[1].breadcrumbs.len(), 1); + assert_eq!( + events[1].breadcrumbs[0].message, + Some("Both a breadcrumb and an event".into()) + ); +} From 8af23eec27a27e6b640920fc2c70b81584d10449 Mon Sep 17 00:00:00 2001 From: Lorenzo Cian <17258265+lcian@users.noreply.github.com> Date: Tue, 7 Oct 2025 11:39:03 +0200 Subject: [PATCH 142/148] ref(log): send logs by default when logs feature flag is enabled (#915) --- CHANGELOG.md | 5 +++++ sentry-log/src/lib.rs | 11 ++++------- sentry-log/src/logger.rs | 6 ++++++ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6654e4013..5442bc6d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,11 @@ - It's now possible to map a `log` record to multiple items in Sentry by combining multiple log filters in the filter, e.g. `log::Level::ERROR => LogFilter::Event | LogFilter::Log`. - If using a custom `mapper` instead, it's possible to return a `Vec` to map a `log` record to multiple items in Sentry. +### Behavioral changes + +- ref(log): send logs by default when logs feature flag is enabled ([#915](https://github.com/getsentry/sentry-rust/pull/915)) + - If the `logs` feature flag is enabled, the default Sentry `log` logger now sends logs for all events at or above INFO. + ## 0.43.0 ### Breaking changes diff --git a/sentry-log/src/lib.rs b/sentry-log/src/lib.rs index 2c2d56c5b..a01e8479f 100644 --- a/sentry-log/src/lib.rs +++ b/sentry-log/src/lib.rs @@ -11,13 +11,10 @@ //! - Records can be captured as traditional [logs](https://docs.sentry.io/product/explore/logs/) //! Logs can be viewed and queried in the Logs explorer. //! -//! By default anything above `Info` is recorded as a breadcrumb and -//! anything above `Error` is captured as error event. -//! -//! To capture records as Sentry logs: -//! 1. Enable the `logs` feature of the `sentry` crate. -//! 2. Initialize the SDK with `enable_logs: true` in your client options. -//! 3. Set up a custom filter (see below) to map records to logs (`LogFilter::Log`) based on criteria such as severity. +//! By default anything at or above `Info` is recorded as a breadcrumb and +//! anything at or above `Error` is captured as error event. +//! Additionally, if the `sentry` crate is used with the `logs` feature flag, anything at or above `Info` +//! is captured as a [Structured Log](https://docs.sentry.io/product/explore/logs/). //! //! # Examples //! diff --git a/sentry-log/src/logger.rs b/sentry-log/src/logger.rs index 0b5177d1d..f6cabd2a9 100644 --- a/sentry-log/src/logger.rs +++ b/sentry-log/src/logger.rs @@ -52,7 +52,13 @@ impl From for Vec { /// `warning` and `info`, and `debug` and `trace` logs are ignored. pub fn default_filter(metadata: &log::Metadata) -> LogFilter { match metadata.level() { + #[cfg(feature = "logs")] + log::Level::Error => LogFilter::Exception | LogFilter::Log, + #[cfg(not(feature = "logs"))] log::Level::Error => LogFilter::Exception, + #[cfg(feature = "logs")] + log::Level::Warn | log::Level::Info => LogFilter::Breadcrumb | LogFilter::Log, + #[cfg(not(feature = "logs"))] log::Level::Warn | log::Level::Info => LogFilter::Breadcrumb, log::Level::Debug | log::Level::Trace => LogFilter::Ignore, } From 900ffa495c653978a8d4423aa9e9df8153b9c59a Mon Sep 17 00:00:00 2001 From: Lorenzo Cian <17258265+lcian@users.noreply.github.com> Date: Tue, 7 Oct 2025 11:44:15 +0200 Subject: [PATCH 143/148] ref(logs): enable logs by default if logs feature flag is used (#910) --- CHANGELOG.md | 8 ++++++-- sentry-core/src/clientoptions.rs | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5442bc6d7..e386d969a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,14 +5,18 @@ ### Breaking changes - feat(log): support combined LogFilters and RecordMappings ([#914](https://github.com/getsentry/sentry-rust/pull/914)) by @lcian - - `sentry::integrations::log::LogFilter` has been changed to a `bitflags` struct. + - Breaking change: `sentry::integrations::log::LogFilter` has been changed to a `bitflags` struct. - It's now possible to map a `log` record to multiple items in Sentry by combining multiple log filters in the filter, e.g. `log::Level::ERROR => LogFilter::Event | LogFilter::Log`. - If using a custom `mapper` instead, it's possible to return a `Vec` to map a `log` record to multiple items in Sentry. ### Behavioral changes -- ref(log): send logs by default when logs feature flag is enabled ([#915](https://github.com/getsentry/sentry-rust/pull/915)) +- ref(log): send logs by default when logs feature flag is enabled ([#915](https://github.com/getsentry/sentry-rust/pull/915)) by @lcian - If the `logs` feature flag is enabled, the default Sentry `log` logger now sends logs for all events at or above INFO. +- ref(logs): enable logs by default if logs feature flag is used ([#910](https://github.com/getsentry/sentry-rust/pull/910)) by @lcian + - This changes the default value of `sentry::ClientOptions::enable_logs` to `true`. + - This simplifies the setup of Sentry structured logs by requiring users to just add the `log` feature flag to the `sentry` dependency to opt-in to sending logs. + - When the `log` feature flag is enabled, the `tracing` and `log` integrations will send structured logs to Sentry for all logs/events at or above INFO level by default. ## 0.43.0 diff --git a/sentry-core/src/clientoptions.rs b/sentry-core/src/clientoptions.rs index ff4a07f95..33b5bbd4c 100644 --- a/sentry-core/src/clientoptions.rs +++ b/sentry-core/src/clientoptions.rs @@ -325,7 +325,7 @@ impl Default for ClientOptions { user_agent: Cow::Borrowed(USER_AGENT), max_request_body_size: MaxRequestBodySize::Medium, #[cfg(feature = "logs")] - enable_logs: false, + enable_logs: true, #[cfg(feature = "logs")] before_send_log: None, } From eb108e858ea289b5b21df3d37b43801f34ba2326 Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Tue, 7 Oct 2025 09:50:21 +0000 Subject: [PATCH 144/148] release: 0.44.0 --- CHANGELOG.md | 2 +- Cargo.lock | 28 ++++++++++---------- sentry-actix/Cargo.toml | 4 +-- sentry-anyhow/Cargo.toml | 6 ++--- sentry-backtrace/Cargo.toml | 4 +-- sentry-contexts/Cargo.toml | 4 +-- sentry-core/Cargo.toml | 4 +-- sentry-core/README.md | 2 +- sentry-debug-images/Cargo.toml | 4 +-- sentry-debug-images/README.md | 2 +- sentry-log/Cargo.toml | 4 +-- sentry-log/README.md | 47 ++++++++++++++++++++++++++++----- sentry-opentelemetry/Cargo.toml | 4 +-- sentry-panic/Cargo.toml | 6 ++--- sentry-slog/Cargo.toml | 4 +-- sentry-tower/Cargo.toml | 4 +-- sentry-tower/README.md | 2 +- sentry-tracing/Cargo.toml | 6 ++--- sentry-tracing/README.md | 2 +- sentry-types/Cargo.toml | 2 +- sentry/Cargo.toml | 26 +++++++++--------- sentry/README.md | 12 ++++----- 22 files changed, 106 insertions(+), 73 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e386d969a..9e3063a0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 0.44.0 ### Breaking changes diff --git a/Cargo.lock b/Cargo.lock index ec238430e..c47dc4c39 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3152,7 +3152,7 @@ dependencies = [ [[package]] name = "sentry" -version = "0.43.0" +version = "0.44.0" dependencies = [ "actix-web", "anyhow", @@ -3188,7 +3188,7 @@ dependencies = [ [[package]] name = "sentry-actix" -version = "0.43.0" +version = "0.44.0" dependencies = [ "actix-http", "actix-web", @@ -3202,7 +3202,7 @@ dependencies = [ [[package]] name = "sentry-anyhow" -version = "0.43.0" +version = "0.44.0" dependencies = [ "anyhow", "sentry", @@ -3212,7 +3212,7 @@ dependencies = [ [[package]] name = "sentry-backtrace" -version = "0.43.0" +version = "0.44.0" dependencies = [ "backtrace", "regex", @@ -3221,7 +3221,7 @@ dependencies = [ [[package]] name = "sentry-contexts" -version = "0.43.0" +version = "0.44.0" dependencies = [ "hostname", "libc", @@ -3234,7 +3234,7 @@ dependencies = [ [[package]] name = "sentry-core" -version = "0.43.0" +version = "0.44.0" dependencies = [ "anyhow", "criterion", @@ -3254,7 +3254,7 @@ dependencies = [ [[package]] name = "sentry-debug-images" -version = "0.43.0" +version = "0.44.0" dependencies = [ "findshlibs", "sentry-core", @@ -3262,7 +3262,7 @@ dependencies = [ [[package]] name = "sentry-log" -version = "0.43.0" +version = "0.44.0" dependencies = [ "bitflags 2.9.4", "log", @@ -3273,7 +3273,7 @@ dependencies = [ [[package]] name = "sentry-opentelemetry" -version = "0.43.0" +version = "0.44.0" dependencies = [ "opentelemetry", "opentelemetry_sdk", @@ -3283,7 +3283,7 @@ dependencies = [ [[package]] name = "sentry-panic" -version = "0.43.0" +version = "0.44.0" dependencies = [ "sentry", "sentry-backtrace", @@ -3292,7 +3292,7 @@ dependencies = [ [[package]] name = "sentry-slog" -version = "0.43.0" +version = "0.44.0" dependencies = [ "erased-serde", "sentry", @@ -3304,7 +3304,7 @@ dependencies = [ [[package]] name = "sentry-tower" -version = "0.43.0" +version = "0.44.0" dependencies = [ "anyhow", "axum 0.8.3", @@ -3324,7 +3324,7 @@ dependencies = [ [[package]] name = "sentry-tracing" -version = "0.43.0" +version = "0.44.0" dependencies = [ "bitflags 2.9.4", "log", @@ -3340,7 +3340,7 @@ dependencies = [ [[package]] name = "sentry-types" -version = "0.43.0" +version = "0.44.0" dependencies = [ "debugid", "hex", diff --git a/sentry-actix/Cargo.toml b/sentry-actix/Cargo.toml index fa7424b2c..1ff43c4bd 100644 --- a/sentry-actix/Cargo.toml +++ b/sentry-actix/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-actix" -version = "0.43.0" +version = "0.44.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -20,7 +20,7 @@ release-health = ["sentry-core/release-health"] actix-web = { version = "4", default-features = false } bytes = "1.2" futures-util = { version = "0.3.5", default-features = false } -sentry-core = { version = "0.43.0", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.44.0", path = "../sentry-core", default-features = false, features = [ "client", ] } actix-http = "3.10" diff --git a/sentry-anyhow/Cargo.toml b/sentry-anyhow/Cargo.toml index eadff0ac5..e8f120ca1 100644 --- a/sentry-anyhow/Cargo.toml +++ b/sentry-anyhow/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-anyhow" -version = "0.43.0" +version = "0.44.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -17,8 +17,8 @@ default = ["backtrace"] backtrace = [] [dependencies] -sentry-backtrace = { version = "0.43.0", path = "../sentry-backtrace" } -sentry-core = { version = "0.43.0", path = "../sentry-core" } +sentry-backtrace = { version = "0.44.0", path = "../sentry-backtrace" } +sentry-core = { version = "0.44.0", path = "../sentry-core" } anyhow = "1.0.77" [dev-dependencies] diff --git a/sentry-backtrace/Cargo.toml b/sentry-backtrace/Cargo.toml index 1a7c21f24..f37ece915 100644 --- a/sentry-backtrace/Cargo.toml +++ b/sentry-backtrace/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-backtrace" -version = "0.43.0" +version = "0.44.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -18,4 +18,4 @@ regex = { version = "1.5.5", default-features = false, features = [ "std", "unicode-perl", ] } -sentry-core = { version = "0.43.0", path = "../sentry-core" } +sentry-core = { version = "0.44.0", path = "../sentry-core" } diff --git a/sentry-contexts/Cargo.toml b/sentry-contexts/Cargo.toml index 2dee512c3..3f7c885ea 100644 --- a/sentry-contexts/Cargo.toml +++ b/sentry-contexts/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-contexts" -version = "0.43.0" +version = "0.44.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -14,7 +14,7 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.43.0", path = "../sentry-core" } +sentry-core = { version = "0.44.0", path = "../sentry-core" } libc = "0.2.66" hostname = "0.4" diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index 9c3fc6a57..764d3030c 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-core" -version = "0.43.0" +version = "0.44.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -29,7 +29,7 @@ logs = [] [dependencies] log = { version = "0.4.8", optional = true, features = ["std"] } rand = { version = "0.9.0", optional = true } -sentry-types = { version = "0.43.0", path = "../sentry-types" } +sentry-types = { version = "0.44.0", path = "../sentry-types" } serde = { version = "1.0.104", features = ["derive"] } serde_json = { version = "1.0.46" } url = { version = "2.1.1" } diff --git a/sentry-core/README.md b/sentry-core/README.md index 3d3c20997..211addac8 100644 --- a/sentry-core/README.md +++ b/sentry-core/README.md @@ -99,7 +99,7 @@ functionality. [Sentry]: https://sentry.io/ [`sentry`]: https://crates.io/crates/sentry [Unified API]: https://develop.sentry.dev/sdk/unified-api/ -[`test`]: https://docs.rs/sentry-core/0.43.0/sentry_core/test/index.html +[`test`]: https://docs.rs/sentry-core/0.44.0/sentry_core/test/index.html ## Resources diff --git a/sentry-debug-images/Cargo.toml b/sentry-debug-images/Cargo.toml index a1550946b..b0a1c4f97 100644 --- a/sentry-debug-images/Cargo.toml +++ b/sentry-debug-images/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-debug-images" -version = "0.43.0" +version = "0.44.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -14,4 +14,4 @@ rust-version = "1.81" [dependencies] findshlibs = "=0.10.2" -sentry-core = { version = "0.43.0", path = "../sentry-core" } +sentry-core = { version = "0.44.0", path = "../sentry-core" } diff --git a/sentry-debug-images/README.md b/sentry-debug-images/README.md index 5c7eddbd5..a7c4a9e6d 100644 --- a/sentry-debug-images/README.md +++ b/sentry-debug-images/README.md @@ -22,7 +22,7 @@ let integration = sentry_debug_images::DebugImagesIntegration::new() .filter(|event| event.level >= Level::Warning); ``` -[`Event`]: https://docs.rs/sentry-debug-images/0.43.0/sentry_debug_images/sentry_core::protocol::Event +[`Event`]: https://docs.rs/sentry-debug-images/0.44.0/sentry_debug_images/sentry_core::protocol::Event ## Resources diff --git a/sentry-log/Cargo.toml b/sentry-log/Cargo.toml index de92399f3..1e20935a8 100644 --- a/sentry-log/Cargo.toml +++ b/sentry-log/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-log" -version = "0.43.0" +version = "0.44.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -17,7 +17,7 @@ default = [] logs = ["sentry-core/logs"] [dependencies] -sentry-core = { version = "0.43.0", path = "../sentry-core" } +sentry-core = { version = "0.44.0", path = "../sentry-core" } log = { version = "0.4.8", features = ["std", "kv"] } bitflags = "2.9.4" diff --git a/sentry-log/README.md b/sentry-log/README.md index 0af6fd8f6..2ee252f66 100644 --- a/sentry-log/README.md +++ b/sentry-log/README.md @@ -19,13 +19,10 @@ The `log` crate is supported in three ways: - Records can be captured as traditional [logs](https://docs.sentry.io/product/explore/logs/) Logs can be viewed and queried in the Logs explorer. -By default anything above `Info` is recorded as a breadcrumb and -anything above `Error` is captured as error event. - -To capture records as Sentry logs: -1. Enable the `logs` feature of the `sentry` crate. -2. Initialize the SDK with `enable_logs: true` in your client options. -3. Set up a custom filter (see below) to map records to logs (`LogFilter::Log`) based on criteria such as severity. +By default anything at or above `Info` is recorded as a breadcrumb and +anything at or above `Error` is captured as error event. +Additionally, if the `sentry` crate is used with the `logs` feature flag, anything at or above `Info` +is captured as a [Structured Log](https://docs.sentry.io/product/explore/logs/). ## Examples @@ -55,6 +52,42 @@ let logger = sentry_log::SentryLogger::new().filter(|md| match md.level() { }); ``` +## Sending multiple items to Sentry + +To map a log record to multiple items in Sentry, you can combine multiple log filters +using the bitwise or operator: + +```rust +use sentry_log::LogFilter; + +let logger = sentry_log::SentryLogger::new().filter(|md| match md.level() { + log::Level::Error => LogFilter::Event, + log::Level::Warn => LogFilter::Breadcrumb | LogFilter::Log, + _ => LogFilter::Ignore, +}); +``` + +If you're using a custom record mapper instead of a filter, you can return a `Vec` +from your mapper function to send multiple items to Sentry from a single log record: + +```rust +use sentry_log::{RecordMapping, SentryLogger, event_from_record, breadcrumb_from_record}; + +let logger = SentryLogger::new().mapper(|record| { + match record.level() { + log::Level::Error => { + // Send both an event and a breadcrumb for errors + vec![ + RecordMapping::Event(event_from_record(record)), + RecordMapping::Breadcrumb(breadcrumb_from_record(record)), + ] + } + log::Level::Warn => RecordMapping::Breadcrumb(breadcrumb_from_record(record)).into(), + _ => RecordMapping::Ignore.into(), + } +}); +``` + ## Resources License: MIT diff --git a/sentry-opentelemetry/Cargo.toml b/sentry-opentelemetry/Cargo.toml index 6edc3c17b..7f67eb5dc 100644 --- a/sentry-opentelemetry/Cargo.toml +++ b/sentry-opentelemetry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-opentelemetry" -version = "0.43.0" +version = "0.44.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -16,7 +16,7 @@ rust-version = "1.81" all-features = true [dependencies] -sentry-core = { version = "0.43.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.44.0", path = "../sentry-core", features = [ "client", ] } opentelemetry = { version = "0.29.0", default-features = false } diff --git a/sentry-panic/Cargo.toml b/sentry-panic/Cargo.toml index 4accf4e61..d358cda99 100644 --- a/sentry-panic/Cargo.toml +++ b/sentry-panic/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-panic" -version = "0.43.0" +version = "0.44.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -13,8 +13,8 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.43.0", path = "../sentry-core", features = ["client"] } -sentry-backtrace = { version = "0.43.0", path = "../sentry-backtrace" } +sentry-core = { version = "0.44.0", path = "../sentry-core", features = ["client"] } +sentry-backtrace = { version = "0.44.0", path = "../sentry-backtrace" } [dev-dependencies] sentry = { path = "../sentry", default-features = false, features = ["test"] } diff --git a/sentry-slog/Cargo.toml b/sentry-slog/Cargo.toml index 5c2ab1f38..eb26ce7fc 100644 --- a/sentry-slog/Cargo.toml +++ b/sentry-slog/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-slog" -version = "0.43.0" +version = "0.44.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.43.0", path = "../sentry-core" } +sentry-core = { version = "0.44.0", path = "../sentry-core" } slog = { version = "2.5.2", features = ["nested-values"] } serde_json = "1.0.46" diff --git a/sentry-tower/Cargo.toml b/sentry-tower/Cargo.toml index 4f3d98a1e..637b33ab2 100644 --- a/sentry-tower/Cargo.toml +++ b/sentry-tower/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tower" -version = "0.43.0" +version = "0.44.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -26,7 +26,7 @@ tower-layer = "0.3" tower-service = "0.3" http = { version = "1.0.0", optional = true } pin-project = { version = "1.0.10", optional = true } -sentry-core = { version = "0.43.0", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.44.0", path = "../sentry-core", default-features = false, features = [ "client", ] } url = { version = "2.2.2", optional = true } diff --git a/sentry-tower/README.md b/sentry-tower/README.md index cd3aea7a9..0c4410e51 100644 --- a/sentry-tower/README.md +++ b/sentry-tower/README.md @@ -103,7 +103,7 @@ feature of the `sentry` crate instead of the `tower` feature. The created transaction will automatically use the request URI as its name. This is sometimes not desirable in case the request URI contains unique IDs or similar. In this case, users should manually override the transaction name -in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.43.0/sentry_tower/sentry_core::Scope::set_transaction) +in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.44.0/sentry_tower/sentry_core::Scope::set_transaction) method. When combining both layers, take care of the ordering of both. For example diff --git a/sentry-tracing/Cargo.toml b/sentry-tracing/Cargo.toml index be30833e6..eb54e361a 100644 --- a/sentry-tracing/Cargo.toml +++ b/sentry-tracing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tracing" -version = "0.43.0" +version = "0.44.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -21,14 +21,14 @@ backtrace = ["dep:sentry-backtrace"] logs = ["sentry-core/logs"] [dependencies] -sentry-core = { version = "0.43.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.44.0", path = "../sentry-core", features = [ "client", ] } tracing-core = "0.1" tracing-subscriber = { version = "0.3.20", default-features = false, features = [ "std", ] } -sentry-backtrace = { version = "0.43.0", path = "../sentry-backtrace", optional = true } +sentry-backtrace = { version = "0.44.0", path = "../sentry-backtrace", optional = true } bitflags = "2.9.4" [dev-dependencies] diff --git a/sentry-tracing/README.md b/sentry-tracing/README.md index 3bbcd4984..5e128aa5f 100644 --- a/sentry-tracing/README.md +++ b/sentry-tracing/README.md @@ -121,7 +121,7 @@ tracing::error!( ); ``` -To track [error structs](https://docs.rs/sentry-tracing/0.43.0/sentry_tracing/std::error::Error), assign a reference to error trait object as field +To track [error structs](https://docs.rs/sentry-tracing/0.44.0/sentry_tracing/std::error::Error), assign a reference to error trait object as field in one of the logging macros. By convention, it is recommended to use the `ERROR` level and assign it to a field called `error`, although the integration will also work with all other levels and field names. diff --git a/sentry-types/Cargo.toml b/sentry-types/Cargo.toml index 9b42fd5c5..e742b9940 100644 --- a/sentry-types/Cargo.toml +++ b/sentry-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-types" -version = "0.43.0" +version = "0.44.0" authors = ["Sentry "] license = "MIT" readme = "README.md" diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index 98a134c90..c3428158d 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry" -version = "0.43.0" +version = "0.44.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -60,20 +60,20 @@ rustls = ["dep:rustls", "reqwest?/rustls-tls", "ureq?/rustls"] embedded-svc-http = ["dep:embedded-svc", "dep:esp-idf-svc"] [dependencies] -sentry-core = { version = "0.43.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.44.0", path = "../sentry-core", features = [ "client", ] } -sentry-anyhow = { version = "0.43.0", path = "../sentry-anyhow", optional = true } -sentry-actix = { version = "0.43.0", path = "../sentry-actix", optional = true, default-features = false } -sentry-backtrace = { version = "0.43.0", path = "../sentry-backtrace", optional = true } -sentry-contexts = { version = "0.43.0", path = "../sentry-contexts", optional = true } -sentry-debug-images = { version = "0.43.0", path = "../sentry-debug-images", optional = true } -sentry-log = { version = "0.43.0", path = "../sentry-log", optional = true } -sentry-panic = { version = "0.43.0", path = "../sentry-panic", optional = true } -sentry-slog = { version = "0.43.0", path = "../sentry-slog", optional = true } -sentry-tower = { version = "0.43.0", path = "../sentry-tower", optional = true } -sentry-tracing = { version = "0.43.0", path = "../sentry-tracing", optional = true } -sentry-opentelemetry = { version = "0.43.0", path = "../sentry-opentelemetry", optional = true } +sentry-anyhow = { version = "0.44.0", path = "../sentry-anyhow", optional = true } +sentry-actix = { version = "0.44.0", path = "../sentry-actix", optional = true, default-features = false } +sentry-backtrace = { version = "0.44.0", path = "../sentry-backtrace", optional = true } +sentry-contexts = { version = "0.44.0", path = "../sentry-contexts", optional = true } +sentry-debug-images = { version = "0.44.0", path = "../sentry-debug-images", optional = true } +sentry-log = { version = "0.44.0", path = "../sentry-log", optional = true } +sentry-panic = { version = "0.44.0", path = "../sentry-panic", optional = true } +sentry-slog = { version = "0.44.0", path = "../sentry-slog", optional = true } +sentry-tower = { version = "0.44.0", path = "../sentry-tower", optional = true } +sentry-tracing = { version = "0.44.0", path = "../sentry-tracing", optional = true } +sentry-opentelemetry = { version = "0.44.0", path = "../sentry-opentelemetry", optional = true } reqwest = { version = "0.12", optional = true, features = [ "blocking", "json", diff --git a/sentry/README.md b/sentry/README.md index 7223f2cc5..aaba0a051 100644 --- a/sentry/README.md +++ b/sentry/README.md @@ -34,8 +34,8 @@ sentry::capture_message("Hello World!", sentry::Level::Info); More complex examples on how to use sentry can also be found in [examples]. Extended instructions may also be found on [Sentry itself]. -[`sentry::init`]: https://docs.rs/sentry/0.43.0/sentry/fn.init.html -[`Hub`]: https://docs.rs/sentry/0.43.0/sentry/struct.Hub.html +[`sentry::init`]: https://docs.rs/sentry/0.44.0/sentry/fn.init.html +[`Hub`]: https://docs.rs/sentry/0.44.0/sentry/struct.Hub.html [examples]: https://github.com/getsentry/sentry-rust/tree/master/sentry/examples [Sentry itself]: https://docs.sentry.io/platforms/rust @@ -47,8 +47,8 @@ the ecosystem require a feature flag. For available integrations and how to use [integrations] and [apply_defaults]. [Features]: #features -[integrations]: https://docs.rs/sentry/0.43.0/sentry/integrations/index.html -[apply_defaults]: https://docs.rs/sentry/0.43.0/sentry/fn.apply_defaults.html +[integrations]: https://docs.rs/sentry/0.44.0/sentry/integrations/index.html +[apply_defaults]: https://docs.rs/sentry/0.44.0/sentry/fn.apply_defaults.html ## Minimal API @@ -56,8 +56,8 @@ This crate comes fully-featured. If the goal is to instrument libraries for usag with sentry, or to extend sentry with a custom [`Integration`] or a [`Transport`], one should use the [`sentry-core`] crate instead. -[`Integration`]: https://docs.rs/sentry/0.43.0/sentry/trait.Integration.html -[`Transport`]: https://docs.rs/sentry/0.43.0/sentry/trait.Transport.html +[`Integration`]: https://docs.rs/sentry/0.44.0/sentry/trait.Integration.html +[`Transport`]: https://docs.rs/sentry/0.44.0/sentry/trait.Transport.html [`sentry-core`]: https://crates.io/crates/sentry-core From b99eb46bcff33ea17b309f772e0bef0db30c0bed Mon Sep 17 00:00:00 2001 From: Tobias Wilfert <36408720+tobias-wilfert@users.noreply.github.com> Date: Wed, 8 Oct 2025 10:59:58 +0200 Subject: [PATCH 145/148] feat(types): Add custom variant to `AttachmentType` (#916) Co-authored-by: Arpad Borsos --- CHANGELOG.md | 6 +++++ sentry-types/src/protocol/attachment.rs | 29 ++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e3063a0b..e8323e51f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Breaking changes + +- Add custom variant to `AttachmentType` that holds an arbitrary String. ([#916](https://github.com/getsentry/sentry-rust/pull/916)) + ## 0.44.0 ### Breaking changes diff --git a/sentry-types/src/protocol/attachment.rs b/sentry-types/src/protocol/attachment.rs index 8b2ce6d74..e23a64784 100644 --- a/sentry-types/src/protocol/attachment.rs +++ b/sentry-types/src/protocol/attachment.rs @@ -3,7 +3,7 @@ use std::fmt; use serde::Deserialize; /// The different types an attachment can have. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Deserialize)] +#[derive(Debug, Clone, Eq, PartialEq, Deserialize)] pub enum AttachmentType { #[serde(rename = "event.attachment")] /// (default) A standard attachment without special meaning. @@ -23,6 +23,9 @@ pub enum AttachmentType { /// the last logs are extracted into event breadcrumbs. #[serde(rename = "unreal.logs")] UnrealLogs, + /// A custom attachment type with an arbitrary string value. + #[serde(untagged)] + Custom(String), } impl Default for AttachmentType { @@ -33,13 +36,14 @@ impl Default for AttachmentType { impl AttachmentType { /// Gets the string value Sentry expects for the attachment type. - pub fn as_str(self) -> &'static str { + pub fn as_str(&self) -> &str { match self { Self::Attachment => "event.attachment", Self::Minidump => "event.minidump", Self::AppleCrashReport => "event.applecrashreport", Self::UnrealContext => "unreal.context", Self::UnrealLogs => "unreal.logs", + Self::Custom(s) => s, } } } @@ -68,7 +72,11 @@ impl Attachment { r#"{{"type":"attachment","length":{length},"filename":"{filename}","attachment_type":"{at}","content_type":"{ct}"}}"#, filename = self.filename, length = self.buffer.len(), - at = self.ty.unwrap_or_default().as_str(), + at = self + .ty + .as_ref() + .unwrap_or(&AttachmentType::default()) + .as_str(), ct = self .content_type .as_ref() @@ -92,3 +100,18 @@ impl fmt::Debug for Attachment { .finish() } } + +#[cfg(test)] +mod tests { + use super::*; + use serde_json; + + #[test] + fn test_attachment_type_deserialize() { + let result: AttachmentType = serde_json::from_str(r#""event.minidump""#).unwrap(); + assert_eq!(result, AttachmentType::Minidump); + + let result: AttachmentType = serde_json::from_str(r#""my.custom.type""#).unwrap(); + assert_eq!(result, AttachmentType::Custom("my.custom.type".to_string())); + } +} From aa6d85b90fc8dcc1292b9727c32350e1aa12a425 Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Wed, 8 Oct 2025 09:13:43 +0000 Subject: [PATCH 146/148] release: 0.45.0 --- CHANGELOG.md | 2 +- Cargo.lock | 28 ++++++++++++++-------------- sentry-actix/Cargo.toml | 4 ++-- sentry-anyhow/Cargo.toml | 6 +++--- sentry-backtrace/Cargo.toml | 4 ++-- sentry-contexts/Cargo.toml | 4 ++-- sentry-core/Cargo.toml | 4 ++-- sentry-core/README.md | 2 +- sentry-debug-images/Cargo.toml | 4 ++-- sentry-debug-images/README.md | 2 +- sentry-log/Cargo.toml | 4 ++-- sentry-opentelemetry/Cargo.toml | 4 ++-- sentry-panic/Cargo.toml | 6 +++--- sentry-slog/Cargo.toml | 4 ++-- sentry-tower/Cargo.toml | 4 ++-- sentry-tower/README.md | 2 +- sentry-tracing/Cargo.toml | 6 +++--- sentry-tracing/README.md | 2 +- sentry-types/Cargo.toml | 2 +- sentry/Cargo.toml | 26 +++++++++++++------------- sentry/README.md | 12 ++++++------ 21 files changed, 66 insertions(+), 66 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e8323e51f..f18433852 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 0.45.0 ### Breaking changes diff --git a/Cargo.lock b/Cargo.lock index c47dc4c39..14808aa5d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3152,7 +3152,7 @@ dependencies = [ [[package]] name = "sentry" -version = "0.44.0" +version = "0.45.0" dependencies = [ "actix-web", "anyhow", @@ -3188,7 +3188,7 @@ dependencies = [ [[package]] name = "sentry-actix" -version = "0.44.0" +version = "0.45.0" dependencies = [ "actix-http", "actix-web", @@ -3202,7 +3202,7 @@ dependencies = [ [[package]] name = "sentry-anyhow" -version = "0.44.0" +version = "0.45.0" dependencies = [ "anyhow", "sentry", @@ -3212,7 +3212,7 @@ dependencies = [ [[package]] name = "sentry-backtrace" -version = "0.44.0" +version = "0.45.0" dependencies = [ "backtrace", "regex", @@ -3221,7 +3221,7 @@ dependencies = [ [[package]] name = "sentry-contexts" -version = "0.44.0" +version = "0.45.0" dependencies = [ "hostname", "libc", @@ -3234,7 +3234,7 @@ dependencies = [ [[package]] name = "sentry-core" -version = "0.44.0" +version = "0.45.0" dependencies = [ "anyhow", "criterion", @@ -3254,7 +3254,7 @@ dependencies = [ [[package]] name = "sentry-debug-images" -version = "0.44.0" +version = "0.45.0" dependencies = [ "findshlibs", "sentry-core", @@ -3262,7 +3262,7 @@ dependencies = [ [[package]] name = "sentry-log" -version = "0.44.0" +version = "0.45.0" dependencies = [ "bitflags 2.9.4", "log", @@ -3273,7 +3273,7 @@ dependencies = [ [[package]] name = "sentry-opentelemetry" -version = "0.44.0" +version = "0.45.0" dependencies = [ "opentelemetry", "opentelemetry_sdk", @@ -3283,7 +3283,7 @@ dependencies = [ [[package]] name = "sentry-panic" -version = "0.44.0" +version = "0.45.0" dependencies = [ "sentry", "sentry-backtrace", @@ -3292,7 +3292,7 @@ dependencies = [ [[package]] name = "sentry-slog" -version = "0.44.0" +version = "0.45.0" dependencies = [ "erased-serde", "sentry", @@ -3304,7 +3304,7 @@ dependencies = [ [[package]] name = "sentry-tower" -version = "0.44.0" +version = "0.45.0" dependencies = [ "anyhow", "axum 0.8.3", @@ -3324,7 +3324,7 @@ dependencies = [ [[package]] name = "sentry-tracing" -version = "0.44.0" +version = "0.45.0" dependencies = [ "bitflags 2.9.4", "log", @@ -3340,7 +3340,7 @@ dependencies = [ [[package]] name = "sentry-types" -version = "0.44.0" +version = "0.45.0" dependencies = [ "debugid", "hex", diff --git a/sentry-actix/Cargo.toml b/sentry-actix/Cargo.toml index 1ff43c4bd..06f88f443 100644 --- a/sentry-actix/Cargo.toml +++ b/sentry-actix/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-actix" -version = "0.44.0" +version = "0.45.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -20,7 +20,7 @@ release-health = ["sentry-core/release-health"] actix-web = { version = "4", default-features = false } bytes = "1.2" futures-util = { version = "0.3.5", default-features = false } -sentry-core = { version = "0.44.0", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.45.0", path = "../sentry-core", default-features = false, features = [ "client", ] } actix-http = "3.10" diff --git a/sentry-anyhow/Cargo.toml b/sentry-anyhow/Cargo.toml index e8f120ca1..aa9b87836 100644 --- a/sentry-anyhow/Cargo.toml +++ b/sentry-anyhow/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-anyhow" -version = "0.44.0" +version = "0.45.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -17,8 +17,8 @@ default = ["backtrace"] backtrace = [] [dependencies] -sentry-backtrace = { version = "0.44.0", path = "../sentry-backtrace" } -sentry-core = { version = "0.44.0", path = "../sentry-core" } +sentry-backtrace = { version = "0.45.0", path = "../sentry-backtrace" } +sentry-core = { version = "0.45.0", path = "../sentry-core" } anyhow = "1.0.77" [dev-dependencies] diff --git a/sentry-backtrace/Cargo.toml b/sentry-backtrace/Cargo.toml index f37ece915..b08723ef8 100644 --- a/sentry-backtrace/Cargo.toml +++ b/sentry-backtrace/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-backtrace" -version = "0.44.0" +version = "0.45.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -18,4 +18,4 @@ regex = { version = "1.5.5", default-features = false, features = [ "std", "unicode-perl", ] } -sentry-core = { version = "0.44.0", path = "../sentry-core" } +sentry-core = { version = "0.45.0", path = "../sentry-core" } diff --git a/sentry-contexts/Cargo.toml b/sentry-contexts/Cargo.toml index 3f7c885ea..0866a9536 100644 --- a/sentry-contexts/Cargo.toml +++ b/sentry-contexts/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-contexts" -version = "0.44.0" +version = "0.45.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -14,7 +14,7 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.44.0", path = "../sentry-core" } +sentry-core = { version = "0.45.0", path = "../sentry-core" } libc = "0.2.66" hostname = "0.4" diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index 764d3030c..da21ae27e 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-core" -version = "0.44.0" +version = "0.45.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -29,7 +29,7 @@ logs = [] [dependencies] log = { version = "0.4.8", optional = true, features = ["std"] } rand = { version = "0.9.0", optional = true } -sentry-types = { version = "0.44.0", path = "../sentry-types" } +sentry-types = { version = "0.45.0", path = "../sentry-types" } serde = { version = "1.0.104", features = ["derive"] } serde_json = { version = "1.0.46" } url = { version = "2.1.1" } diff --git a/sentry-core/README.md b/sentry-core/README.md index 211addac8..41aab7d9f 100644 --- a/sentry-core/README.md +++ b/sentry-core/README.md @@ -99,7 +99,7 @@ functionality. [Sentry]: https://sentry.io/ [`sentry`]: https://crates.io/crates/sentry [Unified API]: https://develop.sentry.dev/sdk/unified-api/ -[`test`]: https://docs.rs/sentry-core/0.44.0/sentry_core/test/index.html +[`test`]: https://docs.rs/sentry-core/0.45.0/sentry_core/test/index.html ## Resources diff --git a/sentry-debug-images/Cargo.toml b/sentry-debug-images/Cargo.toml index b0a1c4f97..f5979c6b9 100644 --- a/sentry-debug-images/Cargo.toml +++ b/sentry-debug-images/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-debug-images" -version = "0.44.0" +version = "0.45.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -14,4 +14,4 @@ rust-version = "1.81" [dependencies] findshlibs = "=0.10.2" -sentry-core = { version = "0.44.0", path = "../sentry-core" } +sentry-core = { version = "0.45.0", path = "../sentry-core" } diff --git a/sentry-debug-images/README.md b/sentry-debug-images/README.md index a7c4a9e6d..fe362e6b3 100644 --- a/sentry-debug-images/README.md +++ b/sentry-debug-images/README.md @@ -22,7 +22,7 @@ let integration = sentry_debug_images::DebugImagesIntegration::new() .filter(|event| event.level >= Level::Warning); ``` -[`Event`]: https://docs.rs/sentry-debug-images/0.44.0/sentry_debug_images/sentry_core::protocol::Event +[`Event`]: https://docs.rs/sentry-debug-images/0.45.0/sentry_debug_images/sentry_core::protocol::Event ## Resources diff --git a/sentry-log/Cargo.toml b/sentry-log/Cargo.toml index 1e20935a8..1dcaa277c 100644 --- a/sentry-log/Cargo.toml +++ b/sentry-log/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-log" -version = "0.44.0" +version = "0.45.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -17,7 +17,7 @@ default = [] logs = ["sentry-core/logs"] [dependencies] -sentry-core = { version = "0.44.0", path = "../sentry-core" } +sentry-core = { version = "0.45.0", path = "../sentry-core" } log = { version = "0.4.8", features = ["std", "kv"] } bitflags = "2.9.4" diff --git a/sentry-opentelemetry/Cargo.toml b/sentry-opentelemetry/Cargo.toml index 7f67eb5dc..548e98afb 100644 --- a/sentry-opentelemetry/Cargo.toml +++ b/sentry-opentelemetry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-opentelemetry" -version = "0.44.0" +version = "0.45.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -16,7 +16,7 @@ rust-version = "1.81" all-features = true [dependencies] -sentry-core = { version = "0.44.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.45.0", path = "../sentry-core", features = [ "client", ] } opentelemetry = { version = "0.29.0", default-features = false } diff --git a/sentry-panic/Cargo.toml b/sentry-panic/Cargo.toml index d358cda99..40f6cbae7 100644 --- a/sentry-panic/Cargo.toml +++ b/sentry-panic/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-panic" -version = "0.44.0" +version = "0.45.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -13,8 +13,8 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.44.0", path = "../sentry-core", features = ["client"] } -sentry-backtrace = { version = "0.44.0", path = "../sentry-backtrace" } +sentry-core = { version = "0.45.0", path = "../sentry-core", features = ["client"] } +sentry-backtrace = { version = "0.45.0", path = "../sentry-backtrace" } [dev-dependencies] sentry = { path = "../sentry", default-features = false, features = ["test"] } diff --git a/sentry-slog/Cargo.toml b/sentry-slog/Cargo.toml index eb26ce7fc..623bf0dff 100644 --- a/sentry-slog/Cargo.toml +++ b/sentry-slog/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-slog" -version = "0.44.0" +version = "0.45.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.81" [dependencies] -sentry-core = { version = "0.44.0", path = "../sentry-core" } +sentry-core = { version = "0.45.0", path = "../sentry-core" } slog = { version = "2.5.2", features = ["nested-values"] } serde_json = "1.0.46" diff --git a/sentry-tower/Cargo.toml b/sentry-tower/Cargo.toml index 637b33ab2..7b4468a3a 100644 --- a/sentry-tower/Cargo.toml +++ b/sentry-tower/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tower" -version = "0.44.0" +version = "0.45.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -26,7 +26,7 @@ tower-layer = "0.3" tower-service = "0.3" http = { version = "1.0.0", optional = true } pin-project = { version = "1.0.10", optional = true } -sentry-core = { version = "0.44.0", path = "../sentry-core", default-features = false, features = [ +sentry-core = { version = "0.45.0", path = "../sentry-core", default-features = false, features = [ "client", ] } url = { version = "2.2.2", optional = true } diff --git a/sentry-tower/README.md b/sentry-tower/README.md index 0c4410e51..e4a159ce4 100644 --- a/sentry-tower/README.md +++ b/sentry-tower/README.md @@ -103,7 +103,7 @@ feature of the `sentry` crate instead of the `tower` feature. The created transaction will automatically use the request URI as its name. This is sometimes not desirable in case the request URI contains unique IDs or similar. In this case, users should manually override the transaction name -in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.44.0/sentry_tower/sentry_core::Scope::set_transaction) +in the request handler using the [`Scope::set_transaction`](https://docs.rs/sentry-tower/0.45.0/sentry_tower/sentry_core::Scope::set_transaction) method. When combining both layers, take care of the ordering of both. For example diff --git a/sentry-tracing/Cargo.toml b/sentry-tracing/Cargo.toml index eb54e361a..c88854632 100644 --- a/sentry-tracing/Cargo.toml +++ b/sentry-tracing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-tracing" -version = "0.44.0" +version = "0.45.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -21,14 +21,14 @@ backtrace = ["dep:sentry-backtrace"] logs = ["sentry-core/logs"] [dependencies] -sentry-core = { version = "0.44.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.45.0", path = "../sentry-core", features = [ "client", ] } tracing-core = "0.1" tracing-subscriber = { version = "0.3.20", default-features = false, features = [ "std", ] } -sentry-backtrace = { version = "0.44.0", path = "../sentry-backtrace", optional = true } +sentry-backtrace = { version = "0.45.0", path = "../sentry-backtrace", optional = true } bitflags = "2.9.4" [dev-dependencies] diff --git a/sentry-tracing/README.md b/sentry-tracing/README.md index 5e128aa5f..cd04aa4a1 100644 --- a/sentry-tracing/README.md +++ b/sentry-tracing/README.md @@ -121,7 +121,7 @@ tracing::error!( ); ``` -To track [error structs](https://docs.rs/sentry-tracing/0.44.0/sentry_tracing/std::error::Error), assign a reference to error trait object as field +To track [error structs](https://docs.rs/sentry-tracing/0.45.0/sentry_tracing/std::error::Error), assign a reference to error trait object as field in one of the logging macros. By convention, it is recommended to use the `ERROR` level and assign it to a field called `error`, although the integration will also work with all other levels and field names. diff --git a/sentry-types/Cargo.toml b/sentry-types/Cargo.toml index e742b9940..f65adb139 100644 --- a/sentry-types/Cargo.toml +++ b/sentry-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry-types" -version = "0.44.0" +version = "0.45.0" authors = ["Sentry "] license = "MIT" readme = "README.md" diff --git a/sentry/Cargo.toml b/sentry/Cargo.toml index c3428158d..c44a55a7d 100644 --- a/sentry/Cargo.toml +++ b/sentry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sentry" -version = "0.44.0" +version = "0.45.0" authors = ["Sentry "] license = "MIT" readme = "README.md" @@ -60,20 +60,20 @@ rustls = ["dep:rustls", "reqwest?/rustls-tls", "ureq?/rustls"] embedded-svc-http = ["dep:embedded-svc", "dep:esp-idf-svc"] [dependencies] -sentry-core = { version = "0.44.0", path = "../sentry-core", features = [ +sentry-core = { version = "0.45.0", path = "../sentry-core", features = [ "client", ] } -sentry-anyhow = { version = "0.44.0", path = "../sentry-anyhow", optional = true } -sentry-actix = { version = "0.44.0", path = "../sentry-actix", optional = true, default-features = false } -sentry-backtrace = { version = "0.44.0", path = "../sentry-backtrace", optional = true } -sentry-contexts = { version = "0.44.0", path = "../sentry-contexts", optional = true } -sentry-debug-images = { version = "0.44.0", path = "../sentry-debug-images", optional = true } -sentry-log = { version = "0.44.0", path = "../sentry-log", optional = true } -sentry-panic = { version = "0.44.0", path = "../sentry-panic", optional = true } -sentry-slog = { version = "0.44.0", path = "../sentry-slog", optional = true } -sentry-tower = { version = "0.44.0", path = "../sentry-tower", optional = true } -sentry-tracing = { version = "0.44.0", path = "../sentry-tracing", optional = true } -sentry-opentelemetry = { version = "0.44.0", path = "../sentry-opentelemetry", optional = true } +sentry-anyhow = { version = "0.45.0", path = "../sentry-anyhow", optional = true } +sentry-actix = { version = "0.45.0", path = "../sentry-actix", optional = true, default-features = false } +sentry-backtrace = { version = "0.45.0", path = "../sentry-backtrace", optional = true } +sentry-contexts = { version = "0.45.0", path = "../sentry-contexts", optional = true } +sentry-debug-images = { version = "0.45.0", path = "../sentry-debug-images", optional = true } +sentry-log = { version = "0.45.0", path = "../sentry-log", optional = true } +sentry-panic = { version = "0.45.0", path = "../sentry-panic", optional = true } +sentry-slog = { version = "0.45.0", path = "../sentry-slog", optional = true } +sentry-tower = { version = "0.45.0", path = "../sentry-tower", optional = true } +sentry-tracing = { version = "0.45.0", path = "../sentry-tracing", optional = true } +sentry-opentelemetry = { version = "0.45.0", path = "../sentry-opentelemetry", optional = true } reqwest = { version = "0.12", optional = true, features = [ "blocking", "json", diff --git a/sentry/README.md b/sentry/README.md index aaba0a051..5a6474d41 100644 --- a/sentry/README.md +++ b/sentry/README.md @@ -34,8 +34,8 @@ sentry::capture_message("Hello World!", sentry::Level::Info); More complex examples on how to use sentry can also be found in [examples]. Extended instructions may also be found on [Sentry itself]. -[`sentry::init`]: https://docs.rs/sentry/0.44.0/sentry/fn.init.html -[`Hub`]: https://docs.rs/sentry/0.44.0/sentry/struct.Hub.html +[`sentry::init`]: https://docs.rs/sentry/0.45.0/sentry/fn.init.html +[`Hub`]: https://docs.rs/sentry/0.45.0/sentry/struct.Hub.html [examples]: https://github.com/getsentry/sentry-rust/tree/master/sentry/examples [Sentry itself]: https://docs.sentry.io/platforms/rust @@ -47,8 +47,8 @@ the ecosystem require a feature flag. For available integrations and how to use [integrations] and [apply_defaults]. [Features]: #features -[integrations]: https://docs.rs/sentry/0.44.0/sentry/integrations/index.html -[apply_defaults]: https://docs.rs/sentry/0.44.0/sentry/fn.apply_defaults.html +[integrations]: https://docs.rs/sentry/0.45.0/sentry/integrations/index.html +[apply_defaults]: https://docs.rs/sentry/0.45.0/sentry/fn.apply_defaults.html ## Minimal API @@ -56,8 +56,8 @@ This crate comes fully-featured. If the goal is to instrument libraries for usag with sentry, or to extend sentry with a custom [`Integration`] or a [`Transport`], one should use the [`sentry-core`] crate instead. -[`Integration`]: https://docs.rs/sentry/0.44.0/sentry/trait.Integration.html -[`Transport`]: https://docs.rs/sentry/0.44.0/sentry/trait.Transport.html +[`Integration`]: https://docs.rs/sentry/0.45.0/sentry/trait.Integration.html +[`Transport`]: https://docs.rs/sentry/0.45.0/sentry/trait.Transport.html [`sentry-core`]: https://crates.io/crates/sentry-core From 2edf6d7a54dde2284b8954501beea311a2468aae Mon Sep 17 00:00:00 2001 From: Lorenzo Cian <17258265+lcian@users.noreply.github.com> Date: Tue, 14 Oct 2025 15:18:29 +0200 Subject: [PATCH 147/148] fix: adjust sentry.origin for log integration (#919) --- CHANGELOG.md | 6 ++++++ sentry-log/src/converters.rs | 2 +- sentry/tests/test_log_logs.rs | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f18433852..71621ac13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Fixes + +- fix: adjust sentry.origin for log integration ([#919](https://github.com/getsentry/sentry-rust/pull/919)) by @lcian + ## 0.45.0 ### Breaking changes diff --git a/sentry-log/src/converters.rs b/sentry-log/src/converters.rs index 799659ab4..1a0b12533 100644 --- a/sentry-log/src/converters.rs +++ b/sentry-log/src/converters.rs @@ -154,7 +154,7 @@ pub fn log_from_record(record: &log::Record<'_>) -> Log { attributes.insert("logger.line".into(), line.into()); } - attributes.insert("sentry.origin".into(), "auto.logger.log".into()); + attributes.insert("sentry.origin".into(), "auto.log.log".into()); Log { level: convert_log_level_to_sentry_log_level(record.level()), diff --git a/sentry/tests/test_log_logs.rs b/sentry/tests/test_log_logs.rs index 1d631a5bf..881ecd25f 100644 --- a/sentry/tests/test_log_logs.rs +++ b/sentry/tests/test_log_logs.rs @@ -51,7 +51,7 @@ fn test_log_logs() { ); assert_eq!( info_log.attributes.get("sentry.origin").unwrap().clone(), - "auto.logger.log".into() + "auto.log.log".into() ); } _ => panic!("expected logs"), From ca232686f4f338f3e13a0123b15654c32c68d47c Mon Sep 17 00:00:00 2001 From: Ivan Dlugos <6349682+vaind@users.noreply.github.com> Date: Tue, 14 Oct 2025 16:01:30 +0200 Subject: [PATCH 148/148] chore(ci): Migrate danger workflow from v2 to v3 (#918) Co-authored-by: Claude --- .github/workflows/danger.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml index 000b75ff3..09d4bcb03 100644 --- a/.github/workflows/danger.yml +++ b/.github/workflows/danger.yml @@ -6,4 +6,6 @@ on: jobs: danger: - uses: getsentry/github-workflows/.github/workflows/danger.yml@v2 + runs-on: ubuntu-latest + steps: + - uses: getsentry/github-workflows/danger@v3