aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/mozart-registry/src
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-02-23 23:52:13 +0900
committernsfisis <nsfisis@gmail.com>2026-02-23 23:52:13 +0900
commit2622fa3089d1df249276083d157e43b080a59100 (patch)
tree43bc31546fd3c81e13e5385cbf5cac493e045691 /crates/mozart-registry/src
parentd6e0c6d34449224ac3687daf551a0acfd15cee32 (diff)
downloadphp-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>
Diffstat (limited to 'crates/mozart-registry/src')
-rw-r--r--crates/mozart-registry/src/downloader.rs6
-rw-r--r--crates/mozart-registry/src/packagist.rs12
2 files changed, 18 insertions, 0 deletions
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!(