metrics: add backup_exported_diff_size_bytes#301
Conversation
fb5f189 to
684c85a
Compare
There was a problem hiding this comment.
Pull request overview
Adds a new Prometheus gauge to report the total size (bytes) of uploaded diff parts for a MantleBackup, and wires it into the controller lifecycle so it is set during upload progress and removed on finalization.
Changes:
- Introduces
mantle_backup_exported_diff_size_bytes(BackupExportedDiffSizeBytes) and registers it with the controller-runtime metrics registry. - Computes and sets the gauge by summing object sizes of uploaded parts via a new
objectstorage.Bucket.GetSize()method (S3HeadObject), and deletes the labeled series on backup finalization. - Extends unit/e2e test coverage to assert the metric is exposed, set, and deleted as expected.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| test/e2e/multik8s/misc_test.go | Adds an e2e assertion that the new metric name is exposed on /metrics. |
| internal/controller/metrics/metrics.go | Defines and registers the new backup_exported_diff_size_bytes gauge vec. |
| internal/controller/mantlebackup_controller.go | Sets the gauge by querying object sizes; deletes the series on finalize; refactors completed-job listing helper. |
| internal/controller/mantlebackup_controller_test.go | Adds helpers/tests to verify the gauge value and that the series is deleted; stubs object storage GetSize. |
| internal/controller/internal/objectstorage/s3.go | Implements GetSize via HeadObject and returns ContentLength. |
| internal/controller/internal/objectstorage/objectstorage.go | Extends Bucket interface with GetSize. |
| internal/controller/internal/objectstorage/objectstorage_mock.go | Updates gomock to include the new GetSize method. |
Files not reviewed (1)
- internal/controller/internal/objectstorage/objectstorage_mock.go: Generated file
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
82e2350 to
c3c2f76
Compare
| prometheus.GaugeOpts{ | ||
| Namespace: namespace, | ||
| Name: "backup_exported_diff_size_bytes", | ||
| Help: "Total bytes of the uploaded diff parts.", |
There was a problem hiding this comment.
| Help: "Total bytes of the uploaded diff parts.", | |
| Help: "The size of the uploaded backup diff data", |
Please clarify this metrics is about one backup data. I consider total is ambiguous in tihs case.
| } | ||
|
|
||
| var totalSize int64 | ||
| for partNum := 0; partNum <= largestCompletedUploadPartNum; partNum++ { |
There was a problem hiding this comment.
I worry about the count of HEAD requests on big PVCs. For instance, let assume the PVC size is 10TiB and the part size is 128GiB. Then the number of part is 80. In this case, the total number of HEAD request will be 80*(1+80)/2. Can we cache the last value in memory? The new code would be like this:
if cache[uid]
size = cache[uid] + r.objectStorageClient.GetSize(cxt, uid)
else
size = <get the total size of all diff parts>
f039f80 to
427a6b6
Compare
satoru-takeuchi
left a comment
There was a problem hiding this comment.
LGTM. Please resolve conflicts and squash commits.
427a6b6 to
d9183b6
Compare
Add a backup_exported_diff_size_bytes Gauge, labeled by persistentvolumeclaim, resource_namespace, and mantlebackup, so there is one series per MantleBackup. A Gauge is used rather than a Counter because it lets us restore the correct value with a single Set() after the controller restarts. Add GetSize to the Bucket interface (the S3 implementation returns the ContentLength of a HeadObject response) and use it in a new setExportedDiffSizeMetric, which sums the sizes of the diff parts uploaded so far and Set()s the gauge to that total. It is called from startUpload (the normal update path) and from the beginning of reconcileAsPrimary (to restore the value after a controller restart, since the replicate path may return early before reaching startUpload). Failures while collecting this metric are only logged, not returned, because it is only for observability: a transient object storage error must not block backup verification, replication, cleanup, or the creation of new upload jobs. The metric series is deleted when the MantleBackup is deleted (in finalizeStandalone), rather than right after the backup completes, since the latter risks the metric disappearing before Prometheus scrapes it. Summing from scratch on every reconcile means the number of HeadObject calls over a backup's lifetime grows quadratically with its number of parts. setExportedDiffSizeMetric now caches, per backup UID, the largest part number already summed and the resulting total, so each call only has to HeadObject the parts completed since the last call. The cache entry is dropped when the MantleBackup is deleted, alongside the metric. Also extract the shared "list the Jobs of a component, keep only the completed ones, and find the largest part number" logic (previously duplicated between getLargestCompletedUploadPartNum and handleCompletedJobsOfComponent) into listCompletedJobsOfComponent, and add an e2e check that backup_exported_diff_size_bytes is exposed. Signed-off-by: Kohya Shiozaki <kouyan120706@gmail.com>
d9183b6 to
865065b
Compare
|
Resolved the conflicts against main and squashed everything into a single commit. Here's the diff scoped to this PR from when you reviewed it to now. You can confirm from this link that there's no actual diff. Thanks for the review. |
This PR adds a metric named
mantle_backup_exported_diff_size_bytes. It is aGauge that represents, for a given MantleBackup, the total size in bytes of the
diff parts uploaded to object storage so far. It is exported as soon as the diff
size is known, without waiting for the backup to complete.
So that the value can still be tracked until the backup completes even if the
controller restarts, it is restored from the part sizes in object storage on the
reconcile after a restart. We use a Gauge rather than a Counter because this
restoration can be done with a single Set(). The metric is deleted when the
corresponding MantleBackup is deleted.
The commits are split for ease of review; they will be squashed into one when merged. See the individual commit messages for details.