Skip to content

[fix] Skip storage capacity/utilization gauges when capacity is None#138

Open
huniu20 wants to merge 1 commit into
Ascend:mainfrom
huniu20:fix/metrics-none-capacity
Open

[fix] Skip storage capacity/utilization gauges when capacity is None#138
huniu20 wants to merge 1 commit into
Ascend:mainfrom
huniu20:fix/metrics-none-capacity

Conversation

@huniu20

@huniu20 huniu20 commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Background

Follow-up of #130, which made total_storage_size optional so that a storage unit can be configured with unlimited capacity.

Problem

When a storage unit is created with total_storage_size=None (unlimited), SimpleStorageUnit._handle_get_metrics reports capacity=None in its /metrics payload.

The metrics exporter in transfer_queue/metrics.py defines two prometheus_client.Gauge objects that consume this value:

  • self.storage_capacity = Gauge("tq_storage_capacity_total", ...) — around L164
  • self.storage_utilization = Gauge("tq_storage_utilization_ratio", ...) — around L170

Inside TQMetricsExporter._collect_storage_metrics, both gauges are updated unconditionally:

capacity = metrics.get("capacity", 0)
active   = metrics.get("active_keys", 0)
self.storage_capacity.labels(storage_unit_id=label).set(capacity)
...
self.storage_utilization.labels(storage_unit_id=label).set(
    active / capacity if capacity > 0 else 0.0
)

When capacity is None, Gauge.set() internally does float(value), and float(None) raises TypeError. Because the whole block is wrapped in try/except, this is caught by the surrounding handler and turned into:

Failed to collect metrics from storage unit <su_id>: float() argument must be a string or a real number, not 'NoneType'

This warning is emitted every TQ_METRICS_COLLECT_INTERVAL for every unlimited-capacity storage unit, flooding the logs and hiding real issues.

Fix

In TQMetricsExporter._collect_storage_metrics, treat capacity is None as "unlimited" and skip only the storage_capacity and storage_utilization gauges for that storage unit. All other metrics (storage_active_keys, storage_memory_rss, per-op request stats such as count / latency avg / p50 / p99) are still reported normally, so dashboards for unlimited-capacity units keep working — they simply no longer publish a (meaningless) capacity/utilization value.

Related

@ascend-robot

Copy link
Copy Markdown

CLA Signature Pass

huniu20, thanks for your pull request. All authors of the commits have signed the CLA. 👍

@huniu20 huniu20 force-pushed the fix/metrics-none-capacity branch from 65daf9d to e0386b0 Compare July 10, 2026 09:41
@ascend-robot

Copy link
Copy Markdown

CLA Signature Pass

huniu20, thanks for your pull request. All authors of the commits have signed the CLA. 👍

Copilot AI 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.

Pull request overview

This PR fixes Prometheus metrics collection for “unlimited capacity” storage units by avoiding publishing capacity/utilization gauge values when the storage unit reports capacity=None, preventing periodic float(None) errors and log flooding.

Changes:

  • Skip setting tq_storage_capacity_total when capacity is None.
  • Skip setting tq_storage_utilization_ratio when capacity is None (while continuing to export other storage metrics).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread transfer_queue/metrics.py
Comment on lines +335 to 342
# ``capacity`` is ``None`` when the storage unit is configured with
# unlimited capacity (``total_storage_size=None``).
if capacity is not None:
self.storage_capacity.labels(storage_unit_id=label).set(capacity)
self.storage_utilization.labels(storage_unit_id=label).set(
active / capacity if capacity > 0 else 0.0
)
self.storage_active_keys.labels(storage_unit_id=label).set(active)
Comment thread transfer_queue/metrics.py
Comment on lines +335 to +339
# ``capacity`` is ``None`` when the storage unit is configured with
# unlimited capacity (``total_storage_size=None``).
if capacity is not None:
self.storage_capacity.labels(storage_unit_id=label).set(capacity)
self.storage_utilization.labels(storage_unit_id=label).set(
Comment thread transfer_queue/metrics.py
self.storage_capacity.labels(storage_unit_id=label).set(capacity)
self.storage_utilization.labels(storage_unit_id=label).set(
active / capacity if capacity > 0 else 0.0
)

@0oshowero0 0oshowero0 Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We can have an else here to deal with the remove logic. For example

     else:
         for gauge in (self.storage_capacity, self.storage_utilization):
             try:
                  gauge.remove(label)
             except (KeyError, ValueError):
                  pass

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done. Added an else branch to prune the stale storage_capacity / storage_utilization series when a unit transitions to unlimited, mirroring the existing partition-level pruning. Also covered Copilot's suggestion with two unit tests in test_metrics.py.

Follow-up of Ascend#130, which made ``total_storage_size`` optional.

When a storage unit is configured with unlimited capacity
(``total_storage_size=None``), ``SimpleStorageUnit._handle_get_metrics``
reports ``capacity=None``. The ``storage_capacity`` and
``storage_utilization`` ``prometheus_client.Gauge`` objects defined in
``transfer_queue/metrics.py`` cannot accept ``None`` (``float(None)``
raises ``TypeError``), which triggers a
``Failed to collect metrics from storage unit ...`` warning every
``TQ_METRICS_COLLECT_INTERVAL`` seconds for every unlimited-capacity
storage unit, polluting the logs.

Skip the capacity and utilization gauges in that case; the remaining
metrics (``active_keys``, ``memory_rss``, per-op stats) are still
reported correctly.

If a storage unit previously reported a numeric capacity and later
transitions to unlimited (e.g. after re-registration), also remove the
stale ``storage_capacity`` / ``storage_utilization`` series so
dashboards do not keep serving outdated values, mirroring the
stale-label pruning already applied to partition-level gauges.

Signed-off-by: nexhu <nexhu@tencent.com>
@huniu20 huniu20 force-pushed the fix/metrics-none-capacity branch from e0386b0 to a43cb6d Compare July 10, 2026 16:37
@ascend-robot

Copy link
Copy Markdown

CLA Signature Pass

huniu20, thanks for your pull request. All authors of the commits have signed the CLA. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants