diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-02-23 23:52:13 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-02-23 23:52:13 +0900 |
| commit | 2622fa3089d1df249276083d157e43b080a59100 (patch) | |
| tree | 43bc31546fd3c81e13e5385cbf5cac493e045691 | |
| parent | d6e0c6d34449224ac3687daf551a0acfd15cee32 (diff) | |
| download | php-mozart-2622fa3089d1df249276083d157e43b080a59100.tar.gz php-mozart-2622fa3089d1df249276083d157e43b080a59100.tar.zst php-mozart-2622fa3089d1df249276083d157e43b080a59100.zip | |
feat(tracing): instrument network requests with tracing spans
Add #[tracing::instrument] and debug logs to all HTTP-calling
functions in mozart-registry and mozart-vcs for request-level
observability (URL, status code, cache hits, download size).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
| -rw-r--r-- | Cargo.lock | 2 | ||||
| -rw-r--r-- | crates/mozart-registry/Cargo.toml | 1 | ||||
| -rw-r--r-- | crates/mozart-registry/src/downloader.rs | 6 | ||||
| -rw-r--r-- | crates/mozart-registry/src/packagist.rs | 12 | ||||
| -rw-r--r-- | crates/mozart-vcs/Cargo.toml | 1 | ||||
| -rw-r--r-- | crates/mozart-vcs/src/driver/bitbucket.rs | 4 | ||||
| -rw-r--r-- | crates/mozart-vcs/src/driver/forgejo.rs | 3 | ||||
| -rw-r--r-- | crates/mozart-vcs/src/driver/github.rs | 4 | ||||
| -rw-r--r-- | crates/mozart-vcs/src/driver/gitlab.rs | 3 |
9 files changed, 36 insertions, 0 deletions
@@ -1184,6 +1184,7 @@ dependencies = [ "tar", "tempfile", "tokio", + "tracing", "zip", ] @@ -1222,6 +1223,7 @@ dependencies = [ "sha1", "tempfile", "tokio", + "tracing", "url", ] diff --git a/crates/mozart-registry/Cargo.toml b/crates/mozart-registry/Cargo.toml index 87d3c69..af65026 100644 --- a/crates/mozart-registry/Cargo.toml +++ b/crates/mozart-registry/Cargo.toml @@ -20,4 +20,5 @@ sha1.workspace = true tar.workspace = true tempfile.workspace = true tokio.workspace = true +tracing.workspace = true zip.workspace = true diff --git a/crates/mozart-registry/src/downloader.rs b/crates/mozart-registry/src/downloader.rs index 8bd99c7..6660188 100644 --- a/crates/mozart-registry/src/downloader.rs +++ b/crates/mozart-registry/src/downloader.rs @@ -79,6 +79,7 @@ impl DownloadProgress { /// the `Content-Length` response header. /// If `files_cache` is provided, the downloaded bytes are cached by URL; cache hits skip /// the network request entirely. +#[tracing::instrument(skip(expected_shasum, progress, files_cache))] pub async fn download_dist( url: &str, expected_shasum: Option<&str>, @@ -100,10 +101,12 @@ pub async fn download_dist( hasher.update(&cached_bytes); let computed = format!("{:x}", hasher.finalize()); if computed == shasum { + tracing::debug!("cache hit"); return Ok(cached_bytes); } // Checksum mismatch — discard cache, re-download } else { + tracing::debug!("cache hit"); return Ok(cached_bytes); } } @@ -112,6 +115,7 @@ pub async fn download_dist( .user_agent(mozart_core::http::user_agent()) .build()?; let response = client.get(url).send().await?; + tracing::debug!(status = %response.status(), "received response"); if !response.status().is_success() { anyhow::bail!( @@ -137,6 +141,8 @@ pub async fn download_dist( response.bytes().await?.to_vec() }; + tracing::debug!(size = bytes.len(), "download complete"); + // Verify SHA-1 checksum if provided if let Some(shasum) = expected_shasum && !shasum.is_empty() diff --git a/crates/mozart-registry/src/packagist.rs b/crates/mozart-registry/src/packagist.rs index 9ff608c..8a5f205 100644 --- a/crates/mozart-registry/src/packagist.rs +++ b/crates/mozart-registry/src/packagist.rs @@ -215,6 +215,7 @@ pub fn parse_p2_response(json: &str, package_name: &str) -> anyhow::Result<Vec<P /// If `repo_cache` is provided, the JSON response is cached on disk under the /// key `"provider-{vendor}~{package}.json"`. Subsequent calls for the same /// package are served from cache without a network request. +#[tracing::instrument(skip(repo_cache))] pub async fn fetch_package_versions( package_name: &str, repo_cache: Option<&Cache>, @@ -226,15 +227,18 @@ pub async fn fetch_package_versions( if let Some(cache) = repo_cache && let Some(cached) = cache.read(&cache_key) { + tracing::debug!("cache hit"); return parse_p2_response(&cached, package_name); } // Cache miss — fetch from Packagist let url = format!("https://repo.packagist.org/p2/{package_name}.json"); + tracing::debug!(%url, "fetching package metadata"); let client = reqwest::Client::builder() .user_agent(mozart_core::http::user_agent()) .build()?; let response = client.get(&url).send().await?; + tracing::debug!(status = %response.status(), "received response"); if !response.status().is_success() { anyhow::bail!( @@ -303,6 +307,7 @@ fn url_encode(s: &str) -> String { /// /// Fetches up to `SEARCH_MAX_PAGES` pages of results and returns the full list. /// An optional `package_type` filter can narrow results (e.g. `"library"`). +#[tracing::instrument(fields(type_filter = package_type))] pub async fn search_packages( query: &str, package_type: Option<&str>, @@ -318,7 +323,9 @@ pub async fn search_packages( loop { let response: SearchResponse = if let Some(ref url) = next_url { + tracing::debug!(%url, page, "fetching next page"); let resp = client.get(url).send().await?; + tracing::debug!(status = %resp.status(), "received response"); if !resp.status().is_success() { anyhow::bail!("Packagist search request failed (HTTP {})", resp.status()); } @@ -331,7 +338,9 @@ pub async fn search_packages( url.push_str(&url_encode(t)); } + tracing::debug!(%url, "fetching search results"); let resp = client.get(&url).send().await?; + tracing::debug!(status = %resp.status(), "received response"); if !resp.status().is_success() { anyhow::bail!("Packagist search request failed (HTTP {})", resp.status()); } @@ -415,6 +424,7 @@ pub struct SecurityAdvisoriesResponse { /// /// If the package list is very large (500+), requests are batched in chunks of /// 500 names per request and the results are merged. +#[tracing::instrument(skip(package_names), fields(package_count = package_names.len()))] pub async fn fetch_security_advisories( package_names: &[&str], ) -> anyhow::Result<BTreeMap<String, Vec<SecurityAdvisory>>> { @@ -433,12 +443,14 @@ pub async fn fetch_security_advisories( .collect::<Vec<_>>() .join("&"); + tracing::debug!(chunk_size = chunk.len(), "fetching security advisories"); let response = client .post("https://packagist.org/api/security-advisories/") .header("Content-Type", "application/x-www-form-urlencoded") .body(body) .send() .await?; + tracing::debug!(status = %response.status(), "received response"); if !response.status().is_success() { anyhow::bail!( diff --git a/crates/mozart-vcs/Cargo.toml b/crates/mozart-vcs/Cargo.toml index 61fd57e..dc6dfc3 100644 --- a/crates/mozart-vcs/Cargo.toml +++ b/crates/mozart-vcs/Cargo.toml @@ -14,6 +14,7 @@ serde.workspace = true serde_json.workspace = true sha1.workspace = true tokio.workspace = true +tracing.workspace = true url.workspace = true [dev-dependencies] diff --git a/crates/mozart-vcs/src/driver/bitbucket.rs b/crates/mozart-vcs/src/driver/bitbucket.rs index dc7d2cf..d47987d 100644 --- a/crates/mozart-vcs/src/driver/bitbucket.rs +++ b/crates/mozart-vcs/src/driver/bitbucket.rs @@ -62,6 +62,7 @@ impl BitbucketDriver { ) } + #[tracing::instrument(skip(self))] async fn api_get(&self, path: &str) -> Result<serde_json::Value> { let url = self.api_url(path); let mut req = self @@ -76,6 +77,7 @@ impl BitbucketDriver { } let response = req.send().await?; + tracing::debug!(status = %response.status(), %url, "Bitbucket API response"); if !response.status().is_success() { bail!( "Bitbucket API request to {} failed: {}", @@ -86,6 +88,7 @@ impl BitbucketDriver { Ok(response.json().await?) } + #[tracing::instrument(skip(self))] async fn api_get_paginated(&self, path: &str) -> Result<Vec<serde_json::Value>> { let mut items = Vec::new(); let mut next_url = Some(self.api_url(path)); @@ -101,6 +104,7 @@ impl BitbucketDriver { req = req.header(AUTHORIZATION, format!("Basic {key}:{secret}")); } let response = req.send().await?; + tracing::debug!(status = %response.status(), %url, "Bitbucket API paginated response"); if !response.status().is_success() { break; } diff --git a/crates/mozart-vcs/src/driver/forgejo.rs b/crates/mozart-vcs/src/driver/forgejo.rs index 0447422..ec2ca14 100644 --- a/crates/mozart-vcs/src/driver/forgejo.rs +++ b/crates/mozart-vcs/src/driver/forgejo.rs @@ -76,6 +76,7 @@ impl ForgejoDriver { ) } + #[tracing::instrument(skip(self))] async fn api_get(&self, path: &str) -> Result<serde_json::Value> { let url = self.api_url(path); let mut req = self @@ -87,6 +88,7 @@ impl ForgejoDriver { req = req.header(AUTHORIZATION, format!("token {token}")); } let response = req.send().await?; + tracing::debug!(status = %response.status(), %url, "Forgejo API response"); if !response.status().is_success() { bail!( "Forgejo API request to {} failed: {}", @@ -97,6 +99,7 @@ impl ForgejoDriver { Ok(response.json().await?) } + #[tracing::instrument(skip(self))] async fn api_get_paginated(&self, path: &str) -> Result<Vec<serde_json::Value>> { let mut items = Vec::new(); let mut page = 1; diff --git a/crates/mozart-vcs/src/driver/github.rs b/crates/mozart-vcs/src/driver/github.rs index 724cb35..c47c2fe 100644 --- a/crates/mozart-vcs/src/driver/github.rs +++ b/crates/mozart-vcs/src/driver/github.rs @@ -65,6 +65,7 @@ impl GitHubDriver { ) } + #[tracing::instrument(skip(self))] async fn api_get(&self, path: &str) -> Result<serde_json::Value> { let url = self.api_url(path); let mut req = self @@ -78,6 +79,7 @@ impl GitHubDriver { } let response = req.send().await?; + tracing::debug!(status = %response.status(), %url, "GitHub API response"); if !response.status().is_success() { bail!( "GitHub API request to {} failed with status {}", @@ -88,6 +90,7 @@ impl GitHubDriver { Ok(response.json().await?) } + #[tracing::instrument(skip(self))] async fn api_get_paginated(&self, path: &str) -> Result<Vec<serde_json::Value>> { let mut items = Vec::new(); let mut page = 1; @@ -107,6 +110,7 @@ impl GitHubDriver { } let response = req.send().await?; + tracing::debug!(status = %response.status(), %url, "GitHub API paginated response"); if !response.status().is_success() { bail!("GitHub API paginated request failed: {}", response.status()); } diff --git a/crates/mozart-vcs/src/driver/gitlab.rs b/crates/mozart-vcs/src/driver/gitlab.rs index 7b1a93b..f96c078 100644 --- a/crates/mozart-vcs/src/driver/gitlab.rs +++ b/crates/mozart-vcs/src/driver/gitlab.rs @@ -80,6 +80,7 @@ impl GitLabDriver { ) } + #[tracing::instrument(skip(self))] async fn api_get(&self, path: &str) -> Result<serde_json::Value> { let url = self.api_url(path); let mut req = self @@ -93,6 +94,7 @@ impl GitLabDriver { } let response = req.send().await?; + tracing::debug!(status = %response.status(), %url, "GitLab API response"); if !response.status().is_success() { bail!( "GitLab API request to {} failed with status {}", @@ -103,6 +105,7 @@ impl GitLabDriver { Ok(response.json().await?) } + #[tracing::instrument(skip(self))] async fn api_get_paginated(&self, path: &str) -> Result<Vec<serde_json::Value>> { let mut items = Vec::new(); let mut page = 1; |
