From 2c7d0fb2cebc0221131ce33d25bc05b101709de8 Mon Sep 17 00:00:00 2001 From: houseme Date: Sun, 9 Aug 2026 16:36:58 +0800 Subject: [PATCH] feat: add hotpath observability for S3 data paths (#5860) --- .github/actions/setup/action.yml | 4 ++-- Cargo.lock | 22 +++++++++++----------- crates/ecstore/src/object_api/readers.rs | 1 + rustfs/src/app/multipart_usecase.rs | 4 ++++ rustfs/src/app/object_usecase.rs | 3 +++ 5 files changed, 21 insertions(+), 13 deletions(-) diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index 9359bb066..c097547c7 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -57,7 +57,7 @@ runs: using: "composite" steps: # protobuf-compiler is deliberately absent: the setup-protoc step below - # installs 34.1 into the tool cache and prepends it to PATH, so the apt + # installs 35.1 into the tool cache and prepends it to PATH, so the apt # build (older, and never version-matched) was shadowed on every run and # simply never used. - name: Install system dependencies (Ubuntu) @@ -81,7 +81,7 @@ runs: - name: Install protoc uses: rustfs/setup-protoc@a3705324d8f9bf5b6c3573fb6cf8ae421db55dd6 # v3.0.1 with: - version: "34.1" + version: "35.1" repo-token: ${{ github.token }} - name: Install flatc diff --git a/Cargo.lock b/Cargo.lock index 308693515..d3f53f07e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4022,7 +4022,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -5468,7 +5468,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -7963,7 +7963,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf" dependencies = [ "heck", - "itertools 0.10.5", + "itertools 0.14.0", "log", "multimap", "once_cell", @@ -7983,7 +7983,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03da047801ff44bb6a4d407d4860c05fd70bb81714e6b2f3812603d5b145b042" dependencies = [ "heck", - "itertools 0.10.5", + "itertools 0.14.0", "log", "multimap", "petgraph 0.8.3", @@ -8004,7 +8004,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" dependencies = [ "anyhow", - "itertools 0.10.5", + "itertools 0.14.0", "proc-macro2", "quote", "syn 2.0.119", @@ -8017,7 +8017,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b570b25f7617e43d59005d0990ccb79e950a423952cea19671b7a876da390adf" dependencies = [ "anyhow", - "itertools 0.10.5", + "itertools 0.14.0", "proc-macro2", "quote", "syn 2.0.119", @@ -8234,7 +8234,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -10459,7 +10459,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -10532,7 +10532,7 @@ dependencies = [ "security-framework", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -11741,7 +11741,7 @@ dependencies = [ "getrandom 0.4.3", "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -12843,7 +12843,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] diff --git a/crates/ecstore/src/object_api/readers.rs b/crates/ecstore/src/object_api/readers.rs index ff82e2a4b..35aefe053 100644 --- a/crates/ecstore/src/object_api/readers.rs +++ b/crates/ecstore/src/object_api/readers.rs @@ -894,6 +894,7 @@ impl GetObjectReader { .await? .into_reader(reader, oi) } + #[hotpath::measure(impl_type = "GetObjectReader")] pub async fn read_all(&mut self) -> Result> { let mut data = Vec::new(); self.stream.read_to_end(&mut data).await?; diff --git a/rustfs/src/app/multipart_usecase.rs b/rustfs/src/app/multipart_usecase.rs index 9a73f2189..1aeb732e3 100644 --- a/rustfs/src/app/multipart_usecase.rs +++ b/rustfs/src/app/multipart_usecase.rs @@ -382,6 +382,7 @@ impl DefaultMultipartUsecase { } #[instrument(level = "debug", skip(self, req))] + #[hotpath::measure(impl_type = "MultipartUsecase")] pub async fn execute_complete_multipart_upload( &self, req: S3Request, @@ -664,6 +665,7 @@ impl DefaultMultipartUsecase { } #[instrument(level = "debug", skip(self, req))] + #[hotpath::measure(impl_type = "MultipartUsecase")] pub async fn execute_create_multipart_upload( &self, req: S3Request, @@ -845,6 +847,7 @@ impl DefaultMultipartUsecase { } #[instrument(level = "debug", skip(self, req))] + #[hotpath::measure(impl_type = "MultipartUsecase")] pub async fn execute_upload_part(&self, req: S3Request) -> S3Result> { let mut opts = ObjectOptions::default(); apply_bucket_generation_guard(&req, &req.input.bucket, &mut opts)?; @@ -1180,6 +1183,7 @@ impl DefaultMultipartUsecase { } #[instrument(level = "debug", skip(self, req))] + #[hotpath::measure(impl_type = "MultipartUsecase")] pub async fn execute_upload_part_copy( &self, req: S3Request, diff --git a/rustfs/src/app/object_usecase.rs b/rustfs/src/app/object_usecase.rs index f53b55433..4798a22df 100644 --- a/rustfs/src/app/object_usecase.rs +++ b/rustfs/src/app/object_usecase.rs @@ -5319,6 +5319,7 @@ impl DefaultObjectUsecase { } #[instrument(level = "info", skip(self, _fs, req))] + #[hotpath::measure(impl_type = "DefaultObjectUsecase")] pub async fn execute_put_object(&self, _fs: &FS, req: S3Request) -> S3Result> { let start_time = std::time::Instant::now(); let mut req = req; @@ -6258,6 +6259,7 @@ impl DefaultObjectUsecase { skip(self, req), fields(start_time=?time::OffsetDateTime::now_utc()) )] + #[hotpath::measure(impl_type = "DefaultObjectUsecase")] pub async fn execute_get_object(&self, req: S3Request) -> S3Result> { if let Some(context) = &self.context { let _ = context.object_store(); @@ -8790,6 +8792,7 @@ impl DefaultObjectUsecase { } #[instrument(level = "debug", skip(self, req))] + #[hotpath::measure(impl_type = "DefaultObjectUsecase")] pub async fn execute_put_object_extract(&self, req: S3Request) -> S3Result> { let helper = OperationHelper::new(&req, EventName::ObjectCreatedPut, S3Operation::PutObject).suppress_event(); let request_context = helper.request_context_or_from_request(&req);