Skip to content

feat(monitor): add metrics, new features, and fix middleware bugs#1833

Open
ReneWerner87 wants to merge 13 commits into
mainfrom
copilot/add-monitor-middleware-absolute-counter
Open

feat(monitor): add metrics, new features, and fix middleware bugs#1833
ReneWerner87 wants to merge 13 commits into
mainfrom
copilot/add-monitor-middleware-absolute-counter

Conversation

@ReneWerner87
Copy link
Copy Markdown
Member

Reopened from #1820 — original was closed due to a broken force-push that orphaned main's history (now restored).

All original changes preserved from the same branch.

Copilot AI and others added 13 commits April 18, 2026 10:00
…nic on process error, APIOnly override logic

Agent-Logs-Url: https://github.com/gofiber/contrib/sessions/6da9d492-f179-4c24-9e49-d2afbdb03db7

Co-authored-by: gaby <835733+gaby@users.noreply.github.com>
…nil-safe process, APIOnly default, improved test

Agent-Logs-Url: https://github.com/gofiber/contrib/sessions/5107777e-20e7-4972-a097-544f30f8fda9

Co-authored-by: gaby <835733+gaby@users.noreply.github.com>
…bal tests, typed JSON assertions, close resp.Body

Agent-Logs-Url: https://github.com/gofiber/contrib/sessions/50b76845-c4b0-4416-8204-1a577a58c8dc

Co-authored-by: gaby <835733+gaby@users.noreply.github.com>
Removed comments regarding APIOnly inheritance behavior.
Copilot AI review requested due to automatic review settings April 25, 2026 11:48
@ReneWerner87 ReneWerner87 requested a review from a team as a code owner April 25, 2026 11:48
@ReneWerner87 ReneWerner87 requested review from efectn, gaby and sixcolors and removed request for a team April 25, 2026 11:48
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 25, 2026

Warning

Rate limit exceeded

@ReneWerner87 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 59 minutes and 59 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 59 minutes and 59 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5803b477-2f8b-4a33-aadf-946a15847e90

📥 Commits

Reviewing files that changed from the base of the PR and between 33e256f and b1d360a.

⛔ Files ignored due to path filters (2)
  • .github/workflows/test-monitor.yml is excluded by !**/*.yml
  • v3/swaggerui/go.mod is excluded by !**/*.mod
📒 Files selected for processing (4)
  • v3/monitor/config_test.go
  • v3/monitor/index.go
  • v3/monitor/monitor.go
  • v3/monitor/monitor_test.go
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch copilot/add-monitor-middleware-absolute-counter

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
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds new monitor metrics (requests, goroutines, uptime), improves JSON safety/precision, and extends UI/tests/workflow coverage for the monitor middleware.

Changes:

  • Add pid.requests (uint64 encoded as string), pid.goroutines, and pid.uptime to the monitor JSON payload.
  • Update the dashboard UI to display/chart requests and goroutines, and show uptime.
  • Extend monitor tests and CI matrix (adds Go 1.26.x) to cover the new fields and behaviors.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
v3/monitor/monitor.go Adds atomic-backed request counter, uptime/goroutine metrics, and snapshot-based JSON response generation.
v3/monitor/index.go Adds new UI elements and charts for requests/goroutines and an uptime display; updates JS sampling logic.
v3/monitor/monitor_test.go Adds typed JSON assertions, request counter test, and improves response body handling.
v3/monitor/config_test.go Adds coverage for ConfigDefault.APIOnly inheritance behavior.
.github/workflows/test-monitor.yml Expands Go test matrix to include 1.26.x.
v3/swaggerui/go.mod Removes trailing blank line at EOF.

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

Comment thread v3/monitor/config_test.go
// Caller sets Title but leaves APIOnly unset — should inherit from ConfigDefault.
cfg := configDefault(Config{Title: "custom"})
assert.Equal(t, true, cfg.APIOnly)
})
Copy link

Copilot AI Apr 25, 2026

Choose a reason for hiding this comment

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

The APIOnly inheritance behavior being tested here highlights an API limitation/bug: because APIOnly is a bool, configDefault cannot distinguish “unset” from “explicitly false”. If ConfigDefault.APIOnly is set to true, callers cannot override it back to false (passing Config{APIOnly:false} will still inherit true). Consider adjusting the config API (e.g., APIOnly *bool, or a separate APIOnlySet flag) and add a subtest that asserts Config{APIOnly:false} overrides a true default.

Suggested change
})
})
t.Run("explicit false overrides true default", func(t *testing.T) {
t.Skip("pending config API change: APIOnly is a bool, so configDefault cannot distinguish unset from explicitly false")
cfg := configDefault(Config{APIOnly: false})
assert.Equal(t, false, cfg.APIOnly)
})

Copilot uses AI. Check for mistakes.
Comment thread v3/monitor/index.go
Comment on lines +285 to +287
const reqsBig = BigInt(json.pid.requests);
const reqsDelta = reqsChart.data.datasets[0].data.length === 0 ? 0 : Number(reqsBig - prevRequestsBig);
reqsChart.data.datasets[0].data.push(reqsDelta);
Copy link

Copilot AI Apr 25, 2026

Choose a reason for hiding this comment

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

reqsDelta is computed as Number(reqsBig - prevRequestsBig), which can lose precision (or become Infinity) if the per-refresh delta exceeds JS’s safe integer range. Since pid.requests is intentionally encoded as a string to preserve uint64 precision, consider clamping at Number.MAX_SAFE_INTEGER (or otherwise handling large deltas explicitly) so the chart doesn’t silently display incorrect values under high traffic.

Copilot uses AI. Check for mistakes.
resp, err := app.Test(req)
assert.Equal(t, nil, err)
assert.Equal(t, 200, resp.StatusCode)
defer resp.Body.Close() //nolint:errcheck
Copy link

Copilot AI Apr 25, 2026

Choose a reason for hiding this comment

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

The deferred resp.Body.Close() is marked //nolint:errcheck, but this test already asserts close errors in the loop above. Consider using t.Cleanup (or a deferred closure that asserts) to check the close error here too, so lint suppression isn’t needed and resource-close failures are still surfaced.

Suggested change
defer resp.Body.Close() //nolint:errcheck
t.Cleanup(func() {
assert.NoError(t, resp.Body.Close())
})

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

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

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 enhances the monitor middleware by adding Uptime, Total Requests, and Goroutine metrics, along with corresponding dashboard UI updates. It improves robustness by initializing atomic values to prevent panics and handling cases where process information is unavailable. Feedback indicates that the "Total Requests" counter is misleading as it only tracks requests to the monitor endpoint rather than the entire application, and notes potential performance concerns regarding frequent connection scanning.

Comment thread v3/monitor/monitor.go
}

// Increment the absolute request counter
monitTotalRequests.Add(1)
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.

medium

The monitTotalRequests counter is incremented here, but since this middleware returns a terminal response (HTML or JSON) and does not call c.Next() for other routes, it effectively only counts requests made to the monitor endpoint itself. This makes the 'Total Requests' metric in the dashboard misleading as it does not reflect the total traffic of the entire Fiber application. To accurately monitor total application requests, this logic would need to be part of a separate middleware that wraps the entire app, or the monitor middleware would need to be split into a collector and a viewer.

Comment thread v3/monitor/monitor.go
Comment on lines +169 to +171
if pidConns, err := net.ConnectionsPid("tcp", p.Pid); err == nil {
monitPIDConns.Store(len(pidConns))
}
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.

medium

Calling net.ConnectionsPid every refresh interval (default 3s) can be performance-intensive on systems with a very high number of open connections, as it requires scanning process network state. While this was present in the previous version, consider if this metric is critical enough to justify the overhead in high-throughput environments.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.


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

Comment thread v3/monitor/index.go
Comment on lines +275 to +277
reqsMetric.innerHTML = json.pid.requests;
goroutinesMetric.innerHTML = json.pid.goroutines;
uptimeMetric.innerHTML = formatUptime(json.pid.uptime);
Copy link

Copilot AI Apr 25, 2026

Choose a reason for hiding this comment

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

reqsMetric, goroutinesMetric, and uptimeMetric are assigned with innerHTML even though they display plain text. Using innerHTML unnecessarily increases XSS risk if the JSON payload ever contains unexpected strings; prefer textContent (or innerText) for these fields.

Suggested change
reqsMetric.innerHTML = json.pid.requests;
goroutinesMetric.innerHTML = json.pid.goroutines;
uptimeMetric.innerHTML = formatUptime(json.pid.uptime);
reqsMetric.textContent = json.pid.requests;
goroutinesMetric.textContent = json.pid.goroutines;
uptimeMetric.textContent = formatUptime(json.pid.uptime);

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✏️ Feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants