1
0
mirror of https://github.com/actix/actix-extras.git synced 2025-02-22 18:33:18 +01:00

Support updated OT 0.14 / tracing-OT 0.13 crate versions (#23)

* Support updated OT 0.14 / tracing-OT 0.12 crate versions

Add support for opentelemetry 0.14 and tracing-opentelemetry 0.13.
Make corresponding changes to the features, docs, and examples.
Due to the use of two different versions of the same packages, some
reorganization had to be done for the internal modules.

Addresses issue #22.

* Re-export versioned set_otel_parent `fn`s for use in macro
This commit is contained in:
Brian Rogers 2021-07-03 09:33:59 -07:00 committed by GitHub
parent 6a11157de7
commit 2367e71ff4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 109 additions and 59 deletions

View File

@ -20,7 +20,8 @@ categories = ["asynchronous", "web-programming"]
[features]
default = ["opentelemetry_0_13", "emit_event_on_error"]
opentelemetry_0_13 = ["opentelemetry", "tracing-opentelemetry"]
opentelemetry_0_13 = ["opentelemetry_0_13_pkg", "tracing-opentelemetry_0_12_pkg"]
opentelemetry_0_14 = ["opentelemetry_0_14_pkg", "tracing-opentelemetry_0_13_pkg"]
emit_event_on_error = []
[dependencies]
@ -31,8 +32,10 @@ tracing = "0.1.19"
tracing-futures = "0.2.4"
futures = "0.3.5"
uuid = { version = "0.8.1", features = ["v4"] }
opentelemetry = { version = "0.13", optional = true }
tracing-opentelemetry = { version = "0.12", optional = true }
opentelemetry_0_13_pkg = { package = "opentelemetry", version = "0.13", optional = true }
opentelemetry_0_14_pkg = { package = "opentelemetry", version = "0.14", optional = true }
tracing-opentelemetry_0_12_pkg = { package = "tracing-opentelemetry",version = "0.12", optional = true }
tracing-opentelemetry_0_13_pkg = { package = "tracing-opentelemetry", version = "0.13", optional = true }
[dev-dependencies]
tracing-subscriber = { version = "0.2.12", features = ["registry", "env-filter"] }

View File

@ -40,12 +40,11 @@ tracing = "0.1"
actix-web = "4.0.0-beta.7"
```
`tracing-actix-web` exposes two feature flags:
`tracing-actix-web` exposes three feature flags:
- `opentelemetry_0_13`: attach [OpenTelemetry](https://github.com/open-telemetry/opentelemetry-rust)'s context to the root span;
- `emit_event_on_error`: emit a [`tracing`] event when request processing fails with an error.
They are both enabled by default.
- `opentelemetry_0_13`: attach [OpenTelemetry](https://github.com/open-telemetry/opentelemetry-rust)'s context to the root span using OTEL 0.13 (enabled by default).
- `opentelemetry_0_14`: same as above but using OTEL 0.14.
- `emit_event_on_error`: emit a [`tracing`] event when request processing fails with an error (enabled by default).
`tracing-actix-web` will release `0.4.0`, going out of beta, as soon as `actix-web` releases a stable `4.0.0`.
@ -242,7 +241,7 @@ async fn index(request_id: RequestId) -> String {
`tracing-actix-web` follows [OpenTelemetry's semantic convention](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/overview.md#spancontext)
for field names.
Furthermore, if you have not disabled the `opentelemetry_0_13` feature flag, `tracing-actix-web` automatically
Furthermore, if you have not disabled the `opentelemetry_0_13` or `opentelemetry_0_14` feature flags, `tracing-actix-web` automatically
performs trace propagation according to the OpenTelemetry standard.
It tries to extract the OpenTelemetry context out of the headers of incoming requests and, when it finds one, it sets
it as the remote context for the current root span.

View File

@ -9,9 +9,9 @@ license = "MIT/Apache-2.0"
[dependencies]
actix-web = "=4.0.0-beta.7"
tracing = "0.1.19"
opentelemetry = { version = "0.13", features = ["rt-tokio-current-thread"] }
opentelemetry-jaeger = { version = "0.12", features = ["tokio"] }
tracing-opentelemetry = { version = "0.12" }
opentelemetry = { version = "0.14", features = ["rt-tokio-current-thread"] }
opentelemetry-jaeger = { version = "0.13", features = ["tokio"] }
tracing-opentelemetry = { version = "0.13" }
tracing-subscriber = { version = "0.2.12", features = ["registry", "env-filter"] }
tracing-bunyan-formatter = "0.1.6"
tracing-actix-web = { path = "../.." }
tracing-actix-web = { path = "../..", features = ["opentelemetry_0_14"] }

View File

@ -13,12 +13,11 @@
//! actix-web = "4.0.0-beta.7"
//! ```
//!
//! `tracing-actix-web` exposes two feature flags:
//! `tracing-actix-web` exposes three feature flags:
//!
//! - `opentelemetry_0_13`: attach [OpenTelemetry](https://github.com/open-telemetry/opentelemetry-rust)'s context to the root span;
//! - `emit_event_on_error`: emit a [`tracing`] event when request processing fails with an error.
//!
//! They are both enabled by default.
//! - `opentelemetry_0_13`: attach [OpenTelemetry](https://github.com/open-telemetry/opentelemetry-rust)'s context to the root span using OTEL 0.13 (enabled by default).
//! - `opentelemetry_0_14`: same as above but using OTEL 0.14.
//! - `emit_event_on_error`: emit a [`tracing`] event when request processing fails with an error (enabled by default).
//!
//! `tracing-actix-web` will release `0.4.0`, going out of beta, as soon as `actix-web` releases a stable `4.0.0`.
//!
@ -215,7 +214,7 @@
//!
//! `tracing-actix-web` follows [OpenTelemetry's semantic convention](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/overview.md#spancontext)
//! for field names.
//! Furthermore, if you have not disabled the `opentelemetry_0_13` feature flag, `tracing-actix-web` automatically
//! Furthermore, if you have not disabled the `opentelemetry_0_13` or `opentelemetry_0_14` feature flags, `tracing-actix-web` automatically
//! performs trace propagation according to the OpenTelemetry standard.
//! It tries to extract the OpenTelemetry context out of the headers of incoming requests and, when it finds one, it sets
//! it as the remote context for the current root span.
@ -245,4 +244,7 @@ pub use root_span_builder::{DefaultRootSpanBuilder, RootSpanBuilder};
pub mod root_span_macro;
#[cfg(feature = "opentelemetry_0_13")]
mod otel;
mod otel_0_13;
#[cfg(feature = "opentelemetry_0_14")]
mod otel_0_14;

View File

@ -1,21 +0,0 @@
use opentelemetry::propagation::Extractor;
pub(crate) struct RequestHeaderCarrier<'a> {
headers: &'a actix_web::http::HeaderMap,
}
impl<'a> RequestHeaderCarrier<'a> {
pub(crate) fn new(headers: &'a actix_web::http::HeaderMap) -> Self {
RequestHeaderCarrier { headers }
}
}
impl<'a> Extractor for RequestHeaderCarrier<'a> {
fn get(&self, key: &str) -> Option<&str> {
self.headers.get(key).and_then(|v| v.to_str().ok())
}
fn keys(&self) -> Vec<&str> {
self.headers.keys().map(|header| header.as_str()).collect()
}
}

36
src/otel_0_13.rs Normal file
View File

@ -0,0 +1,36 @@
use actix_web::dev::ServiceRequest;
use opentelemetry_0_13_pkg::propagation::Extractor;
pub(crate) struct RequestHeaderCarrier<'a> {
headers: &'a actix_web::http::HeaderMap,
}
impl<'a> RequestHeaderCarrier<'a> {
pub(crate) fn new(headers: &'a actix_web::http::HeaderMap) -> Self {
RequestHeaderCarrier { headers }
}
}
impl<'a> Extractor for RequestHeaderCarrier<'a> {
fn get(&self, key: &str) -> Option<&str> {
self.headers.get(key).and_then(|v| v.to_str().ok())
}
fn keys(&self) -> Vec<&str> {
self.headers.keys().map(|header| header.as_str()).collect()
}
}
pub(crate) fn set_otel_parent(req: &ServiceRequest, span: &tracing::Span) {
use opentelemetry_0_13_pkg::trace::TraceContextExt as _;
use tracing_opentelemetry_0_12_pkg::OpenTelemetrySpanExt as _;
let parent_context = opentelemetry_0_13_pkg::global::get_text_map_propagator(|propagator| {
propagator.extract(&crate::otel_0_13::RequestHeaderCarrier::new(req.headers()))
});
span.set_parent(parent_context);
// If we have a remote parent span, this will be the parent's trace identifier.
// If not, it will be the newly generated trace identifier with this request as root span.
let trace_id = span.context().span().span_context().trace_id().to_hex();
span.record("trace_id", &tracing::field::display(trace_id));
}

