mirror of
https://github.com/TrueLayer/reqwest-middleware.git
synced 2024-12-25 18:36:30 +00:00
Match stable Semantic Conventions for HTTP Spans
The stable [Semantic Conventions for HTTP Spans](https://opentelemetry.io/docs/specs/semconv/http/http-spans/) use different keys than the ones used in this crate. This changes them to match the keys as defined by the stable specification.
This commit is contained in:
parent
94a38211f7
commit
3422e7338c
4 changed files with 62 additions and 38 deletions
|
@ -9,11 +9,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
### Breaking changes
|
||||
- Upgraded `reqwest-middleware` to `0.3.0`.
|
||||
- Removed support for `opentelemetry` 0.13 to 0.19
|
||||
- The keys emitted by the crate now match the stable Semantic Conventions for HTTP Spans.
|
||||
|
||||
### Changed
|
||||
- The keys emitted by the crate now match the stable Semantic Conventions for HTTP Spans.
|
||||
- Opentelemetry features are now additive.
|
||||
|
||||
### Deprecated
|
||||
- The old keys are now deprecated.
|
||||
|
||||
## [0.4.8] - 2024-03-11
|
||||
|
||||
### Added
|
||||
|
|
|
@ -91,12 +91,14 @@ mod middleware;
|
|||
mod otel;
|
||||
mod reqwest_otel_span_builder;
|
||||
pub use middleware::TracingMiddleware;
|
||||
#[allow(deprecated)]
|
||||
pub use reqwest_otel_span_builder::{
|
||||
default_on_request_end, default_on_request_failure, default_on_request_success,
|
||||
default_span_name, DefaultSpanBackend, DisableOtelPropagation, OtelName, OtelPathNames,
|
||||
ReqwestOtelSpanBackend, SpanBackendWithUrl, ERROR_CAUSE_CHAIN, ERROR_MESSAGE, HTTP_HOST,
|
||||
HTTP_METHOD, HTTP_SCHEME, HTTP_STATUS_CODE, HTTP_URL, HTTP_USER_AGENT, NET_HOST_PORT,
|
||||
OTEL_KIND, OTEL_NAME, OTEL_STATUS_CODE,
|
||||
HTTP_METHOD, HTTP_REQUEST_METHOD, HTTP_RESPONSE_STATUS_CODE, HTTP_SCHEME, HTTP_STATUS_CODE,
|
||||
HTTP_URL, HTTP_USER_AGENT, NET_HOST_PORT, OTEL_KIND, OTEL_NAME, OTEL_STATUS_CODE,
|
||||
SERVER_ADDRESS, SERVER_PORT, URL_FULL, URL_SCHEME, USER_AGENT_ORIGINAL,
|
||||
};
|
||||
|
||||
#[doc(hidden)]
|
||||
|
|
|
@ -2,36 +2,57 @@ use std::borrow::Cow;
|
|||
|
||||
use http::Extensions;
|
||||
use matchit::Router;
|
||||
use reqwest::header::{HeaderMap, HeaderValue};
|
||||
use reqwest::{Request, Response, StatusCode as RequestStatusCode, Url};
|
||||
use reqwest::{header::HeaderValue, Request, Response, StatusCode as RequestStatusCode, Url};
|
||||
use reqwest_middleware::{Error, Result};
|
||||
use tracing::{warn, Span};
|
||||
|
||||
use crate::reqwest_otel_span;
|
||||
|
||||
/// The `http.method` field added to the span by [`reqwest_otel_span`]
|
||||
pub const HTTP_METHOD: &str = "http.method";
|
||||
/// The `http.scheme` field added to the span by [`reqwest_otel_span`]
|
||||
pub const HTTP_SCHEME: &str = "http.scheme";
|
||||
/// The `http.host` field added to the span by [`reqwest_otel_span`]
|
||||
pub const HTTP_HOST: &str = "http.host";
|
||||
/// The `http.url` field added to the span by [`reqwest_otel_span`]
|
||||
pub const HTTP_URL: &str = "http.url";
|
||||
/// The `host.port` field added to the span by [`reqwest_otel_span`]
|
||||
pub const NET_HOST_PORT: &str = "net.host.port";
|
||||
/// The `http.request.method` field added to the span by [`reqwest_otel_span`]
|
||||
pub const HTTP_REQUEST_METHOD: &str = "http.request.method";
|
||||
/// The `url.scheme` field added to the span by [`reqwest_otel_span`]
|
||||
pub const URL_SCHEME: &str = "url.scheme";
|
||||
/// The `server.address` field added to the span by [`reqwest_otel_span`]
|
||||
pub const SERVER_ADDRESS: &str = "server.address";
|
||||
/// The `server.port` field added to the span by [`reqwest_otel_span`]
|
||||
pub const SERVER_PORT: &str = "server.port";
|
||||
/// The `url.full` field added to the span by [`reqwest_otel_span`]
|
||||
pub const URL_FULL: &str = "url.full";
|
||||
/// The `user_agent.original` field added to the span by [`reqwest_otel_span`]
|
||||
pub const USER_AGENT_ORIGINAL: &str = "user_agent.original";
|
||||
/// The `otel.kind` field added to the span by [`reqwest_otel_span`]
|
||||
pub const OTEL_KIND: &str = "otel.kind";
|
||||
/// The `otel.name` field added to the span by [`reqwest_otel_span`]
|
||||
pub const OTEL_NAME: &str = "otel.name";
|
||||
/// The `otel.status_code` field added to the span by [`reqwest_otel_span`]
|
||||
pub const OTEL_STATUS_CODE: &str = "otel.status_code";
|
||||
/// The `http.response.status_code` field added to the span by [`reqwest_otel_span`]
|
||||
pub const HTTP_RESPONSE_STATUS_CODE: &str = "http.response.status_code";
|
||||
/// The `error.message` field added to the span by [`reqwest_otel_span`]
|
||||
pub const ERROR_MESSAGE: &str = "error.message";
|
||||
/// The `error.cause_chain` field added to the span by [`reqwest_otel_span`]
|
||||
pub const ERROR_CAUSE_CHAIN: &str = "error.cause_chain";
|
||||
/// The `http.status_code` field added to the span by [`reqwest_otel_span`]
|
||||
|
||||
/// The deprecated `http.method` field added to the span by [`reqwest_otel_span`]
|
||||
#[deprecated]
|
||||
pub const HTTP_METHOD: &str = "http.method";
|
||||
/// The deprecated `http.scheme` field added to the span by [`reqwest_otel_span`]
|
||||
#[deprecated]
|
||||
pub const HTTP_SCHEME: &str = "http.scheme";
|
||||
/// The deprecated `http.host` field added to the span by [`reqwest_otel_span`]
|
||||
#[deprecated]
|
||||
pub const HTTP_HOST: &str = "http.host";
|
||||
/// The deprecated `http.url` field added to the span by [`reqwest_otel_span`]
|
||||
#[deprecated]
|
||||
pub const HTTP_URL: &str = "http.url";
|
||||
/// The deprecated `host.port` field added to the span by [`reqwest_otel_span`]
|
||||
#[deprecated]
|
||||
pub const NET_HOST_PORT: &str = "net.host.port";
|
||||
/// The deprecated `http.status_code` field added to the span by [`reqwest_otel_span`]
|
||||
#[deprecated]
|
||||
pub const HTTP_STATUS_CODE: &str = "http.status_code";
|
||||
/// The `http.user_agent` added to the span by [`reqwest_otel_span`]
|
||||
/// The deprecated `http.user_agent` added to the span by [`reqwest_otel_span`]
|
||||
#[deprecated]
|
||||
pub const HTTP_USER_AGENT: &str = "http.user_agent";
|
||||
|
||||
/// [`ReqwestOtelSpanBackend`] allows you to customise the span attached by
|
||||
|
@ -61,12 +82,10 @@ pub fn default_on_request_end(span: &Span, outcome: &Result<Response>) {
|
|||
#[inline]
|
||||
pub fn default_on_request_success(span: &Span, response: &Response) {
|
||||
let span_status = get_span_status(response.status());
|
||||
let user_agent = get_header_value("user_agent", response.headers());
|
||||
if let Some(span_status) = span_status {
|
||||
span.record(OTEL_STATUS_CODE, span_status);
|
||||
}
|
||||
span.record(HTTP_STATUS_CODE, response.status().as_u16());
|
||||
span.record(HTTP_USER_AGENT, user_agent.as_str());
|
||||
span.record(HTTP_RESPONSE_STATUS_CODE, response.status().as_u16());
|
||||
}
|
||||
|
||||
/// Populates default failure fields for a given [`reqwest_otel_span!`] span.
|
||||
|
@ -79,7 +98,7 @@ pub fn default_on_request_failure(span: &Span, e: &Error) {
|
|||
span.record(ERROR_CAUSE_CHAIN, error_cause_chain.as_str());
|
||||
if let Error::Reqwest(e) = e {
|
||||
if let Some(status) = e.status() {
|
||||
span.record(HTTP_STATUS_CODE, status.as_u16());
|
||||
span.record(HTTP_RESPONSE_STATUS_CODE, status.as_u16());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -122,11 +141,6 @@ impl ReqwestOtelSpanBackend for DefaultSpanBackend {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_header_value(key: &str, headers: &HeaderMap) -> String {
|
||||
let header_default = &HeaderValue::from_static("");
|
||||
format!("{:?}", headers.get(key).unwrap_or(header_default)).replace('"', "")
|
||||
}
|
||||
|
||||
/// Similar to [`DefaultSpanBackend`] but also adds the `http.url` attribute to request spans.
|
||||
///
|
||||
/// [`TracingMiddleware`]: crate::middleware::TracingMiddleware
|
||||
|
|
|
@ -3,15 +3,16 @@
|
|||
/// It empowers you to add custom properties to the span on top of the default properties provided by the macro
|
||||
///
|
||||
/// Default Fields:
|
||||
/// - http.method
|
||||
/// - http.scheme
|
||||
/// - http.host
|
||||
/// - net.host
|
||||
/// - http.request.method
|
||||
/// - url.scheme
|
||||
/// - server.address
|
||||
/// - server.port
|
||||
/// - url.full
|
||||
/// - otel.kind
|
||||
/// - otel.name
|
||||
/// - otel.status_code
|
||||
/// - http.user_agent
|
||||
/// - http.status_code
|
||||
/// - user_agent.original
|
||||
/// - http.response.status_code
|
||||
/// - error.message
|
||||
/// - error.cause_chain
|
||||
///
|
||||
|
@ -122,23 +123,26 @@ macro_rules! reqwest_otel_span {
|
|||
let url = $request.url();
|
||||
let scheme = url.scheme();
|
||||
let host = url.host_str().unwrap_or("");
|
||||
let host_port = url.port().unwrap_or(0) as i64;
|
||||
let host_port = url.port_or_known_default().unwrap_or(0) as i64;
|
||||
let otel_name = $name.to_string();
|
||||
let header_default = &HeaderValue::from_static("");
|
||||
let user_agent = format!("{:?}", $request.headers().get("user_agent").unwrap_or(header_default)).replace('"', "");
|
||||
|
||||
macro_rules! request_span {
|
||||
($lvl:expr) => {
|
||||
$crate::reqwest_otel_span_macro::private::span!(
|
||||
$lvl,
|
||||
"HTTP request",
|
||||
http.method = %method,
|
||||
http.scheme = %scheme,
|
||||
http.host = %host,
|
||||
net.host.port = %host_port,
|
||||
http.request.method = %method,
|
||||
url.scheme = %scheme,
|
||||
server.address = %host,
|
||||
server.port = %host_port,
|
||||
url.full = %url,
|
||||
user_agent.original = %user_agent,
|
||||
otel.kind = "client",
|
||||
otel.name = %otel_name,
|
||||
otel.status_code = tracing::field::Empty,
|
||||
http.user_agent = tracing::field::Empty,
|
||||
http.status_code = tracing::field::Empty,
|
||||
http.response.status_code = tracing::field::Empty,
|
||||
error.message = tracing::field::Empty,
|
||||
error.cause_chain = tracing::field::Empty,
|
||||
$($field)*
|
||||
|
|
Loading…
Reference in a new issue