diff --git a/Cargo.lock b/Cargo.lock index 05d6da4e0..abf7f7524 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3432,6 +3432,7 @@ dependencies = [ "rand 0.9.5", "rayon", "sentry", + "sentry-time", "sentry-types", "serde", "serde_json", @@ -3458,6 +3459,7 @@ dependencies = [ "pretty_env_logger", "sentry", "sentry-core", + "sentry-time", ] [[package]] @@ -3468,6 +3470,7 @@ dependencies = [ "opentelemetry_sdk", "sentry", "sentry-core", + "sentry-time", ] [[package]] @@ -3491,6 +3494,13 @@ dependencies = [ "slog", ] +[[package]] +name = "sentry-time" +version = "0.49.1" +dependencies = [ + "web-time", +] + [[package]] name = "sentry-tower" version = "0.49.1" @@ -3520,6 +3530,7 @@ dependencies = [ "sentry", "sentry-backtrace", "sentry-core", + "sentry-time", "serde_json", "tokio", "tracing", @@ -3535,6 +3546,7 @@ dependencies = [ "hex", "rand 0.9.5", "rstest", + "sentry-time", "serde", "serde_json", "thiserror 2.0.19", diff --git a/Cargo.toml b/Cargo.toml index 72d45ec6f..9381acd50 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,35 +1,29 @@ [workspace] resolver = "2" members = [ - "sentry", - "sentry-actix", - "sentry-anyhow", - "sentry-backtrace", - "sentry-contexts", - "sentry-core", - "sentry-debug-images", - "sentry-log", - "sentry-opentelemetry", - "sentry-panic", - "sentry-slog", - "sentry-tower", - "sentry-tracing", - "sentry-types", + "sentry", + "sentry-actix", + "sentry-anyhow", + "sentry-backtrace", + "sentry-contexts", + "sentry-core", + "sentry-debug-images", + "sentry-log", + "sentry-opentelemetry", + "sentry-panic", + "sentry-slog", + "sentry-time", + "sentry-tower", + "sentry-tracing", + "sentry-types", ] [workspace.package] authors = ["Sentry "] -repository = "https://github.com/getsentry/sentry-rust" -homepage = "https://sentry.io/welcome/" edition = "2021" rust-version = "1.88" - -[workspace.lints.clippy] -arithmetic-side-effects.level = "warn" -allow-attributes.level = "warn" - -[workspace.lints.rust] -unexpected_cfgs = { level = "warn", check-cfg = ['cfg(doc_cfg)'] } +homepage = "https://sentry.io/welcome/" +repository = "https://github.com/getsentry/sentry-rust" [workspace.dependencies] actix-http = "3.12" @@ -40,6 +34,7 @@ backtrace = "0.3.44" bitflags = "2.9.4" bytes = "1.11.1" cfg_aliases = "0.2.1" +# chrono = "0.4" criterion = "0.5" curl = "0.4.25" debugid = "0.8.0" @@ -62,27 +57,82 @@ os_info = "3.5.0" pin-project = "1.0.10" pretty_env_logger = "0.5.0" prost = "0.13.3" -rand = "0.9.3" +rand = "0.9" rayon = "1.5.3" regex = { version = "1.5.5", default-features = false } reqwest = { version = "0.13.2", default-features = false } rstest = "0.25.0" rustc_version = "0.4.0" rustls = { version = "0.23.18", default-features = false } -sentry = { version = "0.49.1", path = "sentry", default-features = false } -sentry-actix = { version = "0.49.1", path = "sentry-actix", default-features = false } -sentry-anyhow = { version = "0.49.1", path = "sentry-anyhow", default-features = false, features = ["backtrace"] } -sentry-backtrace = { version = "0.49.1", path = "sentry-backtrace", default-features = false } -sentry-contexts = { version = "0.49.1", path = "sentry-contexts", default-features = false } -sentry-core = { version = "0.49.1", path = "sentry-core", default-features = false } -sentry-debug-images = { version = "0.49.1", path = "sentry-debug-images", default-features = false } -sentry-log = { version = "0.49.1", path = "sentry-log", default-features = false } -sentry-opentelemetry = { version = "0.49.1", path = "sentry-opentelemetry", default-features = false } -sentry-panic = { version = "0.49.1", path = "sentry-panic", default-features = false } -sentry-slog = { version = "0.49.1", path = "sentry-slog", default-features = false } -sentry-tower = { version = "0.49.1", path = "sentry-tower", default-features = false } -sentry-tracing = { version = "0.49.1", path = "sentry-tracing", default-features = false } -sentry-types = { version = "0.49.1", path = "sentry-types", default-features = false, features = ["protocol"] } +sentry = { path = "sentry", version = "0.49.1", default-features = false } +sentry-actix = { + path = "sentry-actix", + version = "0.49.1", + default-features = false +} +sentry-anyhow = { + path = "sentry-anyhow", + version = "0.49.1", + default-features = false, + features = ["backtrace"] +} +sentry-backtrace = { + path = "sentry-backtrace", + version = "0.49.1", + default-features = false +} +sentry-contexts = { + path = "sentry-contexts", + version = "0.49.1", + default-features = false +} +sentry-core = { + path = "sentry-core", + version = "0.49.1", + default-features = false +} +sentry-debug-images = { + path = "sentry-debug-images", + version = "0.49.1", + default-features = false +} +sentry-log = { + path = "sentry-log", + version = "0.49.1", + default-features = false +} +sentry-opentelemetry = { + path = "sentry-opentelemetry", + version = "0.49.1", + default-features = false +} +sentry-panic = { + path = "sentry-panic", + version = "0.49.1", + default-features = false +} +sentry-slog = { + path = "sentry-slog", + version = "0.49.1", + default-features = false +} +sentry-time = { path = "sentry-time", version = "0.49.1" } +sentry-tower = { + path = "sentry-tower", + version = "0.49.1", + default-features = false +} +sentry-tracing = { + path = "sentry-tracing", + version = "0.49.1", + default-features = false +} +sentry-types = { + path = "sentry-types", + version = "0.49.1", + default-features = false, + features = ["protocol"] +} serde = "1.0.117" serde_json = "1.0.48" slog = "2.5.2" @@ -100,3 +150,10 @@ uname = "0.1.1" ureq = { version = "3.0.11", default-features = false } url = "2.2.2" uuid = "1.0.0" + +[workspace.lints.clippy] +allow-attributes.level = "warn" +arithmetic-side-effects.level = "warn" + +[workspace.lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = ["cfg(doc_cfg)"] } diff --git a/sentry-contexts/Cargo.toml b/sentry-contexts/Cargo.toml index 159dd6e90..1c097ebbd 100644 --- a/sentry-contexts/Cargo.toml +++ b/sentry-contexts/Cargo.toml @@ -19,9 +19,11 @@ workspace = true [dependencies] sentry-core = { workspace = true } libc = { workspace = true } + +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] hostname = { workspace = true } -[target."cfg(not(windows))".dependencies] +[target.'cfg(all(not(windows), not(target_arch = "wasm32")))'.dependencies] uname = { workspace = true } [target."cfg(windows)".dependencies] diff --git a/sentry-contexts/src/utils.rs b/sentry-contexts/src/utils.rs index 6c311a36e..55d64c8ad 100644 --- a/sentry-contexts/src/utils.rs +++ b/sentry-contexts/src/utils.rs @@ -110,12 +110,19 @@ mod model_support { } /// Returns the server name (hostname) if available. +#[cfg(not(target_arch = "wasm32"))] pub fn server_name() -> Option { hostname::get().ok().and_then(|s| s.into_string().ok()) } +#[cfg(target_arch = "wasm32")] +pub fn server_name() -> Option { + // TODO: What other options are available? + None +} + /// Returns the OS context -#[cfg(not(windows))] +#[cfg(all(not(windows), not(target_arch = "wasm32")))] pub fn os_context() -> Option { use uname::uname; if let Ok(info) = uname() { @@ -168,6 +175,17 @@ pub fn os_context() -> Option { ) } +#[cfg(target_arch = "wasm32")] +pub fn os_context() -> Option { + Some( + OsContext { + name: Some("WASM".into()), + ..Default::default() + } + .into(), + ) +} + /// Returns the rust info. pub fn rust_context() -> Context { RuntimeContext { diff --git a/sentry-core/Cargo.toml b/sentry-core/Cargo.toml index e2a1d78c4..76d4707f6 100644 --- a/sentry-core/Cargo.toml +++ b/sentry-core/Cargo.toml @@ -2,51 +2,53 @@ name = "sentry-core" version = "0.49.1" authors = { workspace = true } -license = "MIT" -readme = "README.md" -repository = { workspace = true } -homepage = { workspace = true } +edition = { workspace = true } +rust-version = { workspace = true } description = """ Core Sentry library used for instrumentation and integration development. """ -edition = { workspace = true } -rust-version = { workspace = true } - -[lints] -workspace = true +readme = "README.md" +homepage = { workspace = true } +repository = { workspace = true } +license = "MIT" [package.metadata.docs.rs] all-features = true [[bench]] -name = "scope_benchmark" harness = false - -[features] -default = [] -client = ["rand"] -test = ["client", "release-health"] -release-health = [] -logs = [] -metrics = [] +name = "scope_benchmark" [dependencies] +# chrono.workspace = true log = { workspace = true, features = ["std"], optional = true } rand = { workspace = true, optional = true } +sentry-time = { workspace = true } sentry-types = { workspace = true } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } url = { workspace = true } -uuid = { workspace = true, features = ["v4", "serde"], optional = true } +uuid = { workspace = true, features = ["serde", "v4"], optional = true } [dev-dependencies] -# Because we re-export all the public API in `sentry`, we actually run all the -# doctests using the `sentry` crate. This also takes care of the doctest -# limitation documented in https://github.com/rust-lang/rust/issues/45599. -sentry = { workspace = true, features = ["test", "transport", "metrics"] } anyhow = { workspace = true } criterion = { workspace = true } futures = { workspace = true } rayon = { workspace = true } +# Because we re-export all the public API in `sentry`, we actually run all the +# doctests using the `sentry` crate. This also takes care of the doctest +# limitation documented in https://github.com/rust-lang/rust/issues/45599. +sentry = { workspace = true, features = ["metrics", "test", "transport"] } thiserror = { workspace = true } -tokio = { workspace = true, features = ["rt", "rt-multi-thread", "macros"] } +tokio = { workspace = true, features = ["macros", "rt", "rt-multi-thread"] } + +[features] +default = [] +client = ["rand"] +logs = [] +metrics = [] +release-health = [] +test = ["client", "release-health"] + +[lints] +workspace = true diff --git a/sentry-core/src/client/batcher.rs b/sentry-core/src/client/batcher.rs index bedf350fa..d59dff2c5 100644 --- a/sentry-core/src/client/batcher.rs +++ b/sentry-core/src/client/batcher.rs @@ -4,7 +4,7 @@ use std::sync::{Arc, Condvar, Mutex, MutexGuard}; use std::thread::JoinHandle; -use std::time::{Duration, Instant}; +use std::time::Duration; use super::EnvelopeSender; use crate::protocol::EnvelopeItem; @@ -79,7 +79,7 @@ where if *shutdown { return; } - let mut last_flush = Instant::now(); + let mut last_flush = sentry_time::Instant::now(); loop { let timeout = FLUSH_INTERVAL .checked_sub(last_flush.elapsed()) @@ -93,7 +93,7 @@ where worker_queue.lock().unwrap(), &worker_envelope_sender, ); - last_flush = Instant::now(); + last_flush = sentry_time::Instant::now(); } } }) diff --git a/sentry-core/src/lib.rs b/sentry-core/src/lib.rs index 5e03ad631..b01344c6d 100644 --- a/sentry-core/src/lib.rs +++ b/sentry-core/src/lib.rs @@ -169,6 +169,9 @@ pub mod test; // public api from other crates #[doc(inline)] pub use sentry_types as types; + +#[doc(hidden)] +pub use sentry_time; pub use sentry_types::protocol::v7 as protocol; pub use sentry_types::protocol::v7::{Breadcrumb, Envelope, Level, User}; diff --git a/sentry-core/src/logger.rs b/sentry-core/src/logger.rs index 0a0e4db66..288ac4886 100644 --- a/sentry-core/src/logger.rs +++ b/sentry-core/src/logger.rs @@ -10,7 +10,7 @@ macro_rules! logger_log { level: $level, body: $msg.to_owned(), trace_id: None, - timestamp: ::std::time::SystemTime::now(), + timestamp: $crate::sentry_time::now_system_time(), severity_number: None, attributes: $crate::protocol::Map::new(), }; @@ -39,7 +39,7 @@ macro_rules! logger_log { level: $level, body: format!($fmt, $($arg),*), trace_id: None, - timestamp: ::std::time::SystemTime::now(), + timestamp: $crate::sentry_time::now_system_time(), severity_number: None, attributes, }; @@ -58,7 +58,7 @@ macro_rules! logger_log { level: $level, body: $msg.to_owned(), trace_id: None, - timestamp: ::std::time::SystemTime::now(), + timestamp: $crate::sentry_time::now_system_time(), severity_number: None, #[allow(clippy::redundant_field_names)] attributes: $attrs, @@ -86,7 +86,7 @@ macro_rules! logger_log { level: $level, body: format!($fmt, $($arg),*), trace_id: None, - timestamp: ::std::time::SystemTime::now(), + timestamp: $crate::sentry_time::now_system_time(), severity_number: None, #[allow(clippy::redundant_field_names)] attributes: $attrs, diff --git a/sentry-core/src/metrics.rs b/sentry-core/src/metrics.rs index 6531bee2c..56e1b1094 100644 --- a/sentry-core/src/metrics.rs +++ b/sentry-core/src/metrics.rs @@ -43,9 +43,10 @@ //! .capture(); //! ``` +use std::borrow::Cow; use std::collections::BTreeMap; -use std::{borrow::Cow, time::SystemTime}; +use sentry_time::now_system_time; use sentry_types::protocol::v7::{ LogAttribute, Metric as ProtocolMetric, MetricType, SpanId, TraceId, Unit, }; @@ -275,7 +276,7 @@ impl MetricInner { value, attributes, span_id, - timestamp: SystemTime::now(), + timestamp: now_system_time(), unit: None, } } diff --git a/sentry-core/src/performance/mod.rs b/sentry-core/src/performance/mod.rs index 090b59022..2c54643f2 100644 --- a/sentry-core/src/performance/mod.rs +++ b/sentry-core/src/performance/mod.rs @@ -4,6 +4,7 @@ use std::ops::{Deref, DerefMut}; use std::sync::{Arc, Mutex, MutexGuard}; use std::time::SystemTime; +use sentry_time::now_system_time; #[cfg(feature = "client")] use sentry_types::protocol::v7::client_report::Reason as ClientReportReason; #[cfg(feature = "client")] @@ -992,7 +993,7 @@ impl 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()); + self.finish_with_timestamp(now_system_time()); } /// Starts a new child Span with the given `op` and `description`. @@ -1246,7 +1247,7 @@ impl 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()); + self.finish_with_timestamp(now_system_time()); } /// Starts a new child Span with the given `op` and `description`. diff --git a/sentry-core/src/session.rs b/sentry-core/src/session.rs index 05590ad41..2de94b1b8 100644 --- a/sentry-core/src/session.rs +++ b/sentry-core/src/session.rs @@ -13,7 +13,9 @@ 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 std::time::{Duration, SystemTime}; + + use sentry_time::now_system_time; use crate::client::EnvelopeSender; use crate::clientoptions::SessionMode; @@ -31,7 +33,7 @@ mod session_impl { pub struct Session { client: Arc, session_update: SessionUpdate<'static>, - started: Instant, + started: sentry_time::Instant, dirty: bool, } @@ -64,7 +66,7 @@ mod session_impl { distinct_id, sequence: None, timestamp: None, - started: SystemTime::now(), + started: now_system_time(), init: true, duration: None, status: SessionStatus::Ok, @@ -76,7 +78,7 @@ mod session_impl { user_agent: None, }, }, - started: Instant::now(), + started: sentry_time::Instant::now(), dirty: true, }) } @@ -215,7 +217,7 @@ mod session_impl { if *shutdown { return; } - let mut last_flush = Instant::now(); + let mut last_flush = sentry_time::Instant::now(); loop { let timeout = FLUSH_INTERVAL .checked_sub(last_flush.elapsed()) @@ -231,7 +233,7 @@ mod session_impl { worker_queue.lock().unwrap(), &worker_envelope_sender, ); - last_flush = Instant::now(); + last_flush = sentry_time::Instant::now() } }) .unwrap(); diff --git a/sentry-log/Cargo.toml b/sentry-log/Cargo.toml index 554ec55c9..b38a85d40 100644 --- a/sentry-log/Cargo.toml +++ b/sentry-log/Cargo.toml @@ -21,6 +21,7 @@ logs = ["sentry-core/logs"] [dependencies] sentry-core = { workspace = true } +sentry-time = { workspace = true } log = { workspace = true, features = ["std", "kv"] } bitflags = { workspace = true } diff --git a/sentry-log/src/converters.rs b/sentry-log/src/converters.rs index 1a0b12533..7a7a7c2cf 100644 --- a/sentry-log/src/converters.rs +++ b/sentry-log/src/converters.rs @@ -2,9 +2,9 @@ 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::time::SystemTime; +use sentry_time::now_system_time; +use std::collections::BTreeMap; /// Converts a [`log::Level`] to a Sentry [`Level`], used for [`Event`] and [`Breadcrumb`]. pub fn convert_log_level(level: log::Level) -> Level { @@ -160,7 +160,7 @@ pub fn log_from_record(record: &log::Record<'_>) -> Log { level: convert_log_level_to_sentry_log_level(record.level()), body: format!("{}", record.args()), trace_id: None, - timestamp: SystemTime::now(), + timestamp: now_system_time(), severity_number: None, attributes, } diff --git a/sentry-opentelemetry/Cargo.toml b/sentry-opentelemetry/Cargo.toml index 439c4efff..3afbd4366 100644 --- a/sentry-opentelemetry/Cargo.toml +++ b/sentry-opentelemetry/Cargo.toml @@ -2,28 +2,29 @@ name = "sentry-opentelemetry" version = "0.49.1" authors = { workspace = true } -license = "MIT" -readme = "README.md" -repository = { workspace = true } -homepage = { workspace = true } +edition = { workspace = true } +rust-version = { workspace = true } description = """ Sentry integration for OpenTelemetry. """ -edition = { workspace = true } -rust-version = { workspace = true } - -[lints] -workspace = true +readme = "README.md" +homepage = { workspace = true } +repository = { workspace = true } +license = "MIT" [package.metadata.docs.rs] all-features = true [dependencies] -sentry-core = { workspace = true, features = ["client"] } opentelemetry = { workspace = true } opentelemetry_sdk = { workspace = true, features = ["trace"] } +sentry-core = { workspace = true, features = ["client"] } +sentry-time.workspace = true [dev-dependencies] -sentry = { workspace = true, features = ["test", "opentelemetry"] } +opentelemetry_sdk = { workspace = true, features = ["testing", "trace"] } +sentry = { workspace = true, features = ["opentelemetry", "test"] } sentry-core = { workspace = true, features = ["test"] } -opentelemetry_sdk = { workspace = true, features = ["trace", "testing"] } + +[lints] +workspace = true diff --git a/sentry-opentelemetry/src/processor.rs b/sentry-opentelemetry/src/processor.rs index 8818f93fe..67886e0ad 100644 --- a/sentry-opentelemetry/src/processor.rs +++ b/sentry-opentelemetry/src/processor.rs @@ -10,7 +10,7 @@ use std::collections::HashMap; use std::sync::{Arc, LazyLock, Mutex}; -use std::time::{Duration, SystemTime}; +use std::time::Duration; use opentelemetry::global::ObjectSafeSpan; use opentelemetry::trace::{get_active_span, SpanId}; @@ -20,6 +20,7 @@ use opentelemetry_sdk::trace::{Span, SpanData, SpanProcessor}; use opentelemetry_sdk::Resource; use sentry_core::{TracePropagationContext, TransactionContext, TransactionOrSpan}; +use sentry_time::now_system_time; use crate::converters::{ convert_span_id, convert_span_kind, convert_span_status, convert_trace_id, convert_value, @@ -103,7 +104,7 @@ impl SpanProcessor for SentrySpanProcessor { let mut span_description = String::new(); let mut span_op = String::new(); - let mut span_start_timestamp = SystemTime::now(); + let mut span_start_timestamp = now_system_time(); let mut parent_sentry_span = None; if let Some(data) = span.exported_data() { span_description = data.name.to_string(); diff --git a/sentry-time/Cargo.toml b/sentry-time/Cargo.toml new file mode 100644 index 000000000..f6b69ca4c --- /dev/null +++ b/sentry-time/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "sentry-time" +version = "0.49.1" +authors.workspace = true +edition.workspace = true +rust-version.workspace = true +description = """ +Time based functions supporting all targets including WASM. +""" +homepage.workspace = true +repository.workspace = true +license = "MIT" + +[dependencies] +web-time = "1" diff --git a/sentry-time/src/lib.rs b/sentry-time/src/lib.rs new file mode 100644 index 000000000..e2d4a4522 --- /dev/null +++ b/sentry-time/src/lib.rs @@ -0,0 +1,19 @@ +use std::time::SystemTime; + +pub use web_time::Instant; + +/// Returns the current wall-clock time as a [`std::time::SystemTime`], sourced from +/// [`web_time::SystemTime`] so it works on `wasm32-unknown-unknown` (where +/// [`std::time::SystemTime::now`] panics). +pub fn now_system_time() -> SystemTime { + #[cfg(not(all(target_family = "wasm", target_os = "unknown")))] + { + SystemTime::now() + } + + #[cfg(all(target_family = "wasm", target_os = "unknown"))] + { + use web_time::web::SystemTimeExt as _; + web_time::SystemTime::now().to_std() + } +} diff --git a/sentry-tower/Cargo.toml b/sentry-tower/Cargo.toml index d295986bb..0246163e5 100644 --- a/sentry-tower/Cargo.toml +++ b/sentry-tower/Cargo.toml @@ -2,34 +2,26 @@ name = "sentry-tower" version = "0.49.1" authors = { workspace = true } -license = "MIT" -readme = "README.md" -repository = { workspace = true } -homepage = { workspace = true } +edition = { workspace = true } +rust-version = { workspace = true } description = """ Sentry integration for tower-based crates. """ -edition = { workspace = true } -rust-version = { workspace = true } - -[lints] -workspace = true +readme = "README.md" +homepage = { workspace = true } +repository = { workspace = true } +license = "MIT" [package.metadata.docs.rs] all-features = true -[features] -default = [] -http = ["dep:http", "pin-project", "url"] -axum-matched-path = ["http", "axum/matched-path"] - [dependencies] axum = { workspace = true, optional = true } -tower-layer = { workspace = true } -tower-service = { workspace = true } http = { workspace = true, optional = true } pin-project = { workspace = true, optional = true } sentry-core = { workspace = true, features = ["client"] } +tower-layer = { workspace = true } +tower-service = { workspace = true } url = { workspace = true, optional = true } [dev-dependencies] @@ -39,4 +31,12 @@ sentry = { workspace = true, features = ["test"] } sentry-anyhow = { workspace = true } tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } tonic = { workspace = true, features = ["transport"] } -tower = { workspace = true, features = ["util", "timeout"] } +tower = { workspace = true, features = ["timeout", "util"] } + +[features] +default = [] +axum-matched-path = ["axum/matched-path", "http"] +http = ["dep:http", "pin-project", "url"] + +[lints] +workspace = true diff --git a/sentry-tracing/Cargo.toml b/sentry-tracing/Cargo.toml index 53ba7124a..fd4327a0a 100644 --- a/sentry-tracing/Cargo.toml +++ b/sentry-tracing/Cargo.toml @@ -2,38 +2,39 @@ name = "sentry-tracing" version = "0.49.1" authors = { workspace = true } -license = "MIT" -readme = "README.md" -repository = { workspace = true } -homepage = { workspace = true } +edition = { workspace = true } +rust-version = { workspace = true } description = """ Sentry integration for the tracing and tracing-subscriber crates. """ -edition = { workspace = true } -rust-version = { workspace = true } - -[lints] -workspace = true +readme = "README.md" +homepage = { workspace = true } +repository = { workspace = true } +license = "MIT" [package.metadata.docs.rs] all-features = true -[features] -default = [] -backtrace = ["dep:sentry-backtrace"] -logs = ["sentry-core/logs"] - [dependencies] +bitflags = { workspace = true } +sentry-backtrace = { workspace = true, optional = true } sentry-core = { workspace = true, features = ["client"] } +sentry-time.workspace = true tracing-core = { workspace = true } tracing-subscriber = { workspace = true, features = ["std"] } -sentry-backtrace = { workspace = true, optional = true } -bitflags = { workspace = true } [dev-dependencies] log = { workspace = true } sentry = { workspace = true, features = ["test", "tracing"] } serde_json = { workspace = true } +tokio = { workspace = true, features = ["macros", "rt-multi-thread", "time"] } tracing = { workspace = true } tracing-subscriber = { workspace = true, features = ["fmt", "registry"] } -tokio = { workspace = true, features = ["rt-multi-thread", "macros", "time"] } + +[features] +default = [] +backtrace = ["dep:sentry-backtrace"] +logs = ["sentry-core/logs"] + +[lints] +workspace = true diff --git a/sentry-tracing/src/converters.rs b/sentry-tracing/src/converters.rs index 6c82a6657..6cef3a0ac 100644 --- a/sentry-tracing/src/converters.rs +++ b/sentry-tracing/src/converters.rs @@ -6,7 +6,8 @@ use sentry_core::protocol::{Event, Exception, Mechanism, Value}; use sentry_core::protocol::{Log, LogAttribute, LogLevel}; use sentry_core::{event_from_error, Breadcrumb, Level, TransactionOrSpan}; #[cfg(feature = "logs")] -use std::time::SystemTime; +use sentry_time::now_system_time; +#[cfg(feature = "logs")] use tracing_core::field::{Field, Visit}; use tracing_core::Subscriber; use tracing_subscriber::layer::Context; @@ -381,7 +382,7 @@ where level: level_to_log_level(event.metadata().level()), body: message.unwrap_or_default(), trace_id: None, - timestamp: SystemTime::now(), + timestamp: now_system_time(), severity_number: None, attributes, } diff --git a/sentry-types/Cargo.toml b/sentry-types/Cargo.toml index ab7afb172..3d4f4816e 100644 --- a/sentry-types/Cargo.toml +++ b/sentry-types/Cargo.toml @@ -2,31 +2,25 @@ name = "sentry-types" version = "0.49.1" authors = { workspace = true } -license = "MIT" -readme = "README.md" -repository = { workspace = true } -homepage = { workspace = true } +edition = { workspace = true } +rust-version = { workspace = true } description = """ Common reusable types for implementing the sentry.io protocol. """ -keywords = ["sentry", "protocol"] -edition = { workspace = true } -rust-version = { workspace = true } - -[lints] -workspace = true +readme = "README.md" +homepage = { workspace = true } +repository = { workspace = true } +license = "MIT" +keywords = ["protocol", "sentry"] [package.metadata.docs.rs] all-features = true -[features] -default = ["protocol"] -protocol = [] - [dependencies] debugid = { workspace = true, features = ["serde"] } hex = { workspace = true } rand = { workspace = true } +sentry-time = { workspace = true } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } thiserror = { workspace = true } @@ -36,3 +30,10 @@ uuid = { workspace = true, features = ["serde"] } [dev-dependencies] rstest = { workspace = true } + +[features] +default = ["protocol"] +protocol = [] + +[lints] +workspace = true diff --git a/sentry-types/src/auth.rs b/sentry-types/src/auth.rs index 5edb715a8..b36daa67a 100644 --- a/sentry-types/src/auth.rs +++ b/sentry-types/src/auth.rs @@ -3,6 +3,7 @@ use std::fmt; use std::str::FromStr; use std::time::SystemTime; +use sentry_time::now_system_time; use serde::{Deserialize, Serialize}; use thiserror::Error; use url::form_urlencoded; @@ -175,7 +176,7 @@ impl FromStr for Auth { pub(crate) fn auth_from_dsn_and_client(dsn: &Dsn, client: Option<&str>) -> Auth { Auth { - timestamp: Some(SystemTime::now()), + timestamp: Some(now_system_time()), client: client.map(|x| x.to_string()), version: protocol::LATEST, key: dsn.public_key().to_string(), diff --git a/sentry-types/src/protocol/client_report/mod.rs b/sentry-types/src/protocol/client_report/mod.rs index 91a170f22..e5498a541 100644 --- a/sentry-types/src/protocol/client_report/mod.rs +++ b/sentry-types/src/protocol/client_report/mod.rs @@ -4,6 +4,7 @@ use std::time::SystemTime; +use sentry_time::now_system_time; use serde::{Deserialize, Serialize}; use self::list::ClientReportList; @@ -21,7 +22,10 @@ mod relay_size; /// [client report]: https://develop.sentry.dev/sdk/telemetry/client-reports/ #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct Report { - #[serde(default = "SystemTime::now", with = "utils::ts_seconds_float")] + #[serde( + default = "sentry_time::now_system_time", + with = "utils::ts_seconds_float" + )] timestamp: SystemTime, discarded_events: ClientReportList, } @@ -129,7 +133,7 @@ impl Report { I: IntoIterator, I::Item: Into, { - let timestamp = SystemTime::now(); + let timestamp = now_system_time(); let discarded_events = reports.into_iter().map(Into::into).collect(); Self { diff --git a/sentry-types/src/protocol/session.rs b/sentry-types/src/protocol/session.rs index 2bd0f4a57..6059f1a62 100644 --- a/sentry-types/src/protocol/session.rs +++ b/sentry-types/src/protocol/session.rs @@ -108,7 +108,7 @@ pub struct SessionUpdate<'a> { pub timestamp: Option, /// The timestamp of when the session itself started. - #[serde(default = "SystemTime::now", with = "ts_rfc3339")] + #[serde(default = "sentry_time::now_system_time", with = "ts_rfc3339")] pub started: SystemTime, /// A flag that indicates that this is the initial transmission of the session. diff --git a/sentry-types/src/protocol/v7.rs b/sentry-types/src/protocol/v7.rs index f05394258..d63bb70b2 100644 --- a/sentry-types/src/protocol/v7.rs +++ b/sentry-types/src/protocol/v7.rs @@ -16,6 +16,7 @@ use std::str; use std::time::SystemTime; use self::debugid::{CodeId, DebugId}; +use sentry_time::now_system_time; use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; use thiserror::Error; @@ -748,7 +749,7 @@ mod breadcrumb { #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct Breadcrumb { /// The timestamp of the breadcrumb. This is required. - #[serde(default = "SystemTime::now", with = "ts_seconds_float")] + #[serde(default = "sentry_time::now_system_time", with = "ts_seconds_float")] pub timestamp: SystemTime, /// The type of the breadcrumb. #[serde( @@ -778,7 +779,7 @@ pub struct Breadcrumb { impl Default for Breadcrumb { fn default() -> Breadcrumb { Breadcrumb { - timestamp: SystemTime::now(), + timestamp: now_system_time(), ty: breadcrumb::default_type(), category: Default::default(), level: breadcrumb::default_level(), @@ -1676,7 +1677,7 @@ pub struct Event<'a> { /// The timestamp of when the event was created. /// /// This can be set to `None` in which case the server will set a timestamp. - #[serde(default = "SystemTime::now", with = "ts_seconds_float")] + #[serde(default = "sentry_time::now_system_time", with = "ts_seconds_float")] pub timestamp: SystemTime, /// Optionally the server (or device) name of this event. #[serde(default, skip_serializing_if = "Option::is_none")] @@ -1745,7 +1746,7 @@ impl Default for Event<'_> { logger: Default::default(), modules: Default::default(), platform: event::default_platform(), - timestamp: SystemTime::now(), + timestamp: now_system_time(), server_name: Default::default(), release: Default::default(), dist: Default::default(), @@ -1852,7 +1853,7 @@ pub struct Span { )] pub timestamp: Option, /// The timestamp at the measuring of the span started. - #[serde(default = "SystemTime::now", with = "ts_seconds_float")] + #[serde(default = "sentry_time::now_system_time", with = "ts_seconds_float")] pub start_timestamp: SystemTime, /// Describes the status of the span (e.g. `ok`, `cancelled`, etc.) #[serde(default, skip_serializing_if = "Option::is_none")] @@ -1872,7 +1873,7 @@ impl Default for Span { trace_id: Default::default(), timestamp: Default::default(), tags: Default::default(), - start_timestamp: SystemTime::now(), + start_timestamp: now_system_time(), description: Default::default(), status: Default::default(), parent_span_id: Default::default(), @@ -1896,7 +1897,7 @@ impl Span { /// Finalizes the span. pub fn finish(&mut self) { - self.timestamp = Some(SystemTime::now()); + self.timestamp = Some(now_system_time()); } } @@ -2069,7 +2070,7 @@ pub struct Transaction<'a> { )] pub timestamp: Option, /// The start time of the transaction. - #[serde(default = "SystemTime::now", with = "ts_seconds_float")] + #[serde(default = "sentry_time::now_system_time", with = "ts_seconds_float")] pub start_timestamp: SystemTime, /// The collection of finished spans part of this transaction. pub spans: Vec, @@ -2101,7 +2102,7 @@ impl Default for Transaction<'_> { sdk: Default::default(), platform: event::default_platform(), timestamp: Default::default(), - start_timestamp: SystemTime::now(), + start_timestamp: now_system_time(), spans: Default::default(), contexts: Default::default(), request: Default::default(), @@ -2139,7 +2140,7 @@ impl<'a> Transaction<'a> { /// Finalizes the transaction to be dispatched. pub fn finish(&mut self) { - self.timestamp = Some(SystemTime::now()); + self.timestamp = Some(now_system_time()); } /// Finalizes the transaction to be dispatched with the given end timestamp. diff --git a/sentry/tests/test_basic.rs b/sentry/tests/test_basic.rs index eb1222d5e..32d0243f3 100644 --- a/sentry/tests/test_basic.rs +++ b/sentry/tests/test_basic.rs @@ -265,20 +265,20 @@ fn test_panic_scope_pop() { #[cfg(feature = "logs")] #[test] fn test_basic_capture_log() { - use std::time::SystemTime; - use sentry::{protocol::Log, protocol::LogAttribute, protocol::Map, Hub}; let options = sentry::ClientOptions::new().enable_logs(true); let envelopes = sentry::test::with_captured_envelopes_options( || { + use sentry::sentry_time::now_system_time; + 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(), + timestamp: now_system_time(), severity_number: None, attributes, };