36
src/otel_0_14.rs Normal file
View File

@ -0,0 +1,36 @@
use actix_web::dev::ServiceRequest;
use opentelemetry_0_14_pkg::propagation::Extractor;
pub(crate) struct RequestHeaderCarrier<'a> {
headers: &'a actix_web::http::HeaderMap,
}
impl<'a> RequestHeaderCarrier<'a> {
pub(crate) fn new(headers: &'a actix_web::http::HeaderMap) -> Self {
RequestHeaderCarrier { headers }
}
}
impl<'a> Extractor for RequestHeaderCarrier<'a> {
fn get(&self, key: &str) -> Option<&str> {
self.headers.get(key).and_then(|v| v.to_str().ok())
}
fn keys(&self) -> Vec<&str> {
self.headers.keys().map(|header| header.as_str()).collect()
}
}
pub(crate) fn set_otel_parent(req: &ServiceRequest, span: &tracing::Span) {
use opentelemetry_0_14_pkg::trace::TraceContextExt as _;
use tracing_opentelemetry_0_13_pkg::OpenTelemetrySpanExt as _;
let parent_context = opentelemetry_0_14_pkg::global::get_text_map_propagator(|propagator| {
propagator.extract(&crate::otel_0_14::RequestHeaderCarrier::new(req.headers()))
});
span.set_parent(parent_context);
// If we have a remote parent span, this will be the parent's trace identifier.
// If not, it will be the newly generated trace identifier with this request as root span.
let trace_id = span.context().span().span_context().trace_id().to_hex();
span.record("trace_id", &tracing::field::display(trace_id));
}

View File

@ -97,7 +97,12 @@ macro_rules! root_span {
);
std::mem::drop(connection_info);
$crate::root_span_macro::private::set_otel_parent(&$request, &span);
#[cfg(feature = "opentelemetry_0_13")]
$crate::root_span_macro::private::set_otel_parent_0_13(&$request, &span);
#[cfg(feature = "opentelemetry_0_14")]
$crate::root_span_macro::private::set_otel_parent_0_14(&$request, &span);
span
}
};
@ -116,26 +121,16 @@ pub mod private {
pub use tracing;
#[cfg(not(feature = "opentelemetry_0_13"))]
#[doc(hidden)]
pub fn set_otel_parent(_req: &ServiceRequest, _span: &tracing::Span) {
// No-op if the OpenTelemetry feature is not active
}
#[cfg(feature = "opentelemetry_0_13")]
#[doc(hidden)]
pub fn set_otel_parent(req: &ServiceRequest, span: &tracing::Span) {
use opentelemetry::trace::TraceContextExt as _;
use tracing_opentelemetry::OpenTelemetrySpanExt as _;
pub fn set_otel_parent_0_13(req: &ServiceRequest, span: &tracing::Span) {
crate::otel_0_13::set_otel_parent(req, span);
}
let parent_context = opentelemetry::global::get_text_map_propagator(|propagator| {
propagator.extract(&crate::otel::RequestHeaderCarrier::new(req.headers()))
});
span.set_parent(parent_context);
// If we have a remote parent span, this will be the parent's trace identifier.
// If not, it will be the newly generated trace identifier with this request as root span.
let trace_id = span.context().span().span_context().trace_id().to_hex();
span.record("trace_id", &tracing::field::display(trace_id));
#[cfg(feature = "opentelemetry_0_14")]
#[doc(hidden)]
pub fn set_otel_parent_0_14(req: &ServiceRequest, span: &tracing::Span) {
crate::otel_0_14::set_otel_parent(req, span);
}
#[doc(hidden)]