Skip to content

fix(storage): track storage metrics in S3/Azure backends + export read counters to Prometheus - #497

Merged
xe-nvdk merged 4 commits into
mainfrom
fix/s3-azure-storage-metrics
Jun 11, 2026
Merged

xe-nvdk merged 4 commits into
mainfrom
fix/s3-azure-storage-metrics

Conversation

@xe-nvdk

@xe-nvdk xe-nvdk commented Jun 11, 2026

Copy link
Copy Markdown
Member

Closes #349.

Summary

  • The local filesystem backend records storage counters via metrics.Get(), but the S3/MinIO and Azure Blob backends recorded nothing — on cloud-storage deployments arc_storage_* counters sat at zero. Both backends now mirror the local backend's instrumentation exactly: writes (WriteReader, S3 multipart), reads (Read, ReadTo, ReadToAt), byte counters, and IncStorageErrors on failure paths.
  • Unknown-size streaming uploads (S3 multipart with size <= 0, Azure UploadStream) count the write but skip the byte counter; the caveat is documented at both sites.
  • No double counting: Write delegates to WriteReader in both backends, and no caller-level instrumentation exists (verified repo-wide).
  • Related export gap fixed: arc_storage_reads_total and arc_storage_read_bytes_total were tracked (and present in the JSON metrics snapshot) but missing from the Prometheus text export — read metrics were invisible to Prometheus even for local storage. Added the two stanzas plus TestPrometheusFormat_StorageMetrics, locking all five arc_storage_* counters into the export format.
  • Release notes entry added to RELEASE_NOTES_2026.06.2.md.

Test plan

  • go build ./cmd/... ./internal/...
  • go vet and gofmt -l clean on touched files
  • go test ./internal/storage/ ./internal/metrics/ -count=1 passes
  • New TestPrometheusFormat_StorageMetrics asserts all five counter stanzas in the Prometheus output
  • Internal config-matrix + deep review completed (no Blocker/High findings; both Medium findings addressed: export regression test + declared-size caveat comments)

🤖 Generated with Claude Code

