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)
+ [](https://crates.io/crates/sentry-opentelemetry)
+ [](https://docs.rs/sentry-opentelemetry)
+
+ An integration for the `opentelemetry` crate.
+
- [sentry-panic](./sentry-panic)
[](https://crates.io/crates/sentry-panic)
[](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 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 352094d75..27144321a 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")]