Skip to content

Commit

Permalink
Clean up tracing spans for HTTP requests (#1313)
Browse files Browse the repository at this point in the history
  • Loading branch information
svix-jplatte authored May 6, 2024
1 parent e81f1fd commit 6464f5a
Showing 1 changed file with 23 additions and 64 deletions.
87 changes: 23 additions & 64 deletions server/svix-server/src/core/otel_spans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@

//! Module defining utilities for crating `tracing` spans compatible with OpenTelemetry's
//! conventions.
use std::{borrow::Cow, net::SocketAddr};
use std::net::SocketAddr;

use axum::extract::{ConnectInfo, MatchedPath};
use http::{header, uri::Scheme, Method, Version};
use http::header;
use opentelemetry::trace::TraceContextExt;
use svix_ksuid::{KsuidLike, KsuidMs};
use tower_http::{
classify::ServerErrorsFailureClass,
trace::{MakeSpan, OnFailure, OnResponse},
};
use tracing::field::Empty;
use tracing::field::{debug, Empty};
use tracing_opentelemetry::OpenTelemetrySpanExt;

/// An implementor of [`MakeSpan`] which creates `tracing` spans populated with information about
Expand All @@ -26,37 +26,22 @@ impl<B> MakeSpan<B> for AxumOtelSpanCreator {
let user_agent = request
.headers()
.get(header::USER_AGENT)
.map_or("", |header| header.to_str().unwrap_or(""));
.and_then(|header| header.to_str().ok());

let host = request
.headers()
.get(header::HOST)
.map_or("", |header| header.to_str().unwrap_or(""));

let scheme = request.uri().scheme().map_or_else(
|| "HTTP".into(),
|scheme| -> Cow<'static, str> {
if scheme == &Scheme::HTTP {
"http".into()
} else if scheme == &Scheme::HTTPS {
"https".into()
} else {
scheme.to_string().into()
}
},
);
.and_then(|header| header.to_str().ok());

let http_route = if let Some(matched_path) = request.extensions().get::<MatchedPath>() {
matched_path.as_str().to_owned()
} else {
request.uri().path().to_owned()
};
let http_route = request
.extensions()
.get::<MatchedPath>()
.map(|p| p.as_str());

let client_ip: Cow<'static, str> = request
let client_ip = request
.extensions()
.get::<ConnectInfo<SocketAddr>>()
.map(|ConnectInfo(ip)| Cow::from(ip.to_string()))
.unwrap_or_default();
.map(|ConnectInfo(ip)| debug(ip));

let request_id = request
.headers()
Expand All @@ -79,29 +64,7 @@ impl<B> MakeSpan<B> for AxumOtelSpanCreator {
let span_context = remote_span.span_context();
let trace_id = span_context
.is_valid()
.then(|| Cow::from(span_context.trace_id().to_string()))
.unwrap_or_default();

let flavor: Cow<'static, str> = match request.version() {
Version::HTTP_09 => "0.9".into(),
Version::HTTP_10 => "1.0".into(),
Version::HTTP_11 => "1.1".into(),
Version::HTTP_2 => "2.0".into(),
Version::HTTP_3 => "3.0".into(),
other => format!("{other:?}").into(),
};

let method: Cow<'static, str> = match request.method() {
&Method::CONNECT => "CONNECT".into(),
&Method::DELETE => "DELETE".into(),
&Method::GET => "GET".into(),
&Method::OPTIONS => "OPTIONS".into(),
&Method::PATCH => "PATCH".into(),
&Method::POST => "POST".into(),
&Method::PUT => "PUT".into(),
&Method::TRACE => "TRACE".into(),
other => other.to_string().into(),
};
.then(|| span_context.trace_id().to_string());

let idempotency_key = request
.headers()
Expand All @@ -111,28 +74,24 @@ impl<B> MakeSpan<B> for AxumOtelSpanCreator {
let span = tracing::error_span!(
"HTTP request",
grpc.code = Empty,
http.client_ip = %client_ip,
http.flavor = %flavor,
http.host = %host,
http.method = %method,
http.route = %http_route,
http.scheme = %scheme,
http.client_ip = client_ip,
http.versions = ?request.version(),
http.host = host,
http.method = ?request.method(),
http.route = http_route,
http.scheme = request.uri().scheme().map(debug),
http.status_code = Empty,
http.target = %request.uri().path_and_query().map_or("", |p| p.as_str()),
http.user_agent = %user_agent,
http.target = request.uri().path_and_query().map(|p| p.as_str()),
http.user_agent = user_agent,
otel.kind = "server",
otel.status_code = Empty,
request_id = %request_id,
trace_id = %trace_id,
idempotency_key = tracing::field::Empty,
request_id,
trace_id,
idempotency_key,
org_id = tracing::field::Empty,
app_id = tracing::field::Empty,
);

if let Some(key) = idempotency_key {
span.record("idempotency_key", key);
}

span.set_parent(remote_context);

span
Expand Down

0 comments on commit 6464f5a

Please sign in to comment.