Skip to content

Commit

Permalink
Merge pull request #341 from porters-xyz/develop
Browse files Browse the repository at this point in the history
Added regional metrics endpoint for POKTSCAN
  • Loading branch information
scermat authored Aug 15, 2024
2 parents 3076a88 + 13d0891 commit 7cb6626
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 7cb6626

Please sign in to comment.