mirror of
https://github.com/lukaszraczylo/graphql-monitoring-proxy.git
synced 2026-06-05 23:03:48 +00:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| dc9e17eead | |||
| 753df6e133 | |||
| f3a3b849a0 | |||
| 1555958aef | |||
| bccf0006b7 | |||
| 9f4d92db5b | |||
| a99a926d15 | |||
| 6dd0ca3069 | |||
| ef40902998 | |||
| f55ed6d140 | |||
| bc36607d4e | |||
| 51d7af5fe8 | |||
| c9b89275ca | |||
| f0042ffe94 | |||
| 755b433015 | |||
| 86ae4ce802 | |||
| 468cd959a7 |
+2
-1
@@ -2,6 +2,7 @@ FROM gcr.io/distroless/base-debian12:nonroot
|
||||
WORKDIR /go/src/app
|
||||
ARG TARGETARCH
|
||||
ARG TARGETOS
|
||||
# silly workaround for distroless image as no chmod is available
|
||||
COPY --chmod=777 --chown=nonroot:nonroot static/app /go/src/app
|
||||
ADD dist/bot-$TARGETOS-$TARGETARCH /go/src/app/graphql-proxy
|
||||
ADD static/default-ratelimit.json /app/ratelimit.json
|
||||
ENTRYPOINT ["/go/src/app/graphql-proxy"]
|
||||
|
||||
@@ -23,6 +23,7 @@ This project is in active use by [telegram-bot.app](https://telegram-bot.app), a
|
||||
- [Blocking introspection](#blocking-introspection)
|
||||
- [API endpoints](#api-endpoints)
|
||||
- [Ban or unban the user](#ban-or-unban-the-user)
|
||||
- [Cache operations](#cache-operations)
|
||||
- [General](#general)
|
||||
- [Metrics which matter](#metrics-which-matter)
|
||||
- [Healthcheck](#healthcheck)
|
||||
@@ -236,6 +237,11 @@ To do so - you need to enable the api by setting env variable `ENABLE_API=true`
|
||||
* `POST /api/user-ban` - ban the user from accessing the application
|
||||
* `POST /api/user-unban` - unban the user from accessing the application
|
||||
|
||||
#### Cache operations
|
||||
|
||||
* `POST /api/cache-clear` - clear the cache
|
||||
* `GET /api/cache-stats` - get the cache statistics ( hits, misses, size )
|
||||
|
||||
Both endpoints require the `user_id` parameter to be present in the request body and allow you to provide the reason for the ban.
|
||||
|
||||
Example request:
|
||||
|
||||
@@ -23,6 +23,8 @@ func enableApi() {
|
||||
api := apiserver.Group("/api")
|
||||
api.Post("/user-ban", apiBanUser)
|
||||
api.Post("/user-unban", apiUnbanUser)
|
||||
api.Post("/cache-clear", apiClearCache)
|
||||
api.Get("/cache-stats", apiCacheStats)
|
||||
|
||||
go periodicallyReloadBannedUsers()
|
||||
err := apiserver.Listen(fmt.Sprintf(":%d", cfg.Server.ApiPort))
|
||||
@@ -50,6 +52,21 @@ func checkIfUserIsBanned(c *fiber.Ctx, userID string) bool {
|
||||
return found
|
||||
}
|
||||
|
||||
func apiClearCache(c *fiber.Ctx) error {
|
||||
cfg.Logger.Debug("Clearing cache via API", nil)
|
||||
cfg.Cache.CacheClient.ClearCache()
|
||||
cfg.Logger.Info("Cache cleared via API", nil)
|
||||
c.Status(200).SendString("OK: cache cleared")
|
||||
return nil
|
||||
}
|
||||
|
||||
func apiCacheStats(c *fiber.Ctx) error {
|
||||
stats := cfg.Cache.CacheClient.ShowStats()
|
||||
cfg.Logger.Debug("Getting cache stats via API", map[string]interface{}{"stats": stats})
|
||||
c.JSON(stats)
|
||||
return nil
|
||||
}
|
||||
|
||||
type apiBanUserRequest struct {
|
||||
UserID string `json:"user_id"`
|
||||
Reason string `json:"reason"`
|
||||
|
||||
Vendored
+33
-1
@@ -18,6 +18,8 @@ type Cache struct {
|
||||
globalTTL time.Duration
|
||||
compressPool sync.Pool
|
||||
decompressPool sync.Pool
|
||||
cacheHits int
|
||||
cacheMisses int
|
||||
sync.RWMutex // Reintroduced to provide lock methods
|
||||
}
|
||||
|
||||
@@ -75,14 +77,16 @@ func (c *Cache) Get(key string) ([]byte, bool) {
|
||||
|
||||
entry, ok := c.entries.Load(key)
|
||||
if !ok || entry.(CacheEntry).ExpiresAt.Before(time.Now()) {
|
||||
c.cacheMisses++
|
||||
return nil, false
|
||||
}
|
||||
compressedValue := entry.(CacheEntry).Value
|
||||
value, err := c.decompress(compressedValue)
|
||||
if err != nil {
|
||||
c.cacheMisses++
|
||||
return nil, false
|
||||
}
|
||||
|
||||
c.cacheHits++
|
||||
return value, true
|
||||
}
|
||||
|
||||
@@ -109,6 +113,34 @@ func (c *Cache) CleanExpiredEntries() {
|
||||
})
|
||||
}
|
||||
|
||||
type CacheStats struct {
|
||||
CachedQueries int `json:"cached_queries"`
|
||||
CacheHits int `json:"cache_hits"`
|
||||
CacheMisses int `json:"cache_misses"`
|
||||
}
|
||||
|
||||
func (c *Cache) ShowStats() CacheStats {
|
||||
c.RLock()
|
||||
defer c.RUnlock()
|
||||
var count int
|
||||
c.entries.Range(func(_, _ interface{}) bool {
|
||||
count++
|
||||
return true
|
||||
})
|
||||
cs := CacheStats{
|
||||
CachedQueries: count,
|
||||
CacheHits: c.cacheHits,
|
||||
CacheMisses: c.cacheMisses,
|
||||
}
|
||||
return cs
|
||||
}
|
||||
|
||||
func (c *Cache) ClearCache() {
|
||||
c.cacheHits = 0
|
||||
c.cacheMisses = 0
|
||||
c.entries = sync.Map{}
|
||||
}
|
||||
|
||||
func (c *Cache) compress(data []byte) ([]byte, error) {
|
||||
w := c.compressPool.Get().(*gzip.Writer)
|
||||
defer c.compressPool.Put(w)
|
||||
|
||||
Vendored
+54
@@ -0,0 +1,54 @@
|
||||
package libpack_cache
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Assume that New function initializes the cache and it is defined somewhere in the libpack_cache package.
|
||||
|
||||
func BenchmarkCacheSet(b *testing.B) {
|
||||
cache := New(30 * time.Second) // Initializing the cache with a TTL of 30 seconds
|
||||
key := "benchmark-key"
|
||||
value := []byte("benchmark-value")
|
||||
|
||||
b.ResetTimer() // Reset the timer to exclude the setup time from the benchmark
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
cache.Set(key, value, 5*time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkCacheGet(b *testing.B) {
|
||||
cache := New(30 * time.Second) // Initializing the cache
|
||||
key := "benchmark-key"
|
||||
value := []byte("benchmark-value")
|
||||
cache.Set(key, value, 5*time.Second) // Pre-set a value to retrieve
|
||||
|
||||
b.ResetTimer() // Start timing
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = cache.Get(key)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkCacheExpire(b *testing.B) {
|
||||
key := "benchmark-expire-key"
|
||||
value := []byte("benchmark-value")
|
||||
ttl := 5 * time.Millisecond // Setting a short TTL for quick expiration
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
cache := New(30 * time.Second)
|
||||
cache.Set(key, value, ttl)
|
||||
time.Sleep(ttl) // Wait for the key to expire
|
||||
_, _ = cache.Get(key)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkCacheStats(b *testing.B) {
|
||||
cache := New(30 * time.Second) // Initializing the cache
|
||||
key := "benchmark-key"
|
||||
value := []byte("benchmark-value")
|
||||
cache.Set(key, value, 5*time.Second) // Pre-set a value to retrieve
|
||||
cache.Get(key)
|
||||
}
|
||||
Vendored
+33
@@ -110,3 +110,36 @@ func (suite *CacheTestSuite) Test_CacheExpire() {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *CacheTestSuite) Test_CacheStats() {
|
||||
cache := New(30 * time.Second)
|
||||
tests := []struct {
|
||||
name string
|
||||
cache_value string
|
||||
ttl time.Duration
|
||||
}{
|
||||
{
|
||||
name: "test1",
|
||||
cache_value: "test1-123",
|
||||
ttl: 2 * time.Second,
|
||||
},
|
||||
{
|
||||
name: "test2",
|
||||
cache_value: "test2-123",
|
||||
ttl: 5 * time.Second,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
suite.T().Run(tt.name, func(t *testing.T) {
|
||||
cache.Set(tt.name, []byte(tt.name), tt.ttl)
|
||||
c, ok := cache.Get(tt.name)
|
||||
suite.Equal(true, ok)
|
||||
suite.Equal(tt.name, string(c))
|
||||
})
|
||||
}
|
||||
cache.Get("non-existent-non-cached-key")
|
||||
stats := cache.ShowStats()
|
||||
suite.Equal(2, stats.CacheHits, "CacheHits")
|
||||
suite.Equal(1, stats.CacheMisses, "CacheMisses")
|
||||
suite.Equal(2, stats.CachedQueries, "CachedQueries")
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ go 1.21
|
||||
require (
|
||||
github.com/VictoriaMetrics/metrics v1.33.1
|
||||
github.com/avast/retry-go/v4 v4.6.0
|
||||
github.com/goccy/go-json v0.10.2
|
||||
github.com/goccy/go-json v0.10.3
|
||||
github.com/gofiber/fiber/v2 v2.52.4
|
||||
github.com/gofrs/flock v0.8.1
|
||||
github.com/google/uuid v1.6.0
|
||||
@@ -14,9 +14,9 @@ require (
|
||||
github.com/lukaszraczylo/ask v0.0.0-20230927103145-2ff1123b4415
|
||||
github.com/lukaszraczylo/go-ratecounter v0.1.8
|
||||
github.com/lukaszraczylo/go-simple-graphql v1.2.14
|
||||
github.com/rs/zerolog v1.32.0
|
||||
github.com/rs/zerolog v1.33.0
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/valyala/fasthttp v1.53.0
|
||||
github.com/valyala/fasthttp v1.54.0
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -37,11 +37,11 @@ require (
|
||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
|
||||
golang.org/x/net v0.25.0 // indirect
|
||||
golang.org/x/net v0.26.0 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
golang.org/x/sys v0.20.0 // indirect
|
||||
golang.org/x/term v0.20.0 // indirect
|
||||
golang.org/x/text v0.15.0 // indirect
|
||||
golang.org/x/sys v0.21.0 // indirect
|
||||
golang.org/x/term v0.21.0 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
@@ -8,8 +8,8 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
||||
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gofiber/fiber/v2 v2.52.4 h1:P+T+4iK7VaqUsq2PALYEfBBo6bJZ4q3FP8cZ84EggTM=
|
||||
github.com/gofiber/fiber/v2 v2.52.4/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
|
||||
@@ -57,14 +57,14 @@ github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/f
|
||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0=
|
||||
github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
|
||||
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.53.0 h1:lW/+SUkOxCx2vlIu0iaImv4JLrVRnbbkpCoaawvA4zc=
|
||||
github.com/valyala/fasthttp v1.53.0/go.mod h1:6dt4/8olwq9QARP/TDuPmWyWcl4byhpvTJ4AAtcz+QM=
|
||||
github.com/valyala/fasthttp v1.54.0 h1:cCL+ZZR3z3HPLMVfEYVUMtJqVaui0+gu7Lx63unHwS0=
|
||||
github.com/valyala/fasthttp v1.54.0/go.mod h1:6dt4/8olwq9QARP/TDuPmWyWcl4byhpvTJ4AAtcz+QM=
|
||||
github.com/valyala/fastrand v1.1.0 h1:f+5HkLW4rsgzdNoleUOB69hyT9IlD2ZQh9GyDMfb5G8=
|
||||
github.com/valyala/fastrand v1.1.0/go.mod h1:HWqCzkrkg6QXT8V2EXWvXCoow7vLwOFN002oeRzjapQ=
|
||||
github.com/valyala/histogram v1.2.0 h1:wyYGAZZt3CpwUiIb9AU/Zbllg1llXyrtApRS815OLoQ=
|
||||
@@ -75,19 +75,19 @@ github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavM
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
|
||||
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
|
||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
|
||||
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"flag"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/gofiber/fiber/v2/middleware/proxy"
|
||||
"github.com/gookit/goutil/envutil"
|
||||
@@ -13,6 +14,7 @@ import (
|
||||
)
|
||||
|
||||
var cfg *config
|
||||
var once sync.Once
|
||||
|
||||
// function get value from the env where the value can be anything
|
||||
func getDetailsFromEnv[T any](key string, defaultValue T) T {
|
||||
@@ -79,7 +81,9 @@ func parseConfig() {
|
||||
|
||||
enableCache() // takes close to no resources, but can be used with dynamic query cache
|
||||
loadRatelimitConfig()
|
||||
enableApi()
|
||||
once.Do(func() {
|
||||
go enableApi()
|
||||
})
|
||||
prepareQueriesAndExemptions()
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ func (suite *Tests) SetupTest() {
|
||||
},
|
||||
)
|
||||
parseConfig()
|
||||
enableApi()
|
||||
StartMonitoringServer()
|
||||
cfg.Logger = libpack_logging.NewLogger()
|
||||
// Setup environment variables here if needed
|
||||
|
||||
@@ -5,6 +5,9 @@ func (ms *MetricsSetup) RegisterDefaultMetrics() {
|
||||
ms.RegisterMetricsCounter(MetricsFailed, nil)
|
||||
ms.RegisterMetricsCounter(MetricsSkipped, nil)
|
||||
ms.RegisterMetricsHistogram(MetricsDuration, nil)
|
||||
ms.RegisterMetricsCounter(MetricsCacheHit, nil)
|
||||
ms.RegisterMetricsCounter(MetricsCacheMiss, nil)
|
||||
ms.RegisterMetricsCounter(MetricsQueriesCached, nil)
|
||||
}
|
||||
|
||||
func (ms *MetricsSetup) RegisterGoMetrics() {
|
||||
|
||||
@@ -7,4 +7,8 @@ const (
|
||||
MetricsSkipped = "requests_skipped"
|
||||
MetricsExecutedQuery = "executed_query"
|
||||
MetricsTimedQuery = "timed_query"
|
||||
|
||||
MetricsCacheHit = "cache_hit"
|
||||
MetricsCacheMiss = "cache_miss"
|
||||
MetricsQueriesCached = "cached_queries"
|
||||
)
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ var ratelimit_intervals = map[string]time.Duration{
|
||||
}
|
||||
|
||||
func loadRatelimitConfig() error {
|
||||
paths := []string{"/app/ratelimit.json", "./ratelimit.json", "./static/default-ratelimit.json"}
|
||||
paths := []string{"/go/src/app/ratelimit.json", "./ratelimit.json", "./static/app/default-ratelimit.json"}
|
||||
|
||||
for _, path := range paths {
|
||||
err := loadConfigFromPath(path)
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
|
||||
// StartHTTPProxy starts the HTTP and points it to the GraphQL server.
|
||||
func StartHTTPProxy() {
|
||||
cfg.Logger.Debug("Starting the HTTP proxy", nil)
|
||||
server := fiber.New(fiber.Config{
|
||||
DisableStartupMessage: true,
|
||||
AppName: fmt.Sprintf("GraphQL Monitoring Proxy - %s v%s", libpack_config.PKG_NAME, libpack_config.PKG_VERSION),
|
||||
@@ -151,11 +152,13 @@ func processGraphQLRequest(c *fiber.Ctx) error {
|
||||
queryCacheHash = calculateHash(c)
|
||||
|
||||
if cachedResponse := cacheLookup(queryCacheHash); cachedResponse != nil {
|
||||
cfg.Monitoring.Increment(libpack_monitoring.MetricsCacheHit, nil)
|
||||
cfg.Logger.Debug("Cache hit", map[string]interface{}{"hash": queryCacheHash, "user_id": extractedUserID, "request_uuid": c.Locals("request_uuid")})
|
||||
c.Request().Header.Add("X-Cache-Hit", "true")
|
||||
c.Send(cachedResponse)
|
||||
wasCached = true
|
||||
} else {
|
||||
cfg.Monitoring.Increment(libpack_monitoring.MetricsCacheMiss, nil)
|
||||
cfg.Logger.Debug("Cache miss", map[string]interface{}{"hash": queryCacheHash, "user_id": extractedUserID, "request_uuid": c.Locals("request_uuid")})
|
||||
proxyAndCacheTheRequest(c, queryCacheHash, parsedResult.cacheTime, parsedResult.activeEndpoint)
|
||||
}
|
||||
@@ -181,6 +184,7 @@ func proxyAndCacheTheRequest(c *fiber.Ctx, queryCacheHash string, cacheTime int,
|
||||
return
|
||||
}
|
||||
cfg.Cache.CacheClient.Set(queryCacheHash, c.Response().Body(), time.Duration(cacheTime)*time.Second)
|
||||
cfg.Monitoring.Increment(libpack_monitoring.MetricsQueriesCached, nil)
|
||||
c.Send(c.Response().Body())
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
Reference in New Issue
Block a user