Skip to content

feat(metrics): show network storage usage - #164

Open
pjcdawkins wants to merge 3 commits into
mainfrom
claude/storage-metrics-disk-names-3b40fa
Open

pjcdawkins wants to merge 3 commits into
mainfrom
claude/storage-metrics-disk-names-3b40fa

Conversation

@pjcdawkins

@pjcdawkins pjcdawkins commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

The metrics API reports network storage volumes (used by storage mounts) under a storage mountpoint, but metrics:all and metrics:disk-usage only read /mnt and /tmp. On projects using storage mounts, storage usage was not visible in the CLI, and the Disk allocation in resources:get had no matching metrics column (disk_* refers to /mnt).

Changes:

  • metrics:all: add storage_used, storage_limit, storage_percent and storage_inodes_* columns. storage_percent is a default column.
  • metrics:disk-usage: add storage_used, storage_limit, storage_percent and storage_i* columns. storage_used, storage_limit and storage_percent are default columns.
  • In tables, the default storage columns are shown only if a service reports storage. Machine-readable formats always include them (after the existing columns), for stable output.
  • Existing disk_* columns are not renamed.
  • A new api.metrics_storage config key (default true) turns this off.

Note: --latest can pick a partial data point, leaving storage (and disk) columns blank; #49 addresses that separately.

🤖 Generated with Claude Code

The metrics API reports network storage volumes (used by "storage"
mounts) under the "storage" mountpoint, but metrics:all and
metrics:disk-usage only read "/mnt" and "/tmp". On projects using
storage mounts, the only disk the customer sizes could not be
monitored from the CLI, and resources:get "Disk" could not be compared
to any metrics column.

- metrics:all: add storage_used, storage_limit, storage_percent and
  storage_inodes_* columns.
- metrics:disk-usage: add storage_used, storage_limit, storage_percent
  and storage_i* columns, and a --storage report option.
- storage_percent is a default column only when a service reports
  storage, so output is unchanged for other projects.
- Existing disk_* columns are not renamed.
- The api.metrics_storage config key (default true) turns this off.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 23, 2026 19:12

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.

Copilot review overview

🟡 Changes recommended

Boolean environment parsing must be fixed so api.metrics_storage=0 actually disables storage metrics.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity

Open (1)
What changed in this PR

Adds network storage usage metrics to legacy metrics commands, including configurable output and integration coverage.

Changes:

  • Adds storage usage and inode columns to metrics:all and metrics:disk-usage.
  • Adds the --storage report option.
  • Adds the api.metrics_storage configuration flag.
  • Adds integration tests for storage output and disabling behavior.

The environment override currently fails to disable the feature because "0" is cast to true; this requires correction.

File Summary
legacy/​src/​Command/​Metrics/​MetricsCommandBase.php Storage detection and configuration handling
legacy/​src/​Command/​Metrics/​DiskUsageCommand.php Storage columns and --storage option
legacy/​src/​Command/​Metrics/​AllMetricsCommand.php Storage metrics in combined output
legacy/​config-defaults.yaml Enables storage metrics by default
integration-tests/​metrics_test.go Tests storage output and configuration disabling

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread integration-tests/metrics_test.go

@upsun-dispatch upsun-dispatch Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Warning

Changes suggested — 🟡 1 warning · 🔵 2 minor points · ⚪ 1 nitpick

🔍 Full review · 5 files reviewed

⚪ Nitpick

  • legacy/src/Command/Metrics/DiskUsageCommand.php:183storageFields() is duplicated verbatim in DiskUsageCommand and AllMetricsCommand (AllMetricsCommand.php:245), differing only in the key names (storage_iused vs storage_inodes_used). Both construct the same six SourceField/SourceFieldPercentage pairs over self::STORAGE_MOUNTPOINT; a future change (e.g. a different aggregation) has to be made twice or the two commands silently diverge.
Verification
  • $fields += $this->storageFields($bytes) cannot clobber existing entries: no storage_* key collides with the existing disk_/tmp_/inodes_ keys in either command.
  • The new api.metrics_storage: true lives in legacy/config-defaults.yaml, which Config always merges under the user config, so getBool('api.metrics_storage') cannot throw 'Configuration not defined'.
  • TEST_CLI_API_METRICS_STORAGE=0 is picked up by Config::applyEnvironmentOverrides' generic second-level scalar map and cast to boolean false, so the disabled test really exercises the disabled path.
  • Expected test values match the code: 920/1000 and 30/100 render as 92.0% and 30.0% via Format::Percent, and -B renders storage_used as 920 via Format::Rounded.
  • --tmp and --storage are rejected together before either sets columns, so the two report column lists can never be merged.

The diff adds integration-tests/metrics_test.go covering the storage columns, the --storage report and the api.metrics_storage=0 path; it runs in the CI integration-test job (make integration-test, after building the phar), while the legacy-php job runs php-cs-fixer, phpstan (level 8) and PHPUnit over the changed PHP. No PHP unit test covers MetricsCommandBase::storageColumns() directly, and nothing covers a storage mountpoint that omits inode metrics.

Review details
  • Commit: 0efbcec
  • Model: claude-opus-5

Review 1 of 10 for this pull request · View the full run

Comment thread legacy/src/Command/Metrics/AllMetricsCommand.php Outdated
Comment thread legacy/src/Command/Metrics/DiskUsageCommand.php Outdated
Comment thread legacy/src/Command/Metrics/MetricsCommandBase.php Outdated
- Remove the disk --storage option. Instead, disk shows storage_used,
  storage_limit and storage_percent by default (metrics:all shows
  storage_percent).
- In tables, storage columns are shown only if a service reports
  storage. Machine-readable formats always include them, for stable
  output.
- Return empty values instead of failing when the storage mountpoint
  lacks a metric (e.g. inodes).
- Share storageFields() between both commands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@upsun-dispatch

upsun-dispatch Bot commented Sep 23, 2026

Copy link
Copy Markdown

📋 PR Summary

Adds network storage usage reporting to the metrics commands. metrics:all and metrics:disk-usage gain storage_used, storage_limit, storage_percent and storage inode columns, sourced from the API's storage mountpoint; in table output the default storage columns appear only when a service reports storage, while machine-readable formats always include them. A new api.metrics_storage config key (default true) disables the feature, and integration tests cover the new output.

Changes
Layer / File(s) Summary
Metrics commands
legacy/src/Command/Metrics/MetricsCommandBase.php Adds shared storage field definitions and the logic for conditionally showing storage columns; percentage calculation now returns null when the value is missing rather than computing from a null value.
legacy/src/Command/Metrics/AllMetricsCommand.php Adds storage used/limit/percent and storage inode columns, with storage_percent among the defaults.
legacy/src/Command/Metrics/DiskUsageCommand.php Adds storage used/limit/percent and storage inode columns, with used, limit and percent as defaults.
Configuration
legacy/config-defaults.yaml Introduces the api.metrics_storage key, defaulting to true.
Tests
integration-tests/metrics_test.go New integration tests for storage metrics output; the mock now returns a partial inode set (inodes_limit only) for the database storage mount to exercise missing-value handling.

@upsun-dispatch upsun-dispatch Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Warning

Changes suggested — 🟡 1 warning · 🔵 2 minor points

🔁 Incremental · 4 files reviewed

Verification
  • extractValue()'s storage early return makes the db fixture's inode-less storage mountpoint yield blank cells instead of the previous RuntimeException.
  • storageFields($bytes, $inodesPrefix) produces storage_inodes_* for metrics:all and storage_i* for disk, matching each command's TABLE_HEADER keys.
  • $fields += $this->storageFields(...) adds no key that collides with an existing field in either command.
  • The disabled branch of storageColumns() filters storage_* out of the header while the fields array is also skipped, so no row key is rendered without a header.

Covered by the rewritten integration-tests/metrics_test.go table test (storage present/absent, csv determinism, TEST_CLI_API_METRICS_STORAGE=0), run by the integration-test job in .github/workflows/ci.yml via make integration-test; no test covers a storage mountpoint that reports a limit without the matching used value.

Review details

Review 2 of 10 for this pull request · View the full run

Comment thread legacy/src/Command/Metrics/MetricsCommandBase.php
Comment thread legacy/src/Command/Metrics/MetricsCommandBase.php
Comment thread legacy/src/Command/Metrics/MetricsCommandBase.php
A limit without a matching used value was shown as 0%.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@upsun-dispatch upsun-dispatch Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Note

Reviewed — No new issues found · 1 still open

🔁 Incremental · 2 files reviewed

Outstanding from earlier reviews:

  • 🔵 #4086400234legacy/src/Command/Metrics/MetricsCommandBase.php:326: Column-count change silently breaks positional parsers of csv/tsv output. — Code unchanged: storageColumns() still appends the storage columns for machine-readable formats regardless of whether any service reports a storage mountpoint; author states this is intentional for stable column sets.
Verification
  • getValueFromSource now returns null when the percentage numerator is missing, so a storage volume reporting only disk_limit renders blank instead of 0.0%.
  • The mirror case (used present, limit absent) still returns null via $limit > 0, so both halves of the partial-data case now render identically blank.
  • Format::format/formatPercent return '' for null, so the new null propagation renders an empty cell rather than erroring.
  • The updated fixture (db storage with inodes_limit but no inodes_used) exercises the new branch, matching the expected trailing-blank column in 'all storage columns' and 'disk-usage storage columns'.
  • extractValue's storage-mountpoint branch returns null rather than throwing, so the added inodes_limit-only fixture cannot abort buildRows.

integration-tests/metrics_test.go covers the changed branch via the db fixture with partial inode metrics (TestMetricsStorage), run by the integration-test job in .github/workflows/ci.yml (make integration-test); no PHPUnit test in the diff covers getValueFromSource directly, though the legacy-php job runs phpstan/php-cs-fixer over the changed file.

Review details

Review 3 of 10 for this pull request · View the full run

This branch has not been deployed

No deployments
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.

2 participants