…d counters to Prometheus (#349)

The local filesystem backend records storage read/write/error counters,
but the S3/MinIO and Azure Blob backends recorded nothing — on
cloud-storage deployments the counters sat at zero. Both backends now
record the same counters on the same operations the local backend
instruments (writes including multipart, reads, streaming reads, ranged
reads, plus errors on failure paths). Unknown-size streaming uploads
count the write but skip the byte counter.

Also fixes a related export gap found while documenting the change:
arc_storage_reads_total and arc_storage_read_bytes_total were tracked
(and present in the JSON snapshot) but missing from the Prometheus text
export. Adds the two stanzas and a regression test locking all five
arc_storage_* counters into the export format.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds storage metrics tracking (reads, writes, bytes, and errors) to the S3 and Azure storage backends, and exposes these metrics in the Prometheus format. The reviewer suggests ensuring that partially read bytes are still recorded in the metrics even if an io.Copy operation fails halfway through, so that network egress is accurately tracked.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread internal/storage/azure.go Outdated
Comment thread internal/storage/azure.go Outdated
Comment thread internal/storage/s3.go Outdated
Comment thread internal/storage/s3.go Outdated

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements storage metrics tracking for S3 and Azure backends, exposing counters for reads, writes, bytes, and errors, and exporting them in Prometheus format. A regression test was also added to verify these metrics. The review feedback suggests guarding the error metric increments in both S3 and Azure backends with a check for active contexts to prevent false-positive error alerts caused by client-side cancellations or timeouts.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread internal/storage/s3.go Outdated
Comment thread internal/storage/azure.go Outdated
…tion-aware error counter

Round 1: count bytes delivered to the writer in ReadTo/ReadToAt even
when io.Copy fails mid-stream — partial transfers are real network
egress. Applied to the four flagged S3/Azure sites and to the local
backend's two io.Copy sites for cross-backend parity; the operation
counter still counts only completed reads.

Round 2: storage operations that fail because the caller cancelled or
timed out its context no longer increment the error counter — those
are caller-side lifecycle events (client disconnect, shutdown), not
storage failures. Implemented as recordStorageError(err) using
errors.Is on the returned error (matching the query/puller/reconciler
treatment of context.Canceled) rather than a racy ctx.Err() check,
applied at every error site in the S3 and Azure backends. Local file
ops don't fail on cancellation, so local is unchanged.
@xe-nvdk

xe-nvdk commented Jun 11, 2026

Copy link
Copy Markdown
Member Author

@gemini-code-assist Both rounds of findings are addressed in the latest commit — partial-read bytes are now counted on mid-stream copy failures (extended to the local backend for parity), and the storage-error counter is now cancellation-aware via recordStorageError(err) using errors.Is on the returned error (matching the existing context.Canceled treatment in the query/puller paths) rather than a ctx.Err() check. Please take another look.

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces storage metrics tracking (reads, writes, bytes, and errors) for S3 and Azure storage backends, bringing them to parity with the local filesystem backend, and exports these metrics to Prometheus. The reviewer feedback recommends enhancing the error-tracking mechanism by passing context.Context to recordStorageError and checking ctx.Err() != nil to prevent false-positive storage error increments during client disconnects or context cancellations. This robust error-handling pattern should also be adopted in the local storage backend and across all cloud backend error-recording paths.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread internal/storage/util.go Outdated
Comment thread internal/storage/local.go
Comment thread internal/storage/azure.go Outdated
Comment thread internal/storage/s3.go Outdated
…n guard (Gemini round 3)

A disconnecting client kills a streaming io.Copy with EPIPE/connection
reset — a plain network error that does not wrap context.Canceled — so
the errors.Is-only check missed exactly the case the guard exists for.
recordStorageError now also checks ctx.Err(), and is applied at the
local backend's two streaming-read copy sites, whose destination
writer can be a network connection (HTTP response stream).
@xe-nvdk

xe-nvdk commented Jun 11, 2026 •

Copy link
Copy Markdown
Member Author

@gemini-code-assist Round-3 findings addressed: recordStorageError now takes ctx and checks ctx.Err() in addition to errors.Is, catching client-disconnect failures that surface as plain EPIPE/connection-reset without wrapping the context error. Applied at all cloud-backend error sites and at the local backend's two streaming-copy sites. Please take another look.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements storage metrics tracking for S3 and Azure Blob backends, exports storage read and byte counters to Prometheus, and adds a utility to filter out client-side cancellations and timeouts from storage error metrics. Feedback on the changes suggests improving the Read methods in both S3 and Azure backends to record partially read bytes when io.ReadAll fails mid-stream, ensuring consistency with the ReadTo and ReadToAt implementations.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread internal/storage/azure.go Outdated
Comment thread internal/storage/s3.go Outdated
…i round 4)

io.ReadAll (and os.ReadFile) return the data read so far alongside an
error — count those bytes in the read-byte counter on mid-read
failure, consistent with the partial-transfer accounting ReadTo and
ReadToAt already do. Applied to S3 and Azure Read and to local Read
for cross-backend parity; the operation counter still counts only
completed reads.
@xe-nvdk

xe-nvdk commented Jun 11, 2026

Copy link
Copy Markdown
Member Author

@gemini-code-assist Round-4 findings addressed: the buffered Read methods now count partially-transferred bytes on io.ReadAll failure, consistent with ReadTo/ReadToAt — applied to S3, Azure, and the local backend (os.ReadFile has the same partial-data-on-error contract). Please take another look.

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements storage metrics tracking for S3 and Azure Blob storage backends, aligning them with the local filesystem backend. It adds metrics for writes, reads, bytes transferred, and errors, and exports arc_storage_reads_total and arc_storage_read_bytes_total to the Prometheus endpoint. Additionally, a helper function recordStorageError is introduced to avoid incrementing error counters on client-side context cancellations or timeouts. There are no review comments, and we have no further feedback to provide.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@xe-nvdk
xe-nvdk merged commit 42eddfb into main Jun 11, 2026
5 checks passed
@xe-nvdk
xe-nvdk deleted the fix/s3-azure-storage-metrics branch June 11, 2026 15:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

low(storage): S3/Azure backends dont track storage metrics

1 participant