Skip to content

Commit

Permalink
added fly.io regional metrics capture for poktscan. This can be impro…
Browse files Browse the repository at this point in the history
…ved upon in the future
  • Loading branch information
scermat committed Aug 15, 2024
1 parent 13dd448 commit edcbeb5
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 7 deletions.
2 changes: 2 additions & 0 deletions gateway/common/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ const (
INSTRUMENT_ENABLED = "ENABLE_INSTRUMENT"
LOG_LEVEL = "LOG_LEVEL"
LOG_HTTP_RESPONSE = "LOG_HTTP_RESPONSE"
FLY_API_KEY = "FLY_API_KEY"
FLY_GATEWAY_URI = "FLY_GATEWAY_URI"
)

// This may evolve to include config outside env, or use .env file for
Expand Down
95 changes: 93 additions & 2 deletions gateway/proxy/kitMetricsKitRouter.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,66 @@
package proxy

import (
"compress/gzip"
"encoding/json"
"fmt"
"io"
log "log/slog"
"net/http"
"strings"

"porters/common"
)

func kitMetricsHandler(w http.ResponseWriter, r *http.Request, proxyToUrl string) {
type Machine struct {
ID string `json:"id"`
InstanceID string `json:"instance_id"`
Region string `json:"region"`
}

func kitMetricsHandler(w http.ResponseWriter, r *http.Request, proxyToUrl, region string) {
flyApiKey := common.GetConfig(common.FLY_API_KEY)
// Fetch the machines from Fly.io
machines, err := fetchMachines(flyApiKey)
if err != nil {
http.Error(w, "Unable to retrieve machines from Fly.io", http.StatusInternalServerError)
return
}

// Find the machine for the given region
machineID := ""
for _, machine := range machines {
if strings.EqualFold(machine.Region, region) {
machineID = machine.ID
break
}
}

if machineID == "" {
http.Error(w, "Machine not found for the given region", http.StatusNotFound)
return
}

log.Info("Retrieved Machine ID for gatewaykit", "Machine ID", machineID)

// Construct the metrics URL
kitMetricsUrl := fmt.Sprintf("%s/metrics", proxyToUrl)

log.Info("Calling metrics endpoint", "kitMetricsUrl", kitMetricsUrl)

// Create a new HTTP request
req, err := http.NewRequest("GET", kitMetricsUrl, nil)
if err != nil {
http.Error(w, "Unable to create request", http.StatusInternalServerError)
return
}

// Add the fly-force-instance-id header
req.Header.Set("fly-force-instance-id", machineID)

// Forward the request to the kit's /metrics endpoint
resp, err := http.Get(kitMetricsUrl)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
http.Error(w, "Unable to retrieve kit metrics", http.StatusInternalServerError)
return
Expand All @@ -21,3 +71,44 @@ func kitMetricsHandler(w http.ResponseWriter, r *http.Request, proxyToUrl string
w.WriteHeader(resp.StatusCode)
io.Copy(w, resp.Body)
}

func fetchMachines(authToken string) ([]Machine, error) {
flyGatewayMachines := common.GetConfig(common.FLY_GATEWAY_URI)
// Create a new request to fetch the machines
req, err := http.NewRequest("GET", flyGatewayMachines, nil)
if err != nil {
return nil, err
}

// Set the Authorization header with the Bearer token
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", authToken))

// Perform the request
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()

// Check if the response is gzipped and handle accordingly
var reader io.ReadCloser
if resp.Header.Get("Content-Encoding") == "gzip" {
reader, err = gzip.NewReader(resp.Body)
if err != nil {
return nil, err
}
defer reader.Close()
} else {
reader = resp.Body
}

// Decode the JSON response into the machines slice
var machines []Machine
err = json.NewDecoder(reader).Decode(&machines)
if err != nil {
return nil, err
}

return machines, nil
}
11 changes: 6 additions & 5 deletions gateway/proxy/mux.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import (
)

const (
APP_PATH string = "appId"
PRODUCT_NAME = "product"
HEALTH = "health"
APP_PATH string = "appId"
PRODUCT_NAME = "product"
HEALTH = "health"
)

func PluckAppId(req *http.Request) string {
Expand Down Expand Up @@ -48,8 +48,9 @@ func addMetricsRoute(r *mux.Router) *mux.Router {
// Since the Gateway Kit is on an internal private network, with only the Gateway having access to it, we proxy a gateway-kit/metrics endpoint to expose the data to POKTScan
func addMetricsKitRoute(r *mux.Router, proxyToUrl string) *mux.Router {
subrouter := r.PathPrefix("/gateway-kit/metrics").Subrouter()
subrouter.HandleFunc("", func(w http.ResponseWriter, r *http.Request) {
kitMetricsHandler(w, r, proxyToUrl)
subrouter.HandleFunc("/{region}", func(w http.ResponseWriter, r *http.Request) {
region := mux.Vars(r)["region"]
kitMetricsHandler(w, r, proxyToUrl, region)
})
return subrouter
}

0 comments on commit edcbeb5

Please sign in to comment.