From 9f180d6eb91a72a7449307cd1f63528225b65a08 Mon Sep 17 00:00:00 2001 From: Omid Rad Date: Mon, 2 Sep 2024 11:17:49 +0200 Subject: [PATCH] Support otel 0.24 (#127) * Support otel 0.24 * fix the otel example * Fix examples and last bits * Update examples/custom-root-span/src/main.rs * Update examples/opentelemetry/src/main.rs --------- Co-authored-by: Luca Palmieri <20745048+LukeMathWalker@users.noreply.github.com> --- .github/workflows/general.yml | 1 + Cargo.toml | 3 ++ README.md | 1 + examples/custom-root-span/Cargo.toml | 15 ++++++---- examples/custom-root-span/src/main.rs | 42 ++++++++++++++++++++------- examples/opentelemetry/Cargo.toml | 15 ++++++---- examples/opentelemetry/src/main.rs | 39 +++++++++++++++++-------- src/lib.rs | 3 ++ src/otel.rs | 6 ++++ src/root_span_macro.rs | 3 +- 10 files changed, 93 insertions(+), 35 deletions(-) diff --git a/.github/workflows/general.yml b/.github/workflows/general.yml index 4c574d0..ab6a557 100644 --- a/.github/workflows/general.yml +++ b/.github/workflows/general.yml @@ -59,6 +59,7 @@ jobs: - opentelemetry_0_21 - opentelemetry_0_22 - opentelemetry_0_23 + - opentelemetry_0_24 steps: - uses: actions/checkout@v2 - name: Cache dependencies diff --git a/Cargo.toml b/Cargo.toml index 08484a3..d936070 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,6 +31,7 @@ opentelemetry_0_20 = ["opentelemetry_0_20_pkg", "tracing-opentelemetry_0_21_pkg" opentelemetry_0_21 = ["opentelemetry_0_21_pkg", "tracing-opentelemetry_0_22_pkg"] opentelemetry_0_22 = ["opentelemetry_0_22_pkg", "tracing-opentelemetry_0_23_pkg"] opentelemetry_0_23 = ["opentelemetry_0_23_pkg", "tracing-opentelemetry_0_24_pkg"] +opentelemetry_0_24 = ["opentelemetry_0_24_pkg", "tracing-opentelemetry_0_25_pkg"] emit_event_on_error = [] uuid_v7 = ["uuid/v7"] @@ -51,6 +52,7 @@ opentelemetry_0_20_pkg = { package = "opentelemetry", version = "0.20", optional opentelemetry_0_21_pkg = { package = "opentelemetry", version = "0.21", optional = true } opentelemetry_0_22_pkg = { package = "opentelemetry", version = "0.22", optional = true } opentelemetry_0_23_pkg = { package = "opentelemetry", version = "0.23", optional = true } +opentelemetry_0_24_pkg = { package = "opentelemetry", version = "0.24", 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 } tracing-opentelemetry_0_14_pkg = { package = "tracing-opentelemetry", version = "0.14", optional = true } @@ -62,6 +64,7 @@ tracing-opentelemetry_0_21_pkg = { package = "tracing-opentelemetry", version = tracing-opentelemetry_0_22_pkg = { package = "tracing-opentelemetry", version = "0.22", optional = true } tracing-opentelemetry_0_23_pkg = { package = "tracing-opentelemetry", version = "0.23", optional = true } tracing-opentelemetry_0_24_pkg = { package = "tracing-opentelemetry", version = "0.24", optional = true } +tracing-opentelemetry_0_25_pkg = { package = "tracing-opentelemetry", version = "0.25", optional = true } [dev-dependencies] actix-web = { version = "4", default-features = false, features = ["macros"] } diff --git a/README.md b/README.md index 8990c31..ba300e9 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ actix-web = "4" - `opentelemetry_0_21`: same as above but using `opentelemetry` 0.21; - `opentelemetry_0_22`: same as above but using `opentelemetry` 0.22; - `opentelemetry_0_23`: same as above but using `opentelemetry` 0.23; +- `opentelemetry_0_24`: same as above but using `opentelemetry` 0.24; - `emit_event_on_error`: emit a [`tracing`] event when request processing fails with an error (enabled by default). - `uuid_v7`: use the UUID v7 implementation inside [`RequestId`] instead of UUID v4 (disabled by default). ## Quickstart diff --git a/examples/custom-root-span/Cargo.toml b/examples/custom-root-span/Cargo.toml index 9c5133a..f2f39ea 100644 --- a/examples/custom-root-span/Cargo.toml +++ b/examples/custom-root-span/Cargo.toml @@ -2,16 +2,19 @@ name = "custom-root-span" version = "0.1.0" authors = ["LukeMathWalker "] -edition = "2018" +edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] actix-web = "4" -opentelemetry = "0.22" -opentelemetry-jaeger = { version = "0.21", features = ["rt-tokio-current-thread"] } -tracing-opentelemetry = { version = "0.23" } -tracing = "0.1.19" +once_cell = "1.19" +opentelemetry = "0.24" +opentelemetry-otlp = "0.17" +opentelemetry_sdk = { version = "0.24", features = ["rt-tokio-current-thread"] } +opentelemetry-semantic-conventions = "0.16" +tracing-opentelemetry = { version = "0.25" } +tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["registry", "env-filter"] } tracing-bunyan-formatter = "0.3" -tracing-actix-web = { path = "../.." } +tracing-actix-web = { path = "../..", features = ["opentelemetry_0_24"] } diff --git a/examples/custom-root-span/src/main.rs b/examples/custom-root-span/src/main.rs index 7930ef0..f69c790 100644 --- a/examples/custom-root-span/src/main.rs +++ b/examples/custom-root-span/src/main.rs @@ -1,15 +1,19 @@ use actix_web::body::MessageBody; use actix_web::dev::{ServiceRequest, ServiceResponse}; use actix_web::{web, App, Error, HttpServer}; -use opentelemetry::{ - global, runtime::TokioCurrentThread, sdk::propagation::TraceContextPropagator, +use once_cell::sync::Lazy; +use opentelemetry::trace::TracerProvider; +use opentelemetry::{global, KeyValue}; +use opentelemetry_otlp::WithExportConfig; +use opentelemetry_sdk::{ + propagation::TraceContextPropagator, runtime::TokioCurrentThread, trace::Config, Resource, }; +use opentelemetry_semantic_conventions::resource; use std::io; use tracing::Span; use tracing_actix_web::{DefaultRootSpanBuilder, RootSpan, RootSpanBuilder, TracingLogger}; use tracing_bunyan_formatter::{BunyanFormattingLayer, JsonStorageLayer}; -use tracing_subscriber::layer::SubscriberExt; -use tracing_subscriber::{EnvFilter, Registry}; +use tracing_subscriber::{layer::SubscriberExt, EnvFilter, Registry}; /// We will define a custom root span builder to capture additional fields, specific /// to our application, on top of the ones provided by `DefaultRootSpanBuilder` out of the box. @@ -68,22 +72,40 @@ async fn main() -> io::Result<()> { Ok(()) } +const APP_NAME: &str = "tracing-actix-web-demo"; + +static RESOURCE: Lazy = + Lazy::new(|| Resource::new(vec![KeyValue::new(resource::SERVICE_NAME, APP_NAME)])); + /// Init a `tracing` subscriber that prints spans to stdout as well as /// ships them to Jaeger. /// /// Check the `opentelemetry` example for more details. fn init_telemetry() { - let app_name = "tracing-actix-web-demo"; - + // Start a new otlp trace pipeline. + // Spans are exported in batch - recommended setup for a production application. global::set_text_map_propagator(TraceContextPropagator::new()); - let tracer = opentelemetry_jaeger::new_agent_pipeline() - .with_service_name(app_name) + let tracer = opentelemetry_otlp::new_pipeline() + .tracing() + .with_exporter( + opentelemetry_otlp::new_exporter() + .tonic() + .with_endpoint("http://localhost:4317"), + ) + .with_trace_config(Config::default().with_resource(RESOURCE.clone())) .install_batch(TokioCurrentThread) - .expect("Failed to install OpenTelemetry tracer."); + .expect("Failed to install OpenTelemetry tracer.") + .tracer_builder(APP_NAME) + .build(); + // Filter based on level - trace, debug, info, warn, error + // Tunable via `RUST_LOG` env variable let env_filter = EnvFilter::try_from_default_env().unwrap_or(EnvFilter::new("info")); + // Create a `tracing` layer using the otlp tracer let telemetry = tracing_opentelemetry::layer().with_tracer(tracer); - let formatting_layer = BunyanFormattingLayer::new(app_name.into(), std::io::stdout); + // Create a `tracing` layer to emit spans as structured logs to stdout + let formatting_layer = BunyanFormattingLayer::new(APP_NAME.into(), std::io::stdout); + // Combined them all together in a `tracing` subscriber let subscriber = Registry::default() .with(env_filter) .with(telemetry) diff --git a/examples/opentelemetry/Cargo.toml b/examples/opentelemetry/Cargo.toml index 92bdd14..26cfa24 100644 --- a/examples/opentelemetry/Cargo.toml +++ b/examples/opentelemetry/Cargo.toml @@ -2,16 +2,19 @@ name = "otel" version = "0.1.0" authors = ["Luca Palmieri "] -edition = "2018" +edition = "2021" license = "MIT/Apache-2.0" [dependencies] actix-web = "4" -tracing = "0.1.19" -opentelemetry = "0.23" -opentelemetry-jaeger = { version = "0.22", features = ["rt-tokio-current-thread"] } -tracing-opentelemetry = { version = "0.24" } +once_cell = "1.19" +opentelemetry = "0.24" +opentelemetry_sdk = { version = "0.24", features = ["rt-tokio-current-thread"] } +opentelemetry-otlp = "0.17" +opentelemetry-semantic-conventions = "0.16" +tracing-opentelemetry = "0.25" tracing-subscriber = { version = "0.3", features = ["registry", "env-filter"] } tracing-bunyan-formatter = "0.3" -tracing-actix-web = { path = "../..", features = ["opentelemetry_0_23"] } +tracing-actix-web = { path = "../..", features = ["opentelemetry_0_24"] } +tracing = "0.1.40" diff --git a/examples/opentelemetry/src/main.rs b/examples/opentelemetry/src/main.rs index ac56ff8..73ff294 100644 --- a/examples/opentelemetry/src/main.rs +++ b/examples/opentelemetry/src/main.rs @@ -1,35 +1,50 @@ use actix_web::{web, App, HttpServer}; -use opentelemetry::{ - global, runtime::TokioCurrentThread, sdk::propagation::TraceContextPropagator, +use once_cell::sync::Lazy; +use opentelemetry::trace::TracerProvider; +use opentelemetry::{global, KeyValue}; +use opentelemetry_otlp::WithExportConfig; +use opentelemetry_sdk::{ + propagation::TraceContextPropagator, runtime::TokioCurrentThread, trace::Config, Resource, }; +use opentelemetry_semantic_conventions::resource; use std::io; use tracing_actix_web::TracingLogger; use tracing_bunyan_formatter::{BunyanFormattingLayer, JsonStorageLayer}; -use tracing_subscriber::layer::SubscriberExt; -use tracing_subscriber::{EnvFilter, Registry}; +use tracing_subscriber::{layer::SubscriberExt, EnvFilter, Registry}; + +const APP_NAME: &str = "tracing-actix-web-demo"; + +static RESOURCE: Lazy = + Lazy::new(|| Resource::new(vec![KeyValue::new(resource::SERVICE_NAME, APP_NAME)])); async fn hello() -> &'static str { "Hello world!" } fn init_telemetry() { - let app_name = "tracing-actix-web-demo"; - - // Start a new Jaeger trace pipeline. + // Start a new otlp trace pipeline. // Spans are exported in batch - recommended setup for a production application. global::set_text_map_propagator(TraceContextPropagator::new()); - let tracer = opentelemetry_jaeger::new_agent_pipeline() - .with_service_name(app_name) + let tracer = opentelemetry_otlp::new_pipeline() + .tracing() + .with_exporter( + opentelemetry_otlp::new_exporter() + .tonic() + .with_endpoint("http://localhost:4317"), + ) + .with_trace_config(Config::default().with_resource(RESOURCE.clone())) .install_batch(TokioCurrentThread) - .expect("Failed to install OpenTelemetry tracer."); + .expect("Failed to install OpenTelemetry tracer.") + .tracer_builder(APP_NAME) + .build(); // Filter based on level - trace, debug, info, warn, error // Tunable via `RUST_LOG` env variable let env_filter = EnvFilter::try_from_default_env().unwrap_or(EnvFilter::new("info")); - // Create a `tracing` layer using the Jaeger tracer + // Create a `tracing` layer using the otlp tracer let telemetry = tracing_opentelemetry::layer().with_tracer(tracer); // Create a `tracing` layer to emit spans as structured logs to stdout - let formatting_layer = BunyanFormattingLayer::new(app_name.into(), std::io::stdout); + let formatting_layer = BunyanFormattingLayer::new(APP_NAME.into(), std::io::stdout); // Combined them all together in a `tracing` subscriber let subscriber = Registry::default() .with(env_filter) diff --git a/src/lib.rs b/src/lib.rs index ef612ce..5ce13b5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,6 +30,7 @@ //! - `opentelemetry_0_21`: same as above but using `opentelemetry` 0.21; //! - `opentelemetry_0_22`: same as above but using `opentelemetry` 0.22; //! - `opentelemetry_0_23`: same as above but using `opentelemetry` 0.23; +//! - `opentelemetry_0_24`: same as above but using `opentelemetry` 0.24; //! - `emit_event_on_error`: emit a [`tracing`] event when request processing fails with an error (enabled by default). //! - `uuid_v7`: use the UUID v7 implementation inside [`RequestId`] instead of UUID v4 (disabled by default). //! @@ -305,6 +306,7 @@ mutually_exclusive_features::none_or_one_of!( "opentelemetry_0_21", "opentelemetry_0_22", "opentelemetry_0_23", + "opentelemetry_0_24", ); #[cfg(any( @@ -319,5 +321,6 @@ mutually_exclusive_features::none_or_one_of!( feature = "opentelemetry_0_21", feature = "opentelemetry_0_22", feature = "opentelemetry_0_23", + feature = "opentelemetry_0_24", ))] mod otel; diff --git a/src/otel.rs b/src/otel.rs index 72ac021..d180f19 100644 --- a/src/otel.rs +++ b/src/otel.rs @@ -22,6 +22,8 @@ use opentelemetry_0_21_pkg as opentelemetry; use opentelemetry_0_22_pkg as opentelemetry; #[cfg(feature = "opentelemetry_0_23")] use opentelemetry_0_23_pkg as opentelemetry; +#[cfg(feature = "opentelemetry_0_24")] +use opentelemetry_0_24_pkg as opentelemetry; #[cfg(feature = "opentelemetry_0_13")] use tracing_opentelemetry_0_12_pkg as tracing_opentelemetry; @@ -45,6 +47,8 @@ use tracing_opentelemetry_0_22_pkg as tracing_opentelemetry; use tracing_opentelemetry_0_23_pkg as tracing_opentelemetry; #[cfg(feature = "opentelemetry_0_23")] use tracing_opentelemetry_0_24_pkg as tracing_opentelemetry; +#[cfg(feature = "opentelemetry_0_24")] +use tracing_opentelemetry_0_25_pkg as tracing_opentelemetry; use opentelemetry::propagation::Extractor; @@ -86,6 +90,7 @@ pub(crate) fn set_otel_parent(req: &ServiceRequest, span: &tracing::Span) { feature = "opentelemetry_0_21", feature = "opentelemetry_0_22", feature = "opentelemetry_0_23", + feature = "opentelemetry_0_24", )))] let trace_id = span.context().span().span_context().trace_id().to_hex(); @@ -97,6 +102,7 @@ pub(crate) fn set_otel_parent(req: &ServiceRequest, span: &tracing::Span) { feature = "opentelemetry_0_21", feature = "opentelemetry_0_22", feature = "opentelemetry_0_23", + feature = "opentelemetry_0_24", ))] let trace_id = { let id = span.context().span().span_context().trace_id(); diff --git a/src/root_span_macro.rs b/src/root_span_macro.rs index 9aff8fd..40087cd 100644 --- a/src/root_span_macro.rs +++ b/src/root_span_macro.rs @@ -1,5 +1,5 @@ #[macro_export] -/// [`root_span!`] creates a new [`tracing::Span`]. +/// `root_span!` creates a new [`tracing::Span`]. /// It empowers you to add custom properties to the root span on top of the HTTP properties tracked /// by [`DefaultRootSpanBuilder`]. /// @@ -167,6 +167,7 @@ pub mod private { feature = "opentelemetry_0_21", feature = "opentelemetry_0_22", feature = "opentelemetry_0_23", + feature = "opentelemetry_0_24", ))] crate::otel::set_otel_parent(req, span); }