Add the healtcheck checks on the end server.

This commit is contained in:
2023-10-19 15:43:49 +01:00
parent ef8731300c
commit 35e6069f5e
7 changed files with 44 additions and 26 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ help: ## display this help
.PHONY: run
run: build ## run application
@LOG_LEVEL=debug BLOCK_SCHEMA_INTROSPECTION=false CACHE_TTL=10 JWT_ROLE_RATE_LIMIT=false JWT_ROLE_CLAIM_PATH="Hasura.x-hasura-default-role" JWT_USER_CLAIM_PATH="Hasura.x-hasura-user-id" HOST_GRAPHQL=https://hasura8.lan/ ./graphql-proxy
@LOG_LEVEL=debug BLOCK_SCHEMA_INTROSPECTION=false CACHE_TTL=10 JWT_ROLE_RATE_LIMIT=false JWT_ROLE_CLAIM_PATH="Hasura.x-hasura-default-role" JWT_USER_CLAIM_PATH="Hasura.x-hasura-user-id" HOST_GRAPHQL=https://hasura8.lan/ HEALTHCHECK_GRAPHQL_URL=https://hasura8.lan/v1/graphql ./graphql-proxy
.PHONY: build
build: ## build the binary
+11 -2
View File
@@ -22,7 +22,9 @@ You can find the example of the Kubernetes manifest in the [example deployment](
- [Blocking introspection](#blocking-introspection)
- [API endpoints](#api-endpoints)
- [Ban or unban the user](#ban-or-unban-the-user)
- [Monitoring endpoint](#monitoring-endpoint)
- [General](#general)
- [Healthcheck](#healthcheck)
- [Monitoring endpoint](#monitoring-endpoint)
### Why this project exists
@@ -60,6 +62,7 @@ I wanted to monitor the queries and responses of our graphql endpoint. Still, we
| `MONITORING_PORT` | The port to expose the metrics endpoint | `9393` |
| `PORT_GRAPHQL` | The port to expose the graphql endpoint | `8080` |
| `HOST_GRAPHQL` | The host to proxy the graphql endpoint | `http://localhost/` |
| `HEALTHCHECK_GRAPHQL_URL` | The URL to check the health of the graphql endpoint | `` |
| `JWT_USER_CLAIM_PATH` | Path to the user claim in the JWT token | `` |
| `JWT_ROLE_CLAIM_PATH` | Path to the role claim in the JWT token | `` |
| `ROLE_FROM_HEADER` | Header name to extract the role from | `` |
@@ -173,7 +176,13 @@ curl -X POST \
Ban details will be stored in the `banned_users.json` file, which you can mount as a file or configmap to the `/go/src/app/banned_users.json` path ( or use `BANNED_USERS_FILE` environment variable to specify the path to the file). The file operation is important if you have multiple instances of the proxy running, as it will allow you to ban the user from accessing the application on all instances.
### Monitoring endpoint
### General
#### Healthcheck
If you'd like the `/healthz` endpoint to perform actual check for the connectivity to the graphql endpoint - set the `HEALTHCHECK_GRAPHQL_URL` environment variable to the exact URL of the graphql endpoint. The query executed will be `query { __typename }` and if the response is not `200 OK` - the healthcheck will fail.
#### Monitoring endpoint
Example metrics produced by the proxy:
+1 -1
View File
@@ -12,7 +12,7 @@ require (
github.com/json-iterator/go v1.1.12
github.com/lukaszraczylo/ask v0.0.0-20230927103145-2ff1123b4415
github.com/lukaszraczylo/go-ratecounter v0.1.8
github.com/lukaszraczylo/go-simple-graphql v1.1.34
github.com/lukaszraczylo/go-simple-graphql v1.1.35
github.com/rs/zerolog v1.31.0
github.com/stretchr/testify v1.8.4
github.com/valyala/fasthttp v1.50.0
+2 -2
View File
@@ -40,8 +40,8 @@ github.com/lukaszraczylo/ask v0.0.0-20230927103145-2ff1123b4415 h1:lvI8Wlbg4PxkR
github.com/lukaszraczylo/ask v0.0.0-20230927103145-2ff1123b4415/go.mod h1:M+UVdyqZs++xtEPrascaVmZdOMhCnxjZ2SgH+xHpR0c=
github.com/lukaszraczylo/go-ratecounter v0.1.8 h1:ZYm6Wkn58ZAlFWRmC7PaD4oAYHWcu8/0MUDWGe3PnJQ=
github.com/lukaszraczylo/go-ratecounter v0.1.8/go.mod h1:TqXEOCtFJStk1i0tkipprv1kiDHGon1MVUisjSTBSKM=
github.com/lukaszraczylo/go-simple-graphql v1.1.34 h1:ozDRcZEovXJ61/v+4LvF0dIyk5d+Y0Ar6Ne5rbocxkg=
github.com/lukaszraczylo/go-simple-graphql v1.1.34/go.mod h1:LywSrNo3Otp69z1pTZ7FwE8qIa3mxHBUEPBMGRfOHRk=
github.com/lukaszraczylo/go-simple-graphql v1.1.35 h1:51agVc1C5p9VxiZuvk8TwsEAWU+ieNXnmAgRdRXuqFk=
github.com/lukaszraczylo/go-simple-graphql v1.1.35/go.mod h1:YWMelAXnFs8uknj3Pv2gO8Svzv5k4cAL940MI0n/R0k=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+2 -1
View File
@@ -38,8 +38,9 @@ func parseConfig() {
return strings.Split(urls, ",")
}()
c.Logger = libpack_logging.NewLogger()
c.Server.HealthcheckGraphQL = envutil.Getenv("HEALTHCHECK_GRAPHQL_URL", "")
c.Client.GQLClient = graphql.NewConnection()
c.Client.GQLClient.SetEndpoint(c.Server.HostGraphQL)
c.Client.GQLClient.SetEndpoint(c.Server.HealthcheckGraphQL)
c.Server.AccessLog = envutil.GetBool("ENABLE_ACCESS_LOG", false)
c.Server.ReadOnlyMode = envutil.GetBool("READ_ONLY_MODE", false)
c.Server.AllowURLs = func() []string {
+18 -11
View File
@@ -25,12 +25,13 @@ func StartHTTPProxy() {
AllowOrigins: "*",
}))
server.Post("/*", processGraphQLRequest)
server.Get("/*", proxyTheRequest)
server.Get("/healthz", healthCheck)
server.Get("/livez", healthCheck)
server.Post("/*", processGraphQLRequest)
server.Get("/*", proxyTheRequest)
cfg.Logger.Info("GraphQL query proxy started", map[string]interface{}{"port": cfg.Server.PortGraphQL})
err := server.Listen(fmt.Sprintf(":%d", cfg.Server.PortGraphQL))
if err != nil {
cfg.Logger.Critical("Can't start the service", map[string]interface{}{"error": err.Error()})
@@ -50,14 +51,20 @@ func checkAllowedURLs(c *fiber.Ctx) bool {
}
func healthCheck(c *fiber.Ctx) error {
// query := `{ __typename }`
// _, err := cfg.Client.GQLClient.Query(query, nil, nil)
// if err != nil {
// cfg.Logger.Error("Can't reach the GraphQL server", map[string]interface{}{"error": err.Error()})
// cfg.Monitoring.Increment(libpack_monitoring.MetricsFailed, nil)
// return c.SendStatus(500)
// }
return c.SendStatus(200)
if len(cfg.Server.HealthcheckGraphQL) > 0 {
cfg.Logger.Debug("Health check enabled", map[string]interface{}{"url": cfg.Server.HealthcheckGraphQL})
query := `{ __typename }`
_, err := cfg.Client.GQLClient.Query(query, nil, nil)
if err != nil {
cfg.Logger.Error("Can't reach the GraphQL server", map[string]interface{}{"error": err.Error()})
cfg.Monitoring.Increment(libpack_monitoring.MetricsFailed, nil)
c.Status(500).SendString("Can't reach the GraphQL server with {__typename} query")
return err
}
}
cfg.Logger.Debug("Health check returning OK")
c.Status(200).SendString("Health check OK")
return nil
}
func processGraphQLRequest(c *fiber.Ctx) error {
+9 -8
View File
@@ -15,14 +15,15 @@ type config struct {
// Server holds the configuration of the server _ONLY_.
Server struct {
PortGraphQL int
PortMonitoring int
HostGraphQL string
AccessLog bool
ReadOnlyMode bool
AllowURLs []string
EnableApi bool
ApiPort int
PortGraphQL int
PortMonitoring int
HostGraphQL string
HealthcheckGraphQL string
AccessLog bool
ReadOnlyMode bool
AllowURLs []string
EnableApi bool
ApiPort int
}
Client struct {