diff --git a/Cargo.toml b/Cargo.toml index dbc77491..78a6781f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,6 +36,7 @@ futures-util = { version = "0.3.15", optional = true } secrecy = "0.8.0" cfg-if = "1.0.0" either = "1.8.0" +tracing = { version = "0.1", optional = true } [dev-dependencies] tokio = { version = "1.17.0", default-features = false, features = [ @@ -46,8 +47,9 @@ tokio = { version = "1.17.0", default-features = false, features = [ wiremock = "0.5.3" [features] -default = ["native-tls"] +default = ["native-tls", "trace"] rustls = ["rustls-tls"] # Leagcy support (<=0.17.0) +trace = ["tracing"] # Enables native-tls specific functionality not available by default. native-tls = ["reqwest/native-tls"] diff --git a/src/lib.rs b/src/lib.rs index 1803a353..f45cea68 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -179,6 +179,11 @@ pub use self::{ page::Page, }; +#[cfg(feature = "trace")] +use tracing::{self, field, Instrument}; + +const GITHUB_SERVICE: &str = "github.com"; + /// A convenience type with a default error type of [`Error`]. pub type Result = std::result::Result; @@ -920,10 +925,40 @@ impl Octocrab { } }; - let result = request.send().await; + #[cfg(feature = "trace")] + let span = tracing::info_span!( + "github api call", + attempt=retries, + url=field::Empty, + service_name.name=field::Empty, + status=field::Empty, + error=field::Empty, + ); + let result = if cfg!(feature = "trace") { + let service = self.base_url.host_str().unwrap_or(GITHUB_SERVICE); + span.record("service.name", service); + span.in_scope(|| { + request.send() + }).await + } else { + request.send().await + }; + let status = match &result { - Ok(v) => Some(v.status()), - Err(e) => e.status(), + Ok(v) => { + if cfg!(feature = "trace") { + span.record("status", v.status().as_u16()); + } + Some(v.status()) + }, + Err(e) => { + if cfg!(feature = "trace") { + let status = e.status().and_then(|s| Some(s.as_u16())); + span.record("status", status); + span.record("error", format!("{e:?}")); + } + e.status() + }, }; if let Some(StatusCode::UNAUTHORIZED) = status { if let AuthState::Installation { ref token, .. } = self.auth_state {