From 319a119675fe1324b962f58b9070ea6ec15f6d1e Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Tue, 2 Jun 2026 15:27:45 +0200 Subject: [PATCH 1/4] feat(service): Add metrics for multipart upload operations in tiered storage --- objectstore-service/src/backend/tiered.rs | 72 ++++++++++++++++++++--- 1 file changed, 64 insertions(+), 8 deletions(-) diff --git a/objectstore-service/src/backend/tiered.rs b/objectstore-service/src/backend/tiered.rs index 1385e01d..02df0a6b 100644 --- a/objectstore-service/src/backend/tiered.rs +++ b/objectstore-service/src/backend/tiered.rs @@ -604,17 +604,23 @@ impl MultipartUploadBackend for TieredStorage { id: &ObjectId, metadata: &Metadata, ) -> Result { + let start = Instant::now(); let physical = new_long_term_revision(id); - let id = self + let upload_id = self .inner .long_term .initiate_multipart(&physical, metadata) .await?; + objectstore_metrics::record!( + "multipart.initiate.latency" = start.elapsed(), + usecase = id.usecase().to_owned(), + ); + let id = TieredUploadId { revision: physical.key, - upload_id: id, + upload_id, }; id.try_into() } @@ -628,6 +634,7 @@ impl MultipartUploadBackend for TieredStorage { content_md5: Option<&str>, body: ClientStream, ) -> Result { + let start = Instant::now(); let tiered: TieredUploadId = upload_id.try_into()?; let physical = ObjectId { @@ -635,7 +642,8 @@ impl MultipartUploadBackend for TieredStorage { key: tiered.revision, }; - self.inner + let result = self + .inner .long_term .upload_part( &physical, @@ -645,7 +653,18 @@ impl MultipartUploadBackend for TieredStorage { content_md5, body, ) - .await + .await; + + objectstore_metrics::record!( + "multipart.upload_part.latency" = start.elapsed(), + usecase = id.usecase().to_owned(), + ); + objectstore_metrics::record!( + "multipart.upload_part.size" = content_length, + usecase = id.usecase().to_owned(), + ); + + result } async fn list_parts( @@ -655,6 +674,7 @@ impl MultipartUploadBackend for TieredStorage { max_parts: Option, part_number_marker: Option, ) -> Result { + let start = Instant::now(); let tiered: TieredUploadId = upload_id.try_into()?; let physical = ObjectId { @@ -662,10 +682,18 @@ impl MultipartUploadBackend for TieredStorage { key: tiered.revision, }; - self.inner + let result = self + .inner .long_term .list_parts(&physical, &tiered.upload_id, max_parts, part_number_marker) - .await + .await; + + objectstore_metrics::record!( + "multipart.list_parts.latency" = start.elapsed(), + usecase = id.usecase().to_owned(), + ); + + result } async fn abort_multipart( @@ -673,6 +701,7 @@ impl MultipartUploadBackend for TieredStorage { id: &ObjectId, upload_id: &UploadId, ) -> Result { + let start = Instant::now(); let tiered: TieredUploadId = upload_id.try_into()?; let physical = ObjectId { @@ -680,10 +709,18 @@ impl MultipartUploadBackend for TieredStorage { key: tiered.revision, }; - self.inner + let result = self + .inner .long_term .abort_multipart(&physical, &tiered.upload_id) - .await + .await; + + objectstore_metrics::record!( + "multipart.abort.latency" = start.elapsed(), + usecase = id.usecase().to_owned(), + ); + + result } async fn complete_multipart( @@ -692,6 +729,8 @@ impl MultipartUploadBackend for TieredStorage { upload_id: &UploadId, parts: Vec, ) -> Result { + let start = Instant::now(); + let part_count = parts.len(); let tiered: TieredUploadId = upload_id.try_into()?; let physical = ObjectId { @@ -790,6 +829,23 @@ impl MultipartUploadBackend for TieredStorage { // Update guard and let it schedule cleanup in the background. guard.advance(ChangePhase::compare_and_write(written)); + objectstore_metrics::record!( + "multipart.complete.latency" = start.elapsed(), + usecase = id.usecase().to_owned(), + ); + objectstore_metrics::record!( + "multipart.complete.part_count" = part_count as u64, + usecase = id.usecase().to_owned(), + ); + if let Some(size) = metadata.size { + objectstore_metrics::record!( + "put.size" = size as u64, + usecase = id.usecase().to_owned(), + backend_choice = BackendChoice::LongTerm.as_str(), + backend_type = self.backend_type(&BackendChoice::LongTerm), + ); + } + Ok(None) } } From f78dfcd5defe6650b2174c9e8be5c94e512ca30e Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Tue, 2 Jun 2026 15:40:26 +0200 Subject: [PATCH 2/4] improve --- objectstore-service/src/backend/tiered.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/objectstore-service/src/backend/tiered.rs b/objectstore-service/src/backend/tiered.rs index 02df0a6b..7676173f 100644 --- a/objectstore-service/src/backend/tiered.rs +++ b/objectstore-service/src/backend/tiered.rs @@ -843,6 +843,7 @@ impl MultipartUploadBackend for TieredStorage { usecase = id.usecase().to_owned(), backend_choice = BackendChoice::LongTerm.as_str(), backend_type = self.backend_type(&BackendChoice::LongTerm), + upload_type = "multipart", ); } From 737c7456757ab462f6be7ef63fc0b989f2e61c15 Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Tue, 2 Jun 2026 15:42:16 +0200 Subject: [PATCH 3/4] improve --- objectstore-service/src/backend/tiered.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/objectstore-service/src/backend/tiered.rs b/objectstore-service/src/backend/tiered.rs index 7676173f..a78f22a6 100644 --- a/objectstore-service/src/backend/tiered.rs +++ b/objectstore-service/src/backend/tiered.rs @@ -410,6 +410,7 @@ impl Backend for TieredStorage { usecase = id.usecase().to_owned(), backend_choice = backend_choice.as_str(), backend_type = backend_ty, + upload_type = "direct", ); Ok(()) From f35271961e1e20a74ff79b48e27d9dadd11bd1ee Mon Sep 17 00:00:00 2001 From: lcian <17258265+lcian@users.noreply.github.com> Date: Fri, 5 Jun 2026 15:41:33 +0200 Subject: [PATCH 4/4] fix --- objectstore-service/src/backend/tiered.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/objectstore-service/src/backend/tiered.rs b/objectstore-service/src/backend/tiered.rs index a78f22a6..74a82e34 100644 --- a/objectstore-service/src/backend/tiered.rs +++ b/objectstore-service/src/backend/tiered.rs @@ -643,7 +643,7 @@ impl MultipartUploadBackend for TieredStorage { key: tiered.revision, }; - let result = self + let etag = self .inner .long_term .upload_part( @@ -654,7 +654,7 @@ impl MultipartUploadBackend for TieredStorage { content_md5, body, ) - .await; + .await?; objectstore_metrics::record!( "multipart.upload_part.latency" = start.elapsed(), @@ -665,7 +665,7 @@ impl MultipartUploadBackend for TieredStorage { usecase = id.usecase().to_owned(), ); - result + Ok(etag) } async fn list_parts(