Skip to content

Commit 81fed67

Browse files
committed
API Client: Support new metadata endpoint in v1
Introduces support for the new metadata endpoint from Prometheus. The new endpoint provides information independent of targets and collapses the unique combinations of HELP, TYPE and UNIT. Fixes #705 Signed-off-by: gotjosh <[email protected]>
1 parent 673e4a1 commit 81fed67

File tree

3 files changed

+122
-1
lines changed

3 files changed

+122
-1
lines changed

api/prometheus/v1/api.go

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ const (
130130
epSeries = apiPrefix + "/series"
131131
epTargets = apiPrefix + "/targets"
132132
epTargetsMetadata = apiPrefix + "/targets/metadata"
133+
epMetricsMetadata = apiPrefix + "/metadata"
133134
epRules = apiPrefix + "/rules"
134135
epSnapshot = apiPrefix + "/admin/tsdb/snapshot"
135136
epDeleteSeries = apiPrefix + "/admin/tsdb/delete_series"
@@ -248,6 +249,8 @@ type API interface {
248249
Targets(ctx context.Context) (TargetsResult, error)
249250
// TargetsMetadata returns metadata about metrics currently scraped by the target.
250251
TargetsMetadata(ctx context.Context, matchTarget string, metric string, limit string) ([]MetricMetadata, error)
252+
// MetricMetadata returns metadata about metrics currently scraped by the metric name.
253+
MetricsMetadata(ctx context.Context, metric string, limit string) (map[string][]Metadata, error)
251254
}
252255

253256
// AlertsResult contains the result from querying the alerts endpoint.
@@ -357,7 +360,7 @@ type DroppedTarget struct {
357360
DiscoveredLabels map[string]string `json:"discoveredLabels"`
358361
}
359362

360-
// MetricMetadata models the metadata of a metric.
363+
// MetricMetadata models the metadata of a metric with its scrape target and name.
361364
type MetricMetadata struct {
362365
Target map[string]string `json:"target"`
363366
Metric string `json:"metric,omitempty"`
@@ -366,6 +369,13 @@ type MetricMetadata struct {
366369
Unit string `json:"unit"`
367370
}
368371

372+
// Metadata models the metadata of a metric.
373+
type Metadata struct {
374+
Type MetricType `json:"type"`
375+
Help string `json:"help"`
376+
Unit string `json:"unit"`
377+
}
378+
369379
// queryResult contains result data for a query.
370380
type queryResult struct {
371381
Type model.ValueType `json:"resultType"`
@@ -802,6 +812,29 @@ func (h *httpAPI) TargetsMetadata(ctx context.Context, matchTarget string, metri
802812
return res, json.Unmarshal(body, &res)
803813
}
804814

815+
func (h *httpAPI) MetricsMetadata(ctx context.Context, metric string, limit string) (map[string][]Metadata, error) {
816+
u := h.client.URL(epMetricsMetadata, nil)
817+
q := u.Query()
818+
819+
q.Set("metric", metric)
820+
q.Set("limit", limit)
821+
822+
u.RawQuery = q.Encode()
823+
824+
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
825+
if err != nil {
826+
return nil, err
827+
}
828+
829+
_, body, _, err := h.client.Do(ctx, req)
830+
if err != nil {
831+
return nil, err
832+
}
833+
834+
var res map[string][]Metadata
835+
return res, json.Unmarshal(body, &res)
836+
}
837+
805838
// Warnings is an array of non critical errors
806839
type Warnings []string
807840

api/prometheus/v1/api_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,13 @@ func TestAPIs(t *testing.T) {
202202
}
203203
}
204204

205+
doMetricsMetadata := func(metring string, limit string) func() (interface{}, Warnings, error) {
206+
return func() (interface{}, Warnings, error) {
207+
v, err := promAPI.MetricsMetadata(context.Background(), metring, limit)
208+
return v, nil, err
209+
}
210+
}
211+
205212
queryTests := []apiTest{
206213
{
207214
do: doQuery("2", testTime),
@@ -857,6 +864,46 @@ func TestAPIs(t *testing.T) {
857864
},
858865
err: fmt.Errorf("some error"),
859866
},
867+
868+
{
869+
do: doMetricsMetadata("go_goroutines", "1"),
870+
inRes: map[string]interface{}{
871+
"go_goroutines": []map[string]interface{}{
872+
{
873+
"type": "gauge",
874+
"help": "Number of goroutines that currently exist.",
875+
"unit": "",
876+
},
877+
},
878+
},
879+
reqMethod: "GET",
880+
reqPath: "/api/v1/metadata",
881+
reqParam: url.Values{
882+
"metric": []string{"go_goroutines"},
883+
"limit": []string{"1"},
884+
},
885+
res: map[string][]Metadata{
886+
"go_goroutines": []Metadata{
887+
{
888+
Type: "gauge",
889+
Help: "Number of goroutines that currently exist.",
890+
Unit: "",
891+
},
892+
},
893+
},
894+
},
895+
896+
{
897+
do: doMetricsMetadata("", "1"),
898+
inErr: fmt.Errorf("some error"),
899+
reqMethod: "GET",
900+
reqPath: "/api/v1/metadata",
901+
reqParam: url.Values{
902+
"metric": []string{""},
903+
"limit": []string{"1"},
904+
},
905+
err: fmt.Errorf("some error"),
906+
},
860907
}
861908

862909
var tests []apiTest

test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"os"
7+
"time"
8+
9+
"github.com/prometheus/client_golang/api"
10+
v1 "github.com/prometheus/client_golang/api/prometheus/v1"
11+
)
12+
13+
func main() {
14+
client, err := api.NewClient(api.Config{
15+
Address: "http://localhost:9091",
16+
})
17+
if err != nil {
18+
fmt.Printf("Error creating client: %v\n", err)
19+
os.Exit(1)
20+
}
21+
22+
v1api := v1.NewAPI(client)
23+
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
24+
defer cancel()
25+
metadata, err := v1api.MetricsMetadata(ctx, "", "")
26+
if err != nil {
27+
fmt.Printf("Error querying Prometheus: %v\n", err)
28+
os.Exit(1)
29+
}
30+
fmt.Println("Result:")
31+
for metric, metadata := range metadata {
32+
fmt.Println(metric)
33+
for _, m := range metadata {
34+
fmt.Println(m.Type)
35+
fmt.Println(m.Help)
36+
fmt.Println(m.Unit)
37+
fmt.Println("\n\n")
38+
}
39+
}
40+
41+
}

0 commit comments

Comments
 (0)