Skip to content

Commit

Permalink
chore: Add Prometheus metrics for account registration and concurrent…
Browse files Browse the repository at this point in the history
… requests
  • Loading branch information
f-fsantos committed Oct 27, 2024
1 parent ac360cc commit cc052af
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 55 deletions.
2 changes: 2 additions & 0 deletions api/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/pagefaultgames/rogueserver/api/account"
"github.com/pagefaultgames/rogueserver/api/daily"
"github.com/pagefaultgames/rogueserver/db"
"github.com/prometheus/client_golang/prometheus/promhttp"
)

func Init(mux *http.ServeMux) error {
Expand Down Expand Up @@ -73,6 +74,7 @@ func Init(mux *http.ServeMux) error {
mux.HandleFunc("POST /admin/account/googleLink", handleAdminGoogleLink)
mux.HandleFunc("POST /admin/account/googleUnlink", handleAdminGoogleUnlink)
mux.HandleFunc("GET /admin/account/adminSearch", handleAdminSearch)
mux.Handle("GET /metrics", promhttp.Handler())

return nil
}
Expand Down
120 changes: 65 additions & 55 deletions api/endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,23 @@ import (
"github.com/pagefaultgames/rogueserver/api/savedata"
"github.com/pagefaultgames/rogueserver/db"
"github.com/pagefaultgames/rogueserver/defs"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)

/*
The caller of endpoint handler functions are responsible for extracting the necessary data from the request.
Handler functions are responsible for checking the validity of this data and returning a result or error.
Handlers should not return serialized JSON, instead return the struct itself.
*/

var (
accountsRegistered = promauto.NewCounter(prometheus.CounterOpts{
Name: "rogueserver_accounts_registered",
Help: "The total number of accounts registered",
})
)

// account

func handleAccountInfo(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -95,7 +105,7 @@ func handleAccountRegister(w http.ResponseWriter, r *http.Request) {
httpError(w, r, err, http.StatusInternalServerError)
return
}

accountsRegistered.Inc()
w.WriteHeader(http.StatusOK)
}

Expand Down Expand Up @@ -751,36 +761,36 @@ func handleAdminDiscordUnlink(w http.ResponseWriter, r *http.Request) {
discordId := r.Form.Get("discordId")

switch {
case username != "":
log.Printf("Username given, removing discordId")
// this does a quick call to make sure the username exists on the server before allowing the rest of the code to run
// this calls error value 404 (StatusNotFound) if there's no data; this means the username does not exist in the server
_, err = db.CheckUsernameExists(username)
if err != nil {
httpError(w, r, fmt.Errorf("username does not exist on the server"), http.StatusNotFound)
return
}
case username != "":
log.Printf("Username given, removing discordId")
// this does a quick call to make sure the username exists on the server before allowing the rest of the code to run
// this calls error value 404 (StatusNotFound) if there's no data; this means the username does not exist in the server
_, err = db.CheckUsernameExists(username)
if err != nil {
httpError(w, r, fmt.Errorf("username does not exist on the server"), http.StatusNotFound)
return
}

userUuid, err := db.FetchUUIDFromUsername(username)
if err != nil {
httpError(w, r, err, http.StatusInternalServerError)
return
}
userUuid, err := db.FetchUUIDFromUsername(username)
if err != nil {
httpError(w, r, err, http.StatusInternalServerError)
return
}

err = db.RemoveDiscordIdByUUID(userUuid)
if err != nil {
httpError(w, r, err, http.StatusInternalServerError)
return
}
case discordId != "":
log.Printf("DiscordID given, removing discordId")
err = db.RemoveDiscordIdByDiscordId(discordId)
if err != nil {
httpError(w, r, err, http.StatusInternalServerError)
return
}
err = db.RemoveDiscordIdByUUID(userUuid)
if err != nil {
httpError(w, r, err, http.StatusInternalServerError)
return
}
case discordId != "":
log.Printf("DiscordID given, removing discordId")
err = db.RemoveDiscordIdByDiscordId(discordId)
if err != nil {
httpError(w, r, err, http.StatusInternalServerError)
return
}
}

log.Printf("%s: %s removed discord id %s from username %s", userDiscordId, r.URL.Path, r.Form.Get("discordId"), r.Form.Get("username"))

w.WriteHeader(http.StatusOK)
Expand Down Expand Up @@ -821,7 +831,7 @@ func handleAdminGoogleLink(w http.ResponseWriter, r *http.Request) {
httpError(w, r, fmt.Errorf("username does not exist on the server"), http.StatusNotFound)
return
}

userUuid, err := db.FetchUUIDFromUsername(username)
if err != nil {
httpError(w, r, err, http.StatusInternalServerError)
Expand Down Expand Up @@ -868,34 +878,34 @@ func handleAdminGoogleUnlink(w http.ResponseWriter, r *http.Request) {
googleId := r.Form.Get("googleId")

switch {
case username != "":
log.Printf("Username given, removing googleId")
// this does a quick call to make sure the username exists on the server before allowing the rest of the code to run
// this calls error value 404 (StatusNotFound) if there's no data; this means the username does not exist in the server
_, err = db.CheckUsernameExists(username)
if err != nil {
httpError(w, r, fmt.Errorf("username does not exist on the server"), http.StatusNotFound)
return
}
case username != "":
log.Printf("Username given, removing googleId")
// this does a quick call to make sure the username exists on the server before allowing the rest of the code to run
// this calls error value 404 (StatusNotFound) if there's no data; this means the username does not exist in the server
_, err = db.CheckUsernameExists(username)
if err != nil {
httpError(w, r, fmt.Errorf("username does not exist on the server"), http.StatusNotFound)
return
}

userUuid, err := db.FetchUUIDFromUsername(username)
if err != nil {
httpError(w, r, err, http.StatusInternalServerError)
return
}
userUuid, err := db.FetchUUIDFromUsername(username)
if err != nil {
httpError(w, r, err, http.StatusInternalServerError)
return
}

err = db.RemoveGoogleIdByUUID(userUuid)
if err != nil {
httpError(w, r, err, http.StatusInternalServerError)
return
}
case googleId != "":
log.Printf("DiscordID given, removing googleId")
err = db.RemoveGoogleIdByDiscordId(googleId)
if err != nil {
httpError(w, r, err, http.StatusInternalServerError)
return
}
err = db.RemoveGoogleIdByUUID(userUuid)
if err != nil {
httpError(w, r, err, http.StatusInternalServerError)
return
}
case googleId != "":
log.Printf("DiscordID given, removing googleId")
err = db.RemoveGoogleIdByDiscordId(googleId)
if err != nil {
httpError(w, r, err, http.StatusInternalServerError)
return
}
}

log.Printf("%s: %s removed google id %s from username %s", userDiscordId, r.URL.Path, r.Form.Get("googleId"), r.Form.Get("username"))
Expand Down
51 changes: 51 additions & 0 deletions docker-compose.Local.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
services:
server:
command: --debug --dbaddr db --dbuser pokerogue --dbpass pokerogue --dbname pokeroguedb
image: rogueserver:latest
restart: unless-stopped
depends_on:
db:
condition: service_healthy
networks:
- internal
ports:
- "8001:8001"

db:
image: mariadb:11
restart: unless-stopped
healthcheck:
test: [ "CMD", "healthcheck.sh", "--su-mysql", "--connect", "--innodb_initialized" ]
start_period: 10s
start_interval: 10s
interval: 1m
timeout: 5s
retries: 3
environment:
MYSQL_ROOT_PASSWORD: admin
MYSQL_DATABASE: pokeroguedb
MYSQL_USER: pokerogue
MYSQL_PASSWORD: pokerogue
volumes:
- database:/var/lib/mysql
networks:
- internal

# Prometheus monitoring stack for the server and db services above
prometheus:
image: prom/prometheus:latest
restart: unless-stopped
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
command:
- '--config.file=/etc/prometheus/prometheus.yml'
networks:
- internal

volumes:
database:

networks:
internal:
7 changes: 7 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,11 @@ require (
github.com/aws/smithy-go v1.22.0 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
golang.org/x/sys v0.19.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/prometheus/client_golang v1.19.1 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.48.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
google.golang.org/protobuf v1.33.0 // indirect
)
24 changes: 24 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,27 @@ golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE=
github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc=
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
12 changes: 12 additions & 0 deletions prometheus.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
global:
scrape_interval: "10s"
scrape_timeout: "10s"
evaluation_interval: "1m"

scrape_configs:
- job_name: 'rogueserver'
static_configs:
- targets: ['server:8001']
- job_name: 'mariadb'
static_configs:
- targets: ['db:3306']
13 changes: 13 additions & 0 deletions rogueserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@ import (
"github.com/pagefaultgames/rogueserver/api"
"github.com/pagefaultgames/rogueserver/api/account"
"github.com/pagefaultgames/rogueserver/db"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)

var (
concurrentRequests = promauto.NewGauge(prometheus.GaugeOpts{
Name: "rogueserver_concurrent_requests",
Help: "The number of concurrent requests being handled",
})
)

func main() {
Expand Down Expand Up @@ -140,7 +149,9 @@ func prodHandler(router *http.ServeMux, clienturl string) http.Handler {
return
}

concurrentRequests.Inc()
router.ServeHTTP(w, r)
concurrentRequests.Dec()
})
}

Expand All @@ -155,7 +166,9 @@ func debugHandler(router *http.ServeMux) http.Handler {
return
}

concurrentRequests.Inc()
router.ServeHTTP(w, r)
concurrentRequests.Dec()
})
}

Expand Down

0 comments on commit cc052af

Please sign in to comment.