Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deploying updated health checks #367

Merged
merged 4 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gateway/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ RUN go build -o /go/bin/porters

EXPOSE 9000

CMD ["porters", "gateway"]
CMD ["sh", "-c", "ulimit -n 65536 && exec /go/bin/porters gateway"]
2 changes: 1 addition & 1 deletion gateway/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
github.com/lib/pq v1.10.9
github.com/prometheus/client_golang v1.19.0
github.com/redis/go-redis/v9 v9.4.0
golang.org/x/sys v0.25.0
)

require (
Expand All @@ -18,6 +19,5 @@ require (
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
golang.org/x/sys v0.16.0 // indirect
google.golang.org/protobuf v1.33.0 // indirect
)
4 changes: 2 additions & 2 deletions gateway/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ github.com/redis/go-redis/v9 v9.4.0 h1:Yzoz33UZw9I/mFhx4MNrB6Fk+XHO1VukNcCa1+lwy
github.com/redis/go-redis/v9 v9.4.0/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.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=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
63 changes: 60 additions & 3 deletions gateway/proxy/health.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,71 @@
package proxy

import (
"fmt"
"io"
"log/slog"
"net/http"
"os"
"porters/common"
"porters/db"

"golang.org/x/sys/unix"
)

// TODO other healthchecks should be added
type HealthStatus struct {
CacheHealth *common.HealthCheckStatus `json:"cache_health"` // Use the correct type here
}

// New function to check file descriptor health and log the results using slog
func checkFileDescriptorHealth() bool {
var rLimit unix.Rlimit

// Get the max number of allowed file descriptors
err := unix.Getrlimit(unix.RLIMIT_NOFILE, &rLimit)
if err != nil {
slog.Error("Error retrieving file descriptor limit", "error", err)
return false
}

// Get the actual number of file descriptors in use
files, err := os.ReadDir("/proc/self/fd")
if err != nil {
slog.Error("Error reading /proc/self/fd", "error", err)
return false
}
fdUsage := uint64(len(files))

healthy := fdUsage < rLimit.Cur*80/100

// Log the file descriptor information using slog
slog.Info("File Descriptor Usage",
"max", rLimit.Cur,
"used", fdUsage,
"healthy", healthy)

return healthy
}

// Update your healthHandler to log file descriptor health but not expose it
func healthHandler(resp http.ResponseWriter, req *http.Request) {
hc := (&db.Cache{}).Healthcheck()
// Existing cache health check
cacheHealth := (&db.Cache{}).Healthcheck()

// Log file descriptor health and determine if the server is healthy
fdHealthy := checkFileDescriptorHealth()

// Only return the non-sensitive health information (cache health)
healthStatus := HealthStatus{
CacheHealth: cacheHealth,
}

// Marshal the health status into JSON
resp.Header().Set("Content-Type", "application/json")
io.WriteString(resp, hc.ToJson())

if fdHealthy {
io.WriteString(resp, healthStatus.CacheHealth.ToJson())
} else {
resp.WriteHeader(http.StatusInternalServerError)
io.WriteString(resp, fmt.Sprintf(`{"error": "file descriptor limit exceeded"}`))
}
}