diff --git a/seaweed-volume/src/metrics.rs b/seaweed-volume/src/metrics.rs index 572786949..5d65ea442 100644 --- a/seaweed-volume/src/metrics.rs +++ b/seaweed-volume/src/metrics.rs @@ -135,6 +135,13 @@ lazy_static::lazy_static! { "In flight total upload size.", ).expect("metric can be created"); + /// Upload error counter by HTTP status code. Code "0" = transport error (no response). + pub static ref UPLOAD_ERROR_COUNTER: IntCounterVec = IntCounterVec::new( + Opts::new("SeaweedFS_upload_error_total", + "Counter of upload errors by HTTP status code. Code 0 means transport error (no response received)."), + &["code"], + ).expect("metric can be created"); + // ---- Legacy aliases for backward compat with existing code ---- /// Total number of volumes on this server (flat gauge). @@ -243,6 +250,7 @@ pub fn register_metrics() { Box::new(CONCURRENT_UPLOAD_LIMIT.clone()), Box::new(INFLIGHT_DOWNLOAD_SIZE.clone()), Box::new(INFLIGHT_UPLOAD_SIZE.clone()), + Box::new(UPLOAD_ERROR_COUNTER.clone()), // Legacy metrics Box::new(VOLUMES_TOTAL.clone()), Box::new(DISK_SIZE_BYTES.clone()), diff --git a/seaweed-volume/src/server/handlers.rs b/seaweed-volume/src/server/handlers.rs index 83e43fb67..a7d021dad 100644 --- a/seaweed-volume/src/server/handlers.rs +++ b/seaweed-volume/src/server/handlers.rs @@ -557,8 +557,18 @@ async fn do_replicated_request( futures.push(async move { match req_builder.send().await { Ok(r) if r.status().is_success() => Ok(()), - Ok(r) => Err(format!("{} returned status {}", url, r.status())), - Err(e) => Err(format!("{} failed: {}", url, e)), + Ok(r) => { + crate::metrics::UPLOAD_ERROR_COUNTER + .with_label_values(&[&r.status().as_u16().to_string()]) + .inc(); + Err(format!("{} returned status {}", url, r.status())) + } + Err(e) => { + crate::metrics::UPLOAD_ERROR_COUNTER + .with_label_values(&["0"]) + .inc(); + Err(format!("{} failed: {}", url, e)) + } } }); }