Skip to content

Add read-only network metrics API#2003

Open
liameast43345 wants to merge 2 commits into
unraid:mainfrom
liameast43345:bounty/network-metrics-1602
Open

Add read-only network metrics API#2003
liameast43345 wants to merge 2 commits into
unraid:mainfrom
liameast43345:bounty/network-metrics-1602

Conversation

@liameast43345
Copy link
Copy Markdown

@liameast43345 liameast43345 commented May 12, 2026

Summary

  • expands read-only network interface data with link details and address arrays
  • adds metrics.network plus systemMetricsNetwork polling at the existing 2s metrics interval
  • maps systeminformation network stats to GraphQL-friendly fields and reads Linux packet counters from /sys/class/net when available

Fixes #1602

Testing

  • pnpm --dir api exec vitest run src/unraid-api/graph/resolvers/metrics/network/network.service.spec.ts src/unraid-api/graph/resolvers/metrics/metrics.resolver.spec.ts src/unraid-api/graph/resolvers/metrics/metrics.resolver.integration.spec.ts src/unraid-api/graph/resolvers/metrics/temperature/temperature.resolver.integration.spec.ts
  • pnpm --dir api lint
  • pnpm --dir api type-check

Notes

A broader pnpm --dir api test run executed 1,976 passing tests and failed only src/test/core/utils/pm2/unraid-api-running.integration.test.ts, where the PM2 process detection returned false in this local environment.

Summary by CodeRabbit

  • New Features
    • Added richer network interface info (MTU, speed, duplex, VLAN, IPv4/IPv6 address lists).
    • Introduced per-interface network metrics (bytes, packets, errors, drops, RX/TX rates, utilization).
    • Added query for network interfaces and real-time subscription for system network metrics.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 12, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 13048070-7105-4963-867c-576434592532

📥 Commits

Reviewing files that changed from the base of the PR and between 920977f and 3fde249.

📒 Files selected for processing (1)
  • api/src/unraid-api/graph/resolvers/info/network/network.service.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • api/src/unraid-api/graph/resolvers/info/network/network.service.ts

Walkthrough

Adds GraphQL types and a root query for static network interfaces, implements NetworkMetrics collection (polling + pubsub), exposes metrics in metrics.network and systemMetricsNetwork subscription, and updates services, modules, and tests to map systeminformation and /sys counters into GraphQL models.

Changes

Network Metrics and Interface Exposure

Layer / File(s) Summary
Network Interface Schema and Types
api/generated-schema.graphql, api/src/unraid-api/graph/resolvers/info/network/network.model.ts
GraphQL schema introduces InfoNetworkIpv4Address and InfoNetworkIpv6Address types with address and netmask/prefixLength fields, extends InfoNetworkInterface with MTU, speed, duplex, virtual/internal flags, operstate, type, VLAN ID, and arrays of structured IPv4/IPv6 addresses, and exposes networkInterfaces query on the root Query type.
Network Interface Query Implementation
api/src/unraid-api/graph/resolvers/info/network/network.resolver.ts, api/src/unraid-api/graph/resolvers/info/network/network.service.ts
networkInterfaces() is converted to a top-level query with a permissions guard (AuthAction.READ_ANY, Resource.INFO), and a new @ResolveField method populates the networkInterfaces field on Info. Service layer extends interface mapping to include MTU, speed, duplex, operational state, virtual/internal flags, VLAN ID, and structures IPv4/IPv6 addresses with netmask/prefix-length parsing.
Network Metrics Schema and Model
api/generated-schema.graphql, api/src/unraid-api/graph/resolvers/metrics/network/network.model.ts
GraphQL schema introduces NetworkMetrics type with fields for interface name, operational state, byte/packet counters (received/sent), error and drop counters, RX/TX throughput rates, optional utilization percentage, and last-updated timestamp. Metrics type gains network: [NetworkMetrics!]! field.
Network Metrics Collection Service
api/src/unraid-api/graph/resolvers/metrics/network/network.service.ts
NetworkMetricsService fetches interface statistics from systeminformation.networkStats() and augments them with packet counters from /sys/class/net/<iface>/statistics/ (rx_packets, tx_packets). Computes utilizationPercent from combined RX/TX rates and interface speed; gracefully returns zero counters and undefined utilization when speed is unavailable or files are unreadable.
Metrics Query and Network Subscription
api/src/unraid-api/graph/resolvers/metrics/metrics.resolver.ts, api/src/unraid-api/graph/resolvers/metrics/metrics.model.ts
MetricsResolver injects NetworkMetricsService and adds network() resolve field. During onModuleInit, registers PUBSUB_CHANNEL.NETWORK_UTILIZATION polling topic (2000ms) to fetch and publish metrics. Implements systemMetricsNetwork subscription that streams updates through the pubsub channel with READ_ANY / INFO permission guard. GraphQL schema exposes systemMetricsNetwork: [NetworkMetrics!]! on Subscription type.
Module Integration and PubSub Setup
api/src/unraid-api/graph/resolvers/metrics/metrics.module.ts, packages/unraid-shared/src/pubsub/graphql.pubsub.ts
MetricsModule imports ServicesModule and registers NetworkMetricsService as a provider. GRAPHQL_PUBSUB_CHANNEL enum gains NETWORK_UTILIZATION constant to support network metrics streaming.
Unit and Integration Test Coverage
api/src/unraid-api/graph/resolvers/metrics/network/network.service.spec.ts, api/src/unraid-api/graph/resolvers/metrics/metrics.resolver.spec.ts, api/src/unraid-api/graph/resolvers/metrics/metrics.resolver.integration.spec.ts, api/src/unraid-api/graph/resolvers/metrics/temperature/temperature.resolver.integration.spec.ts
Adds Vitest suite for NetworkMetricsService covering normal metric mapping and fallback behavior when speed is unavailable. Extends MetricsResolver specs with network() query tests and subscription/polling lifecycle assertions. Registers NetworkMetricsService in all affected test modules.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

  • [Feature Bounty] Network Metrics #1602 — Implements the "Network Interfaces & Metrics" feature: exposes networkInterfaces, metrics.network, and systemMetricsNetwork subscription with per-interface counters, rates, utilization, and 2s polling.
  • Network Interface Monitoring #1559 — Changes align with previously reported request for per-interface monitoring and schema exposure (interfaces, IPs, MTU/speed/duplex, VLAN, realtime metrics).

Poem

🐰 I hopped through nets and counters bright,
IPv4 and IPv6 now in sight.
Metrics pulse and streams alight,
Per-interface tales in flight.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main objective: adding a read-only network metrics API, which aligns with the primary purpose of this changeset.
Linked Issues check ✅ Passed All required features from issue #1602 are implemented: networkInterfaces query with specified fields, metrics.network query, systemMetricsNetwork subscription with 2s polling, packet counter parsing, utilization calculations, and read-only access controls.
Out of Scope Changes check ✅ Passed All changes directly support the network metrics feature. New GraphQL types, resolvers, and services are scoped to network functionality; test updates reflect feature coverage; pubsub channels support subscriptions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 920977ff70

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@Injectable()
export class NetworkMetricsService {
async getNetworkMetrics(): Promise<NetworkMetrics[]> {
const [stats, interfaces] = await Promise.all([networkStats(), networkInterfaces()]);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Return stats for all interfaces

On hosts with more than one interface, networkStats() without an argument only returns the first/default external interface; the systeminformation docs state to pass '*' for all interfaces (https://systeminformation.io/network.html). Since this API is exposed as metrics.network / systemMetricsNetwork for all interfaces and the service already builds speeds for every interface, Unraid interfaces such as br0, bond0, VLANs, or secondary NICs are silently omitted. Use networkStats('*') or pass the collected interface names here.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
api/src/unraid-api/graph/resolvers/info/network/network.service.ts (1)

53-53: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Replace as with satisfies for structural type validation.

Lines 53 and 100 use as InfoNetworkInterface which bypasses TypeScript's type checking. Use satisfies InfoNetworkInterface instead to enforce structural compatibility while preserving inferred types, providing stricter guardrails and better alignment with the coding guideline to avoid casting.

Suggested change
-            } as InfoNetworkInterface;
+            } satisfies InfoNetworkInterface;
...
-        } as InfoNetworkInterface;
+        } satisfies InfoNetworkInterface;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@api/src/unraid-api/graph/resolvers/info/network/network.service.ts` at line
53, Replace the two non-type-safe casts that use "as InfoNetworkInterface" with
the TypeScript "satisfies InfoNetworkInterface" operator so the objects are
structurally validated while keeping inferred types; update the object
expressions that currently end with "as InfoNetworkInterface" (occurrences
around the object returned in the network service — the expression at the line
shown and the second occurrence near line 100) to use "satisfies
InfoNetworkInterface" instead, ensuring your tsconfig/TS version supports the
satisfies operator.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@api/src/unraid-api/graph/resolvers/info/network/network.service.ts`:
- Around line 111-113: The parseIpv6PrefixLength function currently converts
subnet strings via Number(subnet) which treats empty string as 0; update
parseIpv6PrefixLength to first guard against empty or non-numeric subnet (e.g.,
check subnet == null or subnet.trim() === '' or use a /^\d+$/ test) before
calling Number/parseInt, and only return a numeric prefix when the input is a
valid integer in the expected range (0–128); reference function name
parseIpv6PrefixLength and parameter subnet when making this change.

---

Outside diff comments:
In `@api/src/unraid-api/graph/resolvers/info/network/network.service.ts`:
- Line 53: Replace the two non-type-safe casts that use "as
InfoNetworkInterface" with the TypeScript "satisfies InfoNetworkInterface"
operator so the objects are structurally validated while keeping inferred types;
update the object expressions that currently end with "as InfoNetworkInterface"
(occurrences around the object returned in the network service — the expression
at the line shown and the second occurrence near line 100) to use "satisfies
InfoNetworkInterface" instead, ensuring your tsconfig/TS version supports the
satisfies operator.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: e3f927f4-c9be-475b-b5d5-8c88456925fe

📥 Commits

Reviewing files that changed from the base of the PR and between a2d4843 and 920977f.

📒 Files selected for processing (14)
  • api/generated-schema.graphql
  • api/src/unraid-api/graph/resolvers/info/network/network.model.ts
  • api/src/unraid-api/graph/resolvers/info/network/network.resolver.ts
  • api/src/unraid-api/graph/resolvers/info/network/network.service.ts
  • api/src/unraid-api/graph/resolvers/metrics/metrics.model.ts
  • api/src/unraid-api/graph/resolvers/metrics/metrics.module.ts
  • api/src/unraid-api/graph/resolvers/metrics/metrics.resolver.integration.spec.ts
  • api/src/unraid-api/graph/resolvers/metrics/metrics.resolver.spec.ts
  • api/src/unraid-api/graph/resolvers/metrics/metrics.resolver.ts
  • api/src/unraid-api/graph/resolvers/metrics/network/network.model.ts
  • api/src/unraid-api/graph/resolvers/metrics/network/network.service.spec.ts
  • api/src/unraid-api/graph/resolvers/metrics/network/network.service.ts
  • api/src/unraid-api/graph/resolvers/metrics/temperature/temperature.resolver.integration.spec.ts
  • packages/unraid-shared/src/pubsub/graphql.pubsub.ts

Comment thread api/src/unraid-api/graph/resolvers/info/network/network.service.ts Outdated
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.

[Feature Bounty] Network Metrics

2 participants