Skip to content

Commit 1519ac9

Browse files
Extract W3C traceparent header and set it as Span parent
1 parent d27d240 commit 1519ac9

5 files changed

Lines changed: 47 additions & 1 deletion

File tree

quickwit/Cargo.lock

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

quickwit/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ tower-http = { version = "0.6", features = [
285285
"compression-gzip",
286286
"compression-zstd",
287287
"cors",
288+
"trace",
288289
] }
289290
tracing = "0.1"
290291
tracing-opentelemetry = "0.32"

quickwit/quickwit-proto/src/lib.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,24 @@ pub fn set_parent_span_from_request_metadata(request_metadata: &tonic::metadata:
207207
let _ = Span::current().set_parent(parent_cx);
208208
}
209209

210+
/// `HeaderMap` extracts OpenTelemetry tracing keys from HTTP headers.
211+
struct HeaderMap<'a>(&'a http::HeaderMap);
212+
213+
impl Extractor for HeaderMap<'_> {
214+
fn get(&self, key: &str) -> Option<&str> {
215+
self.0.get(key).and_then(|metadata| metadata.to_str().ok())
216+
}
217+
218+
fn keys(&self) -> Vec<&str> {
219+
self.0.keys().map(|key| key.as_str()).collect()
220+
}
221+
}
222+
223+
/// Extracts an OpenTelemetry context from HTTP [`http::HeaderMap`].
224+
pub fn extract_context_from_request_headers(headers: &http::HeaderMap) -> ::opentelemetry::Context {
225+
global::get_text_map_propagator(|prop| prop.extract(&HeaderMap(headers)))
226+
}
227+
210228
impl search::SortOrder {
211229
#[inline(always)]
212230
pub fn compare_opt<T: Ord>(&self, this: &Option<T>, other: &Option<T>) -> Ordering {

quickwit/quickwit-serve/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ tonic-reflection = { workspace = true }
5252
tower = { workspace = true, features = ["limit"] }
5353
tower-http = { workspace = true }
5454
tracing = { workspace = true }
55+
tracing-opentelemetry = { workspace = true }
5556
utoipa = { workspace = true }
5657
warp = { workspace = true, features = ["server"] }
5758
zstd = { workspace = true }
@@ -84,10 +85,14 @@ assert-json-diff = { workspace = true }
8485
http = { workspace = true }
8586
itertools = { workspace = true }
8687
mockall = { workspace = true }
88+
opentelemetry = { workspace = true }
89+
opentelemetry_sdk = { workspace = true }
8790
tempfile = { workspace = true }
8891
tokio = { workspace = true }
8992
tokio-stream = { workspace = true }
9093
tonic = { workspace = true }
94+
tracing-opentelemetry = { workspace = true }
95+
tracing-subscriber = { workspace = true }
9196

9297
quickwit-actors = { workspace = true, features = ["testsuite"] }
9398
quickwit-cluster = { workspace = true, features = ["testsuite"] }

quickwit/quickwit-serve/src/rest.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use hyper_util::server::conn::auto::Builder;
2121
use hyper_util::service::TowerToHyperService;
2222
use quickwit_common::tower::BoxFutureInfaillible;
2323
use quickwit_config::{disable_ingest_v1, enable_ingest_v2};
24+
use quickwit_proto::extract_context_from_request_headers;
2425
use quickwit_search::SearchService;
2526
use tokio::io::{AsyncRead, AsyncWrite};
2627
use tokio::net::{TcpListener, TcpStream};
@@ -30,7 +31,9 @@ use tower::ServiceBuilder;
3031
use tower_http::compression::CompressionLayer;
3132
use tower_http::compression::predicate::{NotForContentType, Predicate, SizeAbove};
3233
use tower_http::cors::{AllowOrigin, CorsLayer};
33-
use tracing::{error, info};
34+
use tower_http::trace::TraceLayer;
35+
use tracing::{Level, error, info};
36+
use tracing_opentelemetry::OpenTelemetrySpanExt;
3437
use warp::filters::log::Info;
3538
use warp::hyper::http::HeaderValue;
3639
use warp::hyper::{Method, StatusCode, http};
@@ -208,7 +211,21 @@ pub(crate) async fn start_rest_server(
208211
let compression_predicate = CompressionPredicate::from_env().and(NotForContentType::IMAGES);
209212
let cors = build_cors(&quickwit_services.node_config.rest_config.cors_allow_origins);
210213

214+
let trace_layer = TraceLayer::new_for_http().make_span_with(|request: &http::Request<_>| {
215+
let span = tracing::span!(
216+
Level::INFO,
217+
"http_request",
218+
otel.kind = "Server",
219+
http.method = %request.method(),
220+
http.target = %request.uri(),
221+
);
222+
let ctx = extract_context_from_request_headers(request.headers());
223+
let _ = span.set_parent(ctx);
224+
span
225+
});
226+
211227
let service = ServiceBuilder::new()
228+
.layer(trace_layer)
212229
.layer(
213230
CompressionLayer::new()
214231
.zstd(true)

0 commit comments

Comments
 (0)