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

Added regional metrics endpoint for POKTSCAN #341

Merged
merged 2 commits into from
Aug 15, 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: 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
}