WIP: (api): Update metrics handler to take options

This commit is contained in:
Ken Hibino
2021-11-30 07:06:26 -08:00
parent d7ac077083
commit 3483b0ffae
2 changed files with 41 additions and 21 deletions

View File

@@ -188,7 +188,7 @@ func muxRouter(opts Options, rc redis.UniversalClient, inspector *asynq.Inspecto
}
// Time series metrics endpoints.
api.HandleFunc("/metrics", newGetMetricsHandlerFunc(http.DefaultClient)).Methods("GET")
api.HandleFunc("/metrics", newGetMetricsHandlerFunc(http.DefaultClient, opts.PrometheusAddress)).Methods("GET")
// Everything else, route to uiAssetsHandler.
router.NotFoundHandler = &uiAssetsHandler{

View File

@@ -14,29 +14,21 @@ type getMetricsResponse struct {
// TODO
}
func unixTimeString(t time.Time) string {
return strconv.Itoa(int(t.Unix()))
type metricsFetchOptions struct {
// Specifies the number of seconds to scan for metrics.
duration time.Duration
// Specifies the end time when fetching metrics.
endTime time.Time
}
func newGetMetricsHandlerFunc(client *http.Client) http.HandlerFunc {
func newGetMetricsHandlerFunc(client *http.Client, prometheusAddr string) http.HandlerFunc {
// Optional query params:
// `duration_sec`: specifies the number of seconds to scan
// `end_time`: specifies the end_time in Unix time seconds
return func(w http.ResponseWriter, r *http.Request) {
const (
baseAddr = "http://localhost:9090"
apiPath = "/api/v1/query_range"
promQL = "asynq_queue_size"
)
var b strings.Builder
v := url.Values{}
b.WriteString(baseAddr)
b.WriteString(apiPath)
v.Add("query", promQL)
now := time.Now()
v.Add("start", unixTimeString(now.Add(-30*time.Minute)))
v.Add("end", unixTimeString(now))
v.Add("step", (1 * time.Minute).String())
b.WriteString("?")
b.WriteString(v.Encode())
url := b.String()
opts := extractMetricsFetchOptions(r)
url := buildPrometheusURL(prometheusAddr, "asynq_queue_size", opts)
fmt.Printf("DEBUG: url: %s\n", url)
resp, err := client.Get(url)
if err != nil {
@@ -50,3 +42,31 @@ func newGetMetricsHandlerFunc(client *http.Client) http.HandlerFunc {
}
}
}
const prometheusAPIPath = "/api/v1/query_range"
func extractMetricsFetchOptions(r *http.Request) *metricsFetchOptions {
// TODO: Extract these options from the request if any, and default to these values if none are specified
return &metricsFetchOptions{
duration: 60 * time.Minute,
endTime: time.Now(),
}
}
func buildPrometheusURL(baseAddr, promQL string, opts *metricsFetchOptions) string {
var b strings.Builder
b.WriteString(strings.TrimSuffix(baseAddr, "/"))
b.WriteString(prometheusAPIPath)
v := url.Values{}
v.Add("query", promQL)
v.Add("start", unixTimeString(opts.endTime.Add(-opts.duration)))
v.Add("end", unixTimeString(opts.endTime))
v.Add("step", (1 * time.Minute).String())
b.WriteString("?")
b.WriteString(v.Encode())
return b.String()
}
func unixTimeString(t time.Time) string {
return strconv.Itoa(int(t.Unix()))
}