Commit Graph
452 Commits
Author SHA1 Message Date
lukaszraczylo 55fc2ae1de feat(deps)!: migrate from fiber v2 to fiber v3
BREAKING CHANGE: upgrades the HTTP framework from gofiber/fiber/v2 to gofiber/fiber/v3, and gofiber/websocket/v2 to gofiber/contrib/v3/websocket.

- Handlers now take fiber.Ctx (interface) instead of *fiber.Ctx. - DisableStartupMessage moved from fiber.Config to fiber.ListenConfig on the proxy/api/monitoring Listen calls. - cors AllowOrigins is now []string; c.BodyParser -> c.Bind().Body(). - app.Test takes fiber.TestConfig instead of an int timeout (tests updated). - WebSocket swapped to contrib/v3/websocket (same Conn/New/Config/IsCloseError/IsWebSocketUpgrade API; Conn.Query preserved). - Adopts fasthttp v1.71.0 (pulled by fiber v3), resolving the v1.71 Host-header enforcement that broke the prior pinned-v1.69 workaround.

fix(connpool): the background keep-alive goroutine no longer reads the mutable global cfg (captures HostGraphQL/HealthcheckGraphQL at pool creation). Under v3 timing it raced with parseConfig/test cfg reassignment; go test -race ./... is now clean (0 data races).

test: make the circuit-breaker cache-fallback and request-coalescing integration tests deterministic (cache TTL outlives the retry loop; coalescing asserts against a measured single-request baseline instead of a hard-coded count); drop the flaky timing-ratio assertion in TestTimingAttackResistance (constant-time guarantee comes from subtle.ConstantTimeCompare, not wall-clock timing).

Verified: go build, go vet, golangci-lint (0 issues), go test -race ./... (all packages pass, 0 races), govulncheck (no vulnerabilities). App + dashboard + WebSocket verified live under v3 in single-node and cluster modes.
2026-06-21 13:15:14 +01:00
lukaszraczylo 877325a633 chore(deps): update dependencies and clear x/net vulnerabilities
Bump golang.org/x/net v0.52.0 -> v0.56.0, fixing GO-2026-5026 (idna Punycode label rejection) and GO-2026-4918 (HTTP/2 transport infinite loop). govulncheck now reports no vulnerabilities. Also bumps x/sync, x/sys, x/term, x/text, otel v1.43->v1.44, grpc v1.80->v1.81 and genproto.

Hold github.com/valyala/fasthttp at v1.69.0: v1.71.0 changes request handling such that the API auth/integration security suites fail (app.Test errors on benign requests), violating the behaviour-preserving upgrade rule. fasthttp had no flagged vulnerability, so pinning it back loses no security fix. Adopting v1.71.0 needs separate investigation.

Verified: go build, go vet, golangci-lint, go test -race ./... all pass; govulncheck clean.
v1.0.10
2026-06-21 02:54:03 +01:00
lukaszraczylo 7e0d1e19b1 fix(circuitbreaker): guard nil monitoring to prevent boot panic
Starting with ENABLE_CIRCUIT_BREAKER=true panicked at boot: parseConfig -> initCircuitBreaker registers a metrics gauge, but cfg.Monitoring is assigned later by StartMonitoringServer, so the registration dereferenced a nil *MetricsSetup.

Add nil-receiver guards to the MetricsSetup registration methods (RegisterMetricsGauge/GaugeFunc/Counter, RegisterFloatCounter, RegisterMetricsSummary/Histogram), matching their existing 'return a dummy to prevent panics' contract. The guard is a no-op for non-nil receivers, so existing callers are unaffected. The breaker and the admin dashboard (which reads gobreaker state directly) keep working.

Add regression tests for the nil-receiver methods and for initCircuitBreaker with nil monitoring.
2026-06-21 02:48:37 +01:00
lukaszraczylo 5bbe986656 fix(rps): count cache-served requests toward current RPS
RecordRequest() only ran inside proxyTheRequest, but cache hits return from handleCaching before reaching it. As a result the dashboard's current RPS read 0 whenever traffic was served from cache (e.g. a repeated query at 100% hit rate). Record the request on the cache-hit branch too; misses and proxied/GET requests still record in proxyTheRequest, so there is no double counting.

Verified: 100% cache-hit load now reports ~16-20k req/s instead of a flat 0.
2026-06-21 02:48:35 +01:00
lukaszraczylo 01d1de1f0b feat(admin): redesign dashboard and make cluster view a real control
Replace the AI-slop visual (indigo->purple gradient, glassmorphism, uniform rounded cards, hover-lift) with a deliberate warm-paper 'instrument panel': monospace tabular telemetry, GraphQL brand magenta accent, flat hairline cards, real type hierarchy, WCAG-AA contrast, focus-visible, prefers-reduced-motion and aria-live status. No new font/CDN deps.

Make the cluster-view toggle functional: the WebSocket stats stream now honours a ?view=local|cluster query param, so toggling streams this-node-only vs aggregated metrics instead of being cosmetic (the stream previously always sent cluster-aware data when an aggregator existed). The toggle is always visible -- disabled with a 'single node' hint when Redis cluster mode is off -- so it is discoverable.

Fix cluster-mode rendering bugs: derive backend health from healthy/total instances (health card no longer stuck on 'Loading'), show 'n/a' for Redis memory instead of a misleading 0 MB, render aggregated CB/retry/coalescing/connections on the polling path too, and surface the proxy version and backend-health detail.

Tests assert the served dashboard against stable markers instead of the cosmetic page title.
2026-06-21 02:48:20 +01:00
lukaszraczylo 1bff79e4f4 ci: also bump benchmark job Go to 1.25 v1.0.2 2026-05-22 23:37:46 +01:00
lukaszraczylo b6e83f2837 ci: bump release Go to 1.25 to match go.mod directive
The repo's go.mod has required go 1.25.0 since the perf+coverage pass,
but the release workflow still pinned setup-go to 1.24 — the latest
1.24.X tool refuses to compile a 1.25 module with GOTOOLCHAIN=local,
breaking auto-release on every push.
2026-05-22 23:36:44 +01:00
lukaszraczylo 287289cd80 fix(telemetry): inject appVersion at build + auto-resolve at runtime
The released v0.45.1 binary shipped with the source default
appVersion="dev" because .goreleaser.yaml had ldflags="-s -w" only,
so every startup ping was rejected by the receiver with HTTP 400
(invalid version: regex requires leading digit).

Two-layer fix:

1. .goreleaser.yaml now passes -X main.appVersion={{.Version}} so
   goreleaser-built binaries report the actual release version.
2. Switch to telemetry.SendForModule which prefers
   debug.ReadBuildInfo Main/Deps when available, falling back to
   appVersion. This means `go install github.com/lukaszraczylo/
   [email protected]` users also get correct versions
   without relying on the ldflag.

Bumps oss-telemetry to v0.2.1 for SendForModule.
2026-05-22 23:34:09 +01:00
lukaszraczylo 21b429c98a docs: add Telemetry section linking to oss-telemetry opt-out docs
Discloses the single anonymous adoption ping sent on startup and points
users to the upstream README section for full opt-out instructions
instead of duplicating the table here.
2026-05-21 04:07:12 +01:00
lukaszraczylo d96d2f429f feat: anonymous usage telemetry via oss-telemetry
Send a single fire-and-forget ping at startup to help track adoption
and version spread. No persistent identifiers are collected.

Adds main.appVersion var (defaulting to "dev"); wire ldflags
(-X main.appVersion=$VERSION) to populate it at release time.

Opt out via any of:
  DO_NOT_TRACK=1
  OSS_TELEMETRY_DISABLED=1
  GRAPHQL_MONITORING_PROXY_DISABLE_TELEMETRY=1
v0.45.1
2026-05-21 03:06:34 +01:00
lukaszraczylo c2c75d69c0 perf+coverage: optimisation pass + coverage push to ≥70%
Performance / resource usage:
- circuit_breaker_metrics: fix data race on failCounters map (RWMutex + double-checked locking)
- server.go: drop user_id and op_name metric labels (Prometheus cardinality bound); de-duplicate extractUserInfo
- graphql.go: gate runtime.ReadMemStats per-request behind ENABLE_ALLOCATION_TRACKING flag (default off)
- graphql.go: collapse two-pass AST scan into single pass; lower-case once
- sanitization.go: cache compiled redaction regexes per pattern via sync.Map; hoist inner constants to pkg vars
- proxy.go: hoist connection/timeout substrings to pkg vars; sentinel errors for static error paths; drop dead Headers map alloc
- metrics_aggregator.go: log-field allocation guarded by Logger.IsLevelEnabled
- logging/logger.go: add IsLevelEnabled helper
- lru_cache.go: 16-shard sharding, FNV-1a routing (concurrent throughput +22%)
- cache/memory/lru_memory_cache.go: gzip compress/decompress moved outside mu.Lock
- rps_tracker.go: RWMutex+uint64 -> atomic.Uint64
- retry_budget.go: drop unused mutex
- api.go: bannedUsersIDs map+RWMutex -> sync.Map (+ snapshot/replace helpers)
- tracing/tracing.go: pkg-level constSpanAttrs, copy-then-append in StartSpanWithAttributes
- admin_dashboard.go: handleStatsWebSocket reuses bytes.Buffer + json.Encoder per connection

Build / runtime:
- Makefile: -ldflags="-s -w" -trimpath, CGO_ENABLED=0 for build (=1 for test recipes)
- Dockerfile + Dockerfile.goreleaser: ENV GOMEMLIMIT=512MiB
- main.go: blank import go.uber.org/automaxprocs (cgroup-aware GOMAXPROCS)
- main.go: PPROF_PORT env var wires net/http/pprof on 127.0.0.1 only with full server timeouts
- README.md: env-var docs + metric-label docs updated; cardinality note

Test coverage push (per package):
- main 51.2% -> 74.7%
- cache 66.3% -> 93.7%
- cache/redis 45.5% -> 98.2%
- tracing 66.7% -> 72.9%
- (cache/memory 91.6%, logging 91.9%, monitoring 77.6%, pkg/pools 100% unchanged)

New test files: coverage_micro_test, coverage_extras_test, server_handlers_test,
api_health_test, admin_dashboard_cluster_test, metrics_aggregator_test, concerns_test,
cache/cache_coverage_test, cache/redis/redis_coverage_test, tracing/tracing_coverage_test.

Bug fix: connection_resilience_test.go TestIntegratedHealthManagement.health_manager_startup
was sync.Once-coupled to InitializeBackendHealth and panicked when another test (e.g. via
parseConfig) had already triggered Once. Use NewBackendHealthManager directly.
v0.44.1
2026-04-19 19:49:24 +01:00
lukaszraczyloandGitHub 65fa936b60 Update go.mod and go.sum (#86) v0.43.91 2026-04-04 04:48:07 +01:00
lukaszraczyloandGitHub 122148d23e Update go.mod and go.sum (#85) v0.43.89 2026-04-03 04:56:24 +01:00
lukaszraczyloandGitHub 6e493e4100 Update go.mod and go.sum (#84) v0.43.87 2026-04-02 04:54:42 +01:00
lukaszraczyloandGitHub 92da4af001 Update go.mod and go.sum (#83) v0.43.85 2026-04-01 05:02:25 +01:00
lukaszraczyloandGitHub c68dc2f20a Update go.mod and go.sum (#82) v0.43.83 2026-03-31 04:56:07 +01:00
lukaszraczyloandGitHub 11ff751001 Update go.mod and go.sum (#81) v0.43.81 2026-03-23 03:53:38 +00:00
lukaszraczyloandGitHub 0414473f15 Update go.mod and go.sum (#80) v0.43.79 2026-03-22 03:49:12 +00:00
lukaszraczyloandGitHub bc61557015 Update go.mod and go.sum (#79) v0.43.77 2026-03-21 03:42:49 +00:00
lukaszraczyloandGitHub 12ec00f697 Update go.mod and go.sum (#78) v0.43.75 2026-03-20 03:45:16 +00:00
lukaszraczyloandGitHub da4a179d66 Update go.mod and go.sum (#77) v0.43.73 2026-03-18 03:51:52 +00:00
lukaszraczyloandGitHub d0ecefce6c Update go.mod and go.sum (#76) v0.43.71 2026-03-17 03:46:12 +00:00
lukaszraczyloandGitHub c742530d2f Update go.mod and go.sum (#75) v0.43.69 2026-03-13 03:46:36 +00:00
lukaszraczyloandGitHub 7304559801 Update go.mod and go.sum (#74) v0.43.67 2026-03-12 03:45:51 +00:00
lukaszraczyloandGitHub aa46992497 Update go.mod and go.sum (#73) v0.43.65 2026-03-10 03:45:15 +00:00
lukaszraczyloandGitHub e968a48584 Update go.mod and go.sum (#72) v0.43.63 2026-03-09 03:47:33 +00:00
lukaszraczyloandGitHub c67dfe1827 Update go.mod and go.sum (#71) v0.43.61 2026-03-08 03:46:25 +00:00
lukaszraczyloandGitHub 55d86e34cf Update go.mod and go.sum (#70) v0.43.59 2026-03-07 03:37:20 +00:00
lukaszraczyloandGitHub cd4a1f16ed Update go.mod and go.sum (#69) v0.43.57 2026-03-03 03:46:23 +00:00
lukaszraczyloandGitHub 3352050bdb Update go.mod and go.sum (#68) v0.43.55 2026-02-27 03:46:24 +00:00
lukaszraczyloandGitHub bb2509e254 Update go.mod and go.sum (#67) v0.43.53 2026-02-26 03:47:30 +00:00
lukaszraczyloandGitHub d027122446 Update go.mod and go.sum (#66) v0.43.51 2026-02-25 03:48:58 +00:00
lukaszraczyloandGitHub 3abbaf66a1 Update go.mod and go.sum (#65) v0.43.49 2026-02-24 03:47:16 +00:00
lukaszraczyloandGitHub f8871a4fb7 Update go.mod and go.sum (#64) v0.43.47 2026-02-19 03:49:36 +00:00
lukaszraczyloandGitHub 420e63f383 Update go.mod and go.sum (#63) v0.43.45 2026-02-18 03:50:04 +00:00
lukaszraczyloandGitHub 9bd9f0b9ba Update go.mod and go.sum (#62) v0.43.43 2026-02-17 03:47:17 +00:00
lukaszraczyloandGitHub 31cb5930d5 Update go.mod and go.sum (#61) v0.43.41 2026-02-15 03:51:37 +00:00
lukaszraczyloandGitHub 454e1d2425 Update go.mod and go.sum (#60) v0.43.39 2026-02-14 03:46:07 +00:00
lukaszraczyloandGitHub 98afa39943 Update go.mod and go.sum (#59) v0.43.37 2026-02-11 03:57:00 +00:00
lukaszraczyloandGitHub 6605c59efd Update go.mod and go.sum (#58) v0.43.35 2026-02-10 03:58:10 +00:00
lukaszraczyloandGitHub f87f2ae5a2 Update go.mod and go.sum (#57) v0.43.33 2026-02-09 03:52:03 +00:00
lukaszraczyloandGitHub 04f6deb0a8 Update go.mod and go.sum (#56) v0.43.31 2026-02-04 03:46:40 +00:00
lukaszraczyloandGitHub 5ea41ea268 Update go.mod and go.sum (#55) v0.43.29 2026-02-03 03:47:55 +00:00
lukaszraczyloandGitHub b8b814a9be Update go.mod and go.sum (#54) v0.43.27 2026-02-02 03:51:10 +00:00
lukaszraczyloandGitHub 5b79b49b00 Update go.mod and go.sum (#53) v0.43.25 2026-02-01 03:55:03 +00:00
lukaszraczyloandGitHub bdbf829a59 Update go.mod and go.sum (#52) v0.43.23 2026-01-30 03:45:32 +00:00
lukaszraczyloandGitHub dcff327745 Update go.mod and go.sum (#51) v0.43.21 2026-01-29 03:45:20 +00:00
lukaszraczyloandGitHub f2997c4c9f Update go.mod and go.sum (#50) v0.43.19 2026-01-28 03:32:18 +00:00
lukaszraczyloandGitHub c3fe0471df Update go.mod and go.sum (#49) v0.43.17 2026-01-27 03:32:38 +00:00
lukaszraczyloandGitHub d62c718682 Update go.mod and go.sum (#48) v0.43.15 2026-01-26 03:37:18 +00:00