faas/gateway/metrics/prometheus_query.go
Alex Ellis (OpenFaaS Ltd) 546bfee9dc Add User-Agent to Prometheus Queries
Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alex@openfaas.com>
2024-08-07 09:39:31 +01:00

80 lines
1.8 KiB
Go

package metrics
import (
"encoding/json"
"fmt"
"io"
"net/http"
)
// PrometheusQuery represents parameters for querying Prometheus
type PrometheusQuery struct {
host string
port int
client *http.Client
userAgentVersion string
}
type PrometheusQueryFetcher interface {
Fetch(query string) (*VectorQueryResponse, error)
}
// NewPrometheusQuery create a NewPrometheusQuery
func NewPrometheusQuery(host string, port int, client *http.Client, userAgentVersion string) PrometheusQuery {
return PrometheusQuery{
client: client,
host: host,
port: port,
userAgentVersion: userAgentVersion,
}
}
// Fetch queries aggregated stats
func (q PrometheusQuery) Fetch(query string) (*VectorQueryResponse, error) {
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("http://%s:%d/api/v1/query?query=%s", q.host, q.port, query), nil)
if err != nil {
return nil, err
}
req.Header.Set("User-Agent", fmt.Sprintf("openfaas-gateway/%s (Prometheus query)", q.userAgentVersion))
res, err := q.client.Do(req)
if err != nil {
return nil, err
}
if res.Body != nil {
defer res.Body.Close()
}
bytesOut, err := io.ReadAll(res.Body)
if err != nil {
return nil, err
}
if res.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unexpected status code from Prometheus want: %d, got: %d, body: %s", http.StatusOK, res.StatusCode, string(bytesOut))
}
var values VectorQueryResponse
if err := json.Unmarshal(bytesOut, &values); err != nil {
return nil, fmt.Errorf("error unmarshaling result: %s, '%s'", err, string(bytesOut))
}
return &values, nil
}
type VectorQueryResponse struct {
Data struct {
Result []struct {
Metric struct {
Code string `json:"code"`
FunctionName string `json:"function_name"`
}
Value []interface{} `json:"value"`
}
}
}