fix: Metrics page console hygiene + CSP sourcemap fetches - #98
Merged
Conversation
Three chart configurations forced `scales.y.ticks.stepSize: 1` to get
integer-only Y-axis labels (for series like total requests, 5xx
counts, sessions, etc.). When those series climbed into the
thousands — which HAProxy request counters routinely do over the
24-hour default window — Chart.js tried to generate a tick per
unit, capped at 1000, and logged the warning:
scales.y.ticks.stepSize: 1 would result generating up to 8681
ticks. Limiting to 1000.
Once per chart re-render. On a busy metrics page with live SSE
updates that's a steady stream of identical warnings drowning out
useful console output.
Fix: replace `stepSize: 1` with `precision: 0` in all three sites.
Same "integer-only ticks" intent, but Chart.js auto-picks the step
size — 1 for a 0-5 range, 1000 for a 0-8681 range — and the
result rounds to integers. No more clamp warnings.
The existing tick-callback filter (returns `value` only when
`Math.floor(value) === value`) stays in place as a belt-and-braces
guard against any fractional value slipping through.
Sites:
- static/js/charts/chart-defaults.js — the shared chart-options factory
used by the home page widget and most embedded charts.
- internal/framework/templates/pages/metrics.templ — the inline chart
config used inside the Metrics page's chart-render functions.
- internal/framework/templates/pages/details.templ — the per-backend
drill-down chart options builder (was already setting
`precision: 0` alongside `stepSize: 1`; just drops the latter).
Pure JS / templ-comment change; no Go code touched. Templ regen
clean, full test suite green.
The Metrics page's SSE event handlers were leftover with developer
console.log calls firing on every incoming event — i.e. once every
2 seconds per active tab. On a page open for a few minutes the
console fills with rows like:
stats.updated event: {…}
appendStatsData - eventData: {…}
appendStatsData - frontends: 4 backends: 28
metrics.updated event: {…}
appendMetricsData - eventData: {…}
appendMetricsData - metrics: {…}
…drowning out anything useful. Removed the six hot-path logs entirely
and quieted the two "skipping empty data point" branches (kept the
behaviour, dropped the console output). The error-path
`console.debug('capabilities fetch failed; ...')` is unchanged.
Same theme as the Chart.js stepSize fix in this branch: cleaning up
the Metrics page's developer-console hygiene without touching any
chart behaviour.
Browsers with DevTools open follow the .map references in chart.js /
tabulator / hammerjs (the .min.js files we already load from CDN) and
issue fetch requests for the sourcemaps. Those fetches go through the
CSP connect-src directive — not script-src — and our production CSP
only allowed 'self' ws: wss:, so the requests were blocked and the
browser console filled with violations like:
Connecting to 'https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/
chart.umd.js.map' violates the following Content Security Policy
directive: "connect-src 'self' ws: wss:".
Adds https://unpkg.com and https://cdn.jsdelivr.net to connect-src in
production CSP mode. These hosts are already trusted by script-src and
style-src for the same vendored libraries, so this is consistent
rather than expanding trust — connect-src to fetch their .map files
matches the trust we already grant to fetch their .min.js files.
Strict-CSP mode (USE_LOCAL_ASSETS=true) is unchanged: it still
requires 'self' only, since the local-asset build serves everything
same-origin and there are no cross-origin sourcemap fetches.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR reduces browser-console noise on the Gearbox dashboard by adjusting Chart.js integer tick configuration on Metrics-related charts, removing hot-path debug logging from Metrics SSE handlers, and updating the production CSP to stop sourcemap-related CSP violations when DevTools is open.
Changes:
- Replaced Chart.js
scales.y.ticks.stepSize: 1withprecision: 0for integer-only Y-axis ticks to avoid excessive-tick warning spam. - Removed frequent
console.logcalls in Metrics page SSE handlers and empty-payload paths. - Expanded production CSP
connect-srcto allow CDN sourcemap fetches fromunpkg.comandcdn.jsdelivr.net.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
gearbox/static/js/charts/chart-defaults.js |
Updates shared “integer Y-axis” Chart.js defaults to use precision: 0 (avoids tick spam warnings). |
gearbox/internal/framework/templates/pages/metrics.templ |
Adjusts inline chart tick config and removes noisy Metrics SSE console.log statements. |
gearbox/internal/framework/templates/pages/details.templ |
Removes redundant stepSize: 1 usage, relying on precision: 0 for integer ticks. |
gearbox/internal/framework/middleware/security_headers.go |
Updates production CSP connect-src to allow sourcemap fetches from approved CDNs. |
Reverts the CDN-host expansion of connect-src added earlier in this PR. Copilot review (PR #98) correctly flagged the trade-off: even though script-src already trusts unpkg.com and cdn.jsdelivr.net to serve the .min.js libraries we depend on, expanding connect-src to those same origins materially weakens defense-in-depth. A compromised CDN script can already run in our origin, but the prior connect-src restriction prevented it from exfiltrating data via fetch/XHR/EventSource. That's worth keeping. The .map sourcemap fetches the browser issues with DevTools open will again show as CSP-violation lines in the DevTools console — but only in DevTools, only with it open, and only for the .map files. No production user ever sees them. For developers who want to silence the DevTools noise: USE_LOCAL_ASSETS=true serves all vendored libraries from /static/js/vendor/ same-origin, which eliminates the cross-origin sourcemap fetches entirely. The existing connect-src 'self' allows same-origin map fetches. Documented the choice in a comment on the directive so a future reader can find the reasoning without re-deriving it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three small fixes that clean up the dashboard's browser console. All limited to the Metrics page + the CSP middleware; no behaviour changes elsewhere.
What's fixed
1. Chart.js
stepSize: 1warning spamThree chart configurations were forcing
scales.y.ticks.stepSize: 1to get integer-only Y-axis labels. When the series climbed into the thousands — which HAProxy request counters routinely do over a 24-hour window — Chart.js tried to draw a tick per unit, capped at 1000, and logged:Once per chart re-render. On a busy Metrics page with live SSE updates that's a steady stream of identical warnings.
Replaced
stepSize: 1withprecision: 0in all three sites. Same "integer-only ticks" intent, but Chart.js auto-picks the step size — 1 for a 0-5 range, 1000 for a 0-8681 range — and the result rounds to integers. The existing tick-callback filter stays in place as a belt-and-braces guard.Sites:
gearbox/static/js/charts/chart-defaults.js— shared chart-options factorygearbox/internal/framework/templates/pages/metrics.templ— inline chart configgearbox/internal/framework/templates/pages/details.templ— per-backend drill-down (was already settingprecision: 0; just drops the redundantstepSize: 1)2. Dev-debug
console.logspam on the Metrics pageThe SSE event handlers were leftover with developer
console.logcalls firing on every incoming event — once every 2 seconds per active tab. Six hot-path logs and two "skipping empty payload" logs. Removed them all. The error-pathconsole.debug('capabilities fetch failed; ...')is unchanged.3. CSP
connect-srcblocking CDN sourcemap fetchesBrowsers with DevTools open follow the
//# sourceMappingURL=...references inchart.umd.min.js/tabulator.min.js/hammer.min.jsand issue fetch requests for the.mapfiles. Those go throughconnect-src(notscript-src), and the production CSP only allowed'self' ws: wss:— so DevTools spammed CSP-violation errors:Added
https://unpkg.comandhttps://cdn.jsdelivr.nettoconnect-srcin production-mode CSP. Consistent rather than escalating — those hosts are already trusted byscript-srcandstyle-srcto serve the libraries; allowingconnect-srcto fetch their sourcemaps matches the existing trust. Strict-CSP mode (USE_LOCAL_ASSETS=true) is unchanged.Test plan
make testgreen on both modules.go vetclean.light-hugger, leave it open for ~30s with DevTools console open:scales.y.ticks.stepSizewarnings.appendStatsData/appendMetricsData/stats.updated eventlog spam.*.mapfetches.Out of scope (separate work)
cdn.tailwindcss.com(the Play CDN runtime that explicitly warns "should not be used in production"). Switching to a proper Tailwind CLI build is a multi-file change with build-tooling implications and deserves its own dedicated PR./api/session-info401 in dev-auto-login mode — investigating whether it's just cosmetic in DevTools or actually breaks anything. Will file an issue if it impacts testing.🤖 Generated with Claude